Version 2.1.0-dev.5.0

Merge commit '4134b95' into dev
diff --git a/.mailmap b/.mailmap
index 3a5f7a8..5f5adcc 100644
--- a/.mailmap
+++ b/.mailmap
@@ -64,12 +64,12 @@
 Jakob Kummerow <jkummerow@google.com>
 Janice Leung <janicejl@google.com>
 Jason Rosenberg <jbrosenberg@google.com>
+Jenny Messerly <jmesserly@google.com>
 Jim Hugunin <jimhug@google.com>
 Joel Webber <jgw@google.com>
 John Lenz <johnlenz@google.com>
 John McCutchan <johnmccutchan@google.com>
 John McDole <codefu@google.com>
-John Messerly <jmesserly@google.com>
 Johnni Winther <johnniwinther@google.com>
 John Tamplin <jat@google.com>
 Jørgen Fogh <jrgfogh@google.com>
diff --git a/.packages b/.packages
index fe03169..df189b4 100644
--- a/.packages
+++ b/.packages
@@ -30,7 +30,6 @@
 dart2js_info:third_party/pkg/dart2js_info/lib
 dart2js_tools:pkg/dart2js_tools/lib
 dart_internal:pkg/dart_internal/lib
-dart_messages:pkg/dart_messages/lib
 dart_style:third_party/pkg_tested/dart_style/lib
 dartdoc:third_party/pkg/dartdoc/lib
 dev_compiler:pkg/dev_compiler/lib
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 3b3a06d..36b3269 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,18 @@
+## 2.1.0-dev.5.0
+
+### Core library changes
+
+#### `dart:core`
+
+*   Exported `Future` and `Stream` from `dart:core`.
+*   Added operators `&`, `|` and `^` to `bool`.
+
+#### `dart:async`
+
+*   Fix a bug where calling `stream.take(0).drain(value)` would not correctly
+    forward the `value` through the returned `Future`.
+*   Add a `StreamTransformer.fromBind` constructor.
+
 ## 2.1.0-dev.4.0
 
 ### Core library changes
diff --git a/DEPS b/DEPS
index 0680c4b..cc19e00 100644
--- a/DEPS
+++ b/DEPS
@@ -53,7 +53,7 @@
   # Revisions of /third_party/* dependencies.
   "args_tag": "1.4.4",
   "async_tag": "2.0.8",
-  "bazel_worker_tag": "0.1.11",
+  "bazel_worker_tag": "0.1.14",
   "boolean_selector_tag" : "1.0.4",
   "boringssl_gen_rev": "fc47eaa1a245d858bae462cd64d4155605b850ea",
   "boringssl_rev" : "189270cd190267f5bd60cfe8f8ce7a61d07ba6f4",
@@ -95,7 +95,7 @@
   "intl_tag": "0.15.6",
   "jinja2_rev": "2222b31554f03e62600cd7e383376a7c187967a1",
   "json_rpc_2_tag": "2.0.9",
-  "linter_tag": "0.1.60",
+  "linter_tag": "0.1.62",
   "logging_tag": "0.11.3+2",
   "markdown_tag": "2.0.2",
   "matcher_tag": "0.12.3",
@@ -157,7 +157,7 @@
       "packages": [
           {
               "package": "dart/dart-sdk/${{platform}}",
-              "version": "version:2.1.0-dev.2.0",
+              "version": "version:2.1.0-dev.4.0",
           },
       ],
       "dep_type": "cipd",
diff --git a/build/config/compiler/BUILD.gn b/build/config/compiler/BUILD.gn
index e29aa03..4e9d66b 100644
--- a/build/config/compiler/BUILD.gn
+++ b/build/config/compiler/BUILD.gn
@@ -690,11 +690,13 @@
       # See http://lwn.net/Articles/192624/ .
       "-Wl,-O1",
       "-Wl,--gc-sections",
+    ]
 
+    if (is_clang) {
       # Identical code folding to reduce size.
       # Warning: This changes C/C++ semantics of function pointer comparison.
-      "-Wl,--icf=all",
-    ]
+      common_optimize_on_ldflags += [ "-Wl,--icf=all" ]
+    }
 
     if (!using_sanitizer) {
       # Functions interposed by the sanitizers can make ld think
diff --git a/docs/language/dart.sty b/docs/language/dart.sty
index 3146317..a7e9cb7 100644
--- a/docs/language/dart.sty
+++ b/docs/language/dart.sty
@@ -1,12 +1,6 @@
-\def\keyword#1{\textbf{#1}}
-\def\builtinId#1{\textbf{#1}}
 \def\code#1{\textsf{#1}}
-\def\comment#1{\textit{#1}}
-\def\capt#1{\rmfamily \caption{#1}}
-\def\lt{\ensuremath{<}}
-\def\gt{\ensuremath{>}}
-\def\<{\ensuremath{\langle}}
-\def\>{\ensuremath{\rangle}}
+\def\builtinId#1{\code{\textbf{#1}}}
+\def\keyword#1{\code{\textbf{#1}}}
 \def\metavar#1{\ensuremath{\mathit{#1}}}
 
 \def\ABSTRACT{\builtinId{abstract}}
@@ -34,7 +28,6 @@
 \def\ASYNC{\keyword{async}}
 \def\AWAIT{\keyword{await}}
 \def\BREAK{\keyword{break}}
-\def\CALL{\keyword{call}}
 \def\CASE{\keyword{case}}
 \def\CATCH{\keyword{catch}}
 \def\CLASS{\keyword{class}}
@@ -73,6 +66,18 @@
 \def\WITH{\keyword{with}}
 \def\YIELD{\keyword{yield}}
 
+% `call` has no special lexical status, so we just use \code{}.
+\def\CALL{\code{call}}
+
+% Used in regular text to indicate that #1 consists of non-terminals.
+%% TODO(eernst): Update to use grammar font when we start using that;
+%% at this point we just make it "regular text" using \mbox.
+\newcommand{\NonTerminal}[1]{\mbox{#1}}
+
+% Angle brackets used for operators in grammar context.
+\def\lt{\ensuremath{<}}
+\def\gt{\ensuremath{>}}
+
 % A quoted comma as used in the grammar: needs spacing fix.
 \newcommand{\gcomma}{\mbox{`,\hspace{-0.1em}'}}
 
@@ -88,6 +93,14 @@
 \newenvironment{rationale}[1]{{\it #1}}{}
 \newenvironment{commentary}[1]{{\sf #1}}{}
 
+\newcommand{\flatten}[1]{\ensuremath{\mbox{\it flatten}({#1})}}
+
+% Used as a mini-section marker, indicating visibly that a range of
+% text (usually just a couple of paragraphs) are concerned with one
+% specific topic in a list of similar topics (like many forms of
+% expressions of a similar nature).
+\newcommand{\Case}[1]{\textbf{Case }$\langle\hspace{0.1em}${#1}$\hspace{0.1em}\rangle$\textbf{.}}
+
 \newenvironment{dartCode}[1][!ht] {
 %  \begin{verbatim}[#1]
   \def\@programcr{\@addfield\strut}
diff --git a/docs/language/dartLangSpec.tex b/docs/language/dartLangSpec.tex
index 5284f7b..b37d438 100644
--- a/docs/language/dartLangSpec.tex
+++ b/docs/language/dartLangSpec.tex
@@ -27,6 +27,35 @@
 %   declaration must be taken into account during static checks.
 % - Disallow any expression statement starting with `{`, not just
 %   those that are map literals.
+% - Define a notion of lookup that is needed for super invocations, adjust
+%   specification of super invocations accordingly.
+% - Specify that it is a dynamic error to initialize a non-static variable
+%   with a value that does not have the declared type (e.g., a failed cast).
+% - Specify for constructor initializers that target variable must exist and
+%   the initializing expression must have a type which is assignable to its
+%   type.
+% - Specify for superinitializers that the target constructor must exist and
+%   the argument part must have a matching shape and pass type and value
+%   arguments satisfying the relevant constraints.
+% - Reword rules about abstract methods and inheritance to use 'class
+%   interface'.
+% - Specify that it is an error for a concrete class with no non-trivial
+%   \code{noSuchMethod} to not have a concrete declaration for some member
+%   in its interface, or to have one which is not a correct override.
+% - Use \ref{bindingActualsToFormals} in 3 locations, eliminating 2 extra
+%   copies of nearly the same text.
+% - Add figure in \ref{bindingActualsToFormals} for improved readability.
+% - Introduce a notion of lookup which is needed for superinvocations.
+% - Use new lookup concept to simplify specification of getter, setter, method
+%   lookup.
+% - Introduce several `Case< SomeTopic >` markers in order to improve
+%   readability.
+% - Reorganize several sections to specify static analysis first and then
+%   dynamic semantics; clarify many details along the way. The sections are:
+%   \ref{variables}, \ref{new}, \ref{const}, \ref{bindingActualsToFormals},
+%   \ref{unqualifiedInvocation}, \ref{functionExpressionInvocation},
+%   \ref{superInvocations}, \ref{assignment}, \ref{compoundAssignment},
+%   \ref{localVariableDeclaration}, and \ref{return}.
 %
 % 2.0
 % - Don't allow functions as assert test values.
@@ -621,10 +650,49 @@
 \end{grammar}
 
 \LMHash{}
-A variable that has not been initialized has the null object (\ref{null}) as its initial value.
+A variable declaration that contains one or more terms of the form
+\NonTerminal{initializedIdentifier}
+(\commentary{i.e., a declaration that declares two or more variables})
+is equivalent to multiple variable declarations declaring
+the same set of variable names in the same order,
+with the same initialization, type, and modifiers.
+
+\commentary{
+For example,
+\code{\VAR{} x = 1, y;}
+is equivalent to
+\code{\VAR{} x = 1; \VAR{} y;}
+and
+\code{\STATIC{} \FINAL{} String s1, s2 = "foo";}
+is equivalent to
+\code{\STATIC{} \FINAL{} String s1; \STATIC{} \FINAL{} String s2 = "foo";}.
+}
 
 \LMHash{}
-A variable declared at the top-level of a library is referred to as either a {\em library variable} or simply a top-level variable.
+In a variable declaration of one of the forms
+\code{$N$ $v$;}
+\code{$N$ $v$ = $e$;}
+where $N$ is derived from
+\NonTerminal{metadata finalConstVarOrType},
+we say that $v$ is the {\em declaring occurrence} of the identifier.
+For every identifier which is not a declaring occurrence,
+we say that it is an {\em referencing occurrence}.
+We also abbreviate that to say that an identifier is
+a {\em declaring identifier} respectively an {\em referencing identifier}.
+
+\commentary{
+In an expression of the form \code{$e$.\id} it is possible that
+$e$ has static type \DYNAMIC{} and \id{} cannot be associated with
+any declaration named \id{} at compile-time,
+but in this situation \id{} is still an referencing identifier.
+}
+
+\LMHash{}
+An {\em initialized variable} is a variable whose declaring identifier is
+immediately followed by `\code{=}' and an {\em initializing expression}.
+
+\LMHash{}
+A variable declared at the top-level of a library is referred to as either a {\em library variable} or a top-level variable.
 
 \LMHash{}
 A {\em static variable} is a variable that is not associated with a particular instance, but rather with an entire library or class.
@@ -634,49 +702,74 @@
 It is a compile-time error to preface a top-level variable declaration with the built-in identifier (\ref{identifierReference}) \STATIC{}.
 
 \LMHash{}
-Static variable declarations are initialized lazily.
-When a static variable $v$ is read, if{}f it has not yet been assigned, it is set to the result of evaluating its initializer.
-The precise rules are given in section \ref{evaluationOfImplicitVariableGetters}.
-
-\rationale{
-The lazy semantics are given because we do not want a language where one tends to define expensive initialization computations, causing long application startup times.
-This is especially crucial for Dart, which must support the coding of client applications.
-}
-
-\LMHash{}
-A {\em final variable} is a variable whose binding is fixed upon initialization; a final variable $v$ will always refer to the same object after $v$ has been initialized.
-The declaration of a final variable must include the modifier \FINAL{}.
-
-\LMHash{}
-It is a compile-time error if a final instance variable whose declaration has an initializer expression
-is also initialized by a constructor, either by an initializing formal or an initializer list entry.
-It is a compile-time error if a local variable $v$ is final and $v$ is not initialized at its point of declaration.
-It is a compile-time error to assign to a final local variable.
-
-\commentary{
-It is a compile-time error if a final instance variable
-that has been initialized by means of an initializing formal of a constructor $k$
-is also initialized in the initializer list of $k$ (\ref{initializerLists}).
-Any attempt to assign to a final non-local variable \id{} will cause a compile-time error,
-because it amounts to an invocation of a setter named \code{\id=},
-except of course when such a setter has been declared separately.
-}
-
-\LMHash{}
 A {\em constant variable} is a variable whose declaration includes the modifier \CONST{}.
-A constant variable is always implicitly final.
 A constant variable must be initialized to a compile-time constant (\ref{constants}) or a compile-time error occurs.
 
 \LMHash{}
-We say that a variable $v$ is {\em potentially mutated} in some scope $s$ if $v$ is not final or constant and an assignment to $v$ occurs in $s$.
+A {\em final variable} is a variable whose binding is fixed upon initialization;
+a final variable $v$ will always refer to the same object after $v$ has been initialized.
+A variable is final if{}f its declaration includes the modifier \FINAL{} or the modifier \CONST{}.
 
 \LMHash{}
-If a variable declaration does not explicitly specify a type, the type of the declared variable(s) is \DYNAMIC{}, the unknown type (\ref{typeDynamic}).
+A {\em mutable variable} is a variable which is not final.
+
+%% Note that the following relies on the assumption that inference has
+%% already taken place, including member signature inference. For instance,
+%% if `var x;` is an instance variable declaration that overrides `T get x;`
+%% then we treat `var x;` as if it had been `T x;`.
 
 \LMHash{}
-A variable is {\em mutable} if it is not final.
-Static and instance variable declarations always induce implicit getters.
-If the variable is mutable it also introduces an implicit setter.
+The following rules apply to all static and instance variables.
+
+\LMHash{}
+A variable declaration of one of the forms
+\code{$T$ $v$;}
+\code{$T$ $v$ = $e$;}
+\code{\CONST{} $T$ $v$ = $e$;}
+\code{\FINAL{} $T$ $v$;}
+or \code{\FINAL{} $T$ $v$ = $e$;}
+induces an implicit getter function (\ref{getters}) with signature
+\code{$T$ \GET{} $v$}
+whose invocation evaluates as described below
+(\ref{evaluationOfImplicitVariableGetters}).
+In these cases the static type of $v$ is $T$.
+
+\LMHash{}
+A variable declaration of one of the forms
+\code{\VAR{} $v$;}
+\code{\VAR{} $v$ = $e$;}
+\code{\CONST{} $v$ = $e$;}
+\code{\FINAL{} $v$;}
+or \code{\FINAL{} $v$ = $e$;}
+induces an implicit getter function with signature
+\code{\DYNAMIC{} \GET{} $v$}
+whose invocation evaluates as described below
+(\ref{evaluationOfImplicitVariableGetters}).
+%% TODO[inference]: We assume inference has taken place, i.e., inferred types
+%% are written explicitly. Does this mean that the initialized variants
+%% cannot exist (not even for `$e$` of type `dynamic`?). We probably don't
+%% want to start talking about a grammar before inference and another one
+%% after inference.
+In these cases, the static type of $v$ is \DYNAMIC{}
+(\ref{typeDynamic}).
+
+\LMHash{}
+A mutable variable declaration of the form
+\code{{} $T$ $v$;}
+or \code{$T$ $v$ = $e$;}
+induces an implicit setter function (\ref{setters}) with signature
+\code{\VOID{} \SET{} $v$=($T$ $x$)}
+whose execution sets the value of $v$ to the incoming argument $x$.
+
+\LMHash{}
+A mutable variable declaration of the form
+\code{\VAR{} $v$;}
+or \code{\VAR{} $v$ = $e$;}
+induces an implicit setter function with signature
+\code{\VOID{} \SET{} $v$=(\DYNAMIC{} $x$)}
+whose execution sets the value of $v$ to the incoming argument $x$.
+
+\LMHash{}
 The scope into which the implicit getters and setters are introduced depends on the kind of variable declaration involved.
 
 \LMHash{}
@@ -690,113 +783,78 @@
 A mutable instance variable introduces an instance setter into the immediately enclosing class.
 
 \LMHash{}
-Local variables are added to the innermost enclosing scope.
-They do not induce getters and setters.
-A local variable may only be referenced at a source code location that is after its initializer, if any, is complete, or a compile-time error occurs.
-The error may be reported either at the point where the premature reference occurs, or at the variable declaration.
+Let $v$ be an initialized variable and let $e$ be the associated initializing expression.
+It is a compile-time error if the static type of $e$ is not assignable to the declared type of $v$.
+It is a compile-time error if a final instance variable whose declaration has an initializer expression
+is also initialized by a constructor, either by an initializing formal or an initializer list entry.
+
+\commentary{
+It is a compile-time error if a final instance variable
+that has been initialized by means of an initializing formal of a constructor $k$
+is also initialized in the initializer list of $k$ (\ref{initializerLists}).
+
+A static final variable $v$ does not induce a setter,
+so unless a setter named \code{$v$=} is in scope
+it is a compile-time error to assign to $v$.
+
+Similarly, assignment to a final instance variable $v$
+is a compile-time error,
+unless a setter named \code{$v$=} is in scope,
+or the receiver has type \DYNAMIC{}.
+$v$ can be initialized in its declaration or in initializer lists,
+but initialization and assignment is not the same thing.
+When the receiver has type \DYNAMIC{}
+such an assignment is not a compile-time error,
+but if there is no setter it will cause a dynamic error.
+}
+
+\LMHash{}
+A variable that has no initializing expression has the null object (\ref{null}) as its initial value.
+Otherwise, variable initialization proceeds as follows:
+
+\LMHash{}
+Static variable declarations with an initializing expression are initialized lazily
+(\ref{evaluationOfImplicitVariableGetters}).
 
 \rationale{
-We allow the error to be reported at the declaration to allow implementations to avoid an extra processing phase.
+The lazy semantics are given because we do not want a language where one tends to define expensive initialization computations, causing long application startup times.
+This is especially crucial for Dart, which must support the coding of client applications.
 }
 
 \commentary{
-The example below illustrates the expected behavior.
-A variable $x$ is declared at the library level, and another $x$ is declared inside the function $f$.
+Initialization of an instance variable with no initializing expression
+takes place during constructor execution
+(\ref{initializerLists}).
 }
 
-\begin{dartCode}
-\VAR{} x = 0;
-
-f(y) \{
-  \VAR{} z = x; // compile-time error
-  if (y) \{
-    x = x + 1; // two compile-time errors
-    print(x); // compile-time error
-  \}
-  \VAR{} x = x++; // compile-time error
-  print(x);
-\}
-\end{dartCode}
+\LMHash{}
+Initialization of an instance variable $v$
+with an initializing expression $e$
+proceeds as follows:
+$e$ is evaluated to an object $o$
+and the variable $v$ is bound to $o$.
 
 \commentary{
-The declaration inside $f$ hides the enclosing one.
-So all references to $x$ inside $f$ refer to the inner declaration of $x$.
-However, many of these references are illegal, because they appear before the declaration.
-The assignment to $z$ is one such case.
-The assignment to $x$ in the \IF{} statement suffers from multiple problems.
-The right hand side reads $x$ before its declaration, and the left hand side assigns to $x$ before its declaration.
-Each of these are, independently, compile-time errors.
-The print statement inside the \IF{} is also illegal.
-
-The inner declaration of $x$ is itself erroneous because its right hand side attempts to read $x$ before the declaration has terminated.
-The left hand side is not, technically, a reference or an assignment but a declaration and so is legal.
-The last print statement is perfectly legal as well.
+It is specified elsewhere when this initialization occurs,
+and in which environment
+(p.\,\pageref{executionOfGenerativeConstructors},
+\ref{localVariableDeclaration},
+\ref{bindingActualsToFormals}).
 }
 
 \commentary{
-As another example \code{\VAR{} x = 3, y = x;} is legal, because \code{x} is referenced after its initializer.
-
-A particularly perverse example involves a local variable name shadowing a type.
-This is possible because Dart has a single namespace for types, functions and variables.
+If the initializing expression throws then
+access to the uninitialized variable is prevented,
+because the instance creation
+that caused this initialization to take place
+will throw.
 }
 
-\begin{dartCode}
-\CLASS{} C \{\}
-perverse() \{
-   \VAR{} v = \NEW{} C(); // compile-time error
-   C aC; // compile-time error
-   \VAR{} C = 10;
-\}
-\end{dartCode}
-
-\commentary{
-Inside \code{perverse()}, \code{C} denotes a local variable.
-The type \code{C} is hidden by the variable of the same name.
-The attempt to instantiate \code{C} causes a compile-time error because it references a local variable prior to its declaration.
-Similarly, for the declaration of \code{aC} (even though it is only a type annotation).
-}
-
-\rationale{
-As a rule, type annotations are ignored in production mode.
-However, we do not want to allow programs to compile legally in one mode and not another, and in this extremely odd situation, that consideration takes precedence.
-}
-
-% the grammar does not support local getters and setters.
-% The local var discussion does not seem to mention getters and setters based semantics.
-% It simply discusses the creation of the variable, not its access.
-% Access is either assignment or identifiers.
-% Identifiers ignore the getter story.
-
 \LMHash{}
-The following rules apply to all static and instance variables.
-
-\LMHash{}
-A variable declaration of one of the forms \code{$T$ $v$;}, \code{$T$ $v$ = $e$;} \code{\CONST{} $T$ $v$ = $e$;}, \code{\FINAL{} $T$ $v$;} or \code{\FINAL{} $T$ $v$ = $e$;} always induces an implicit getter function (\ref{getters}) with signature
-
-$T$ \GET{} $v$
-
-whose invocation evaluates as described below (\ref{evaluationOfImplicitVariableGetters}).
-
-\LMHash{}
-A variable declaration of one of the forms \code{\VAR{} $v$;}, \code{\VAR{} $v$ = $e$;}, \code{\CONST{} $v$ = $e$;}, \code{\FINAL{} $v$;} or \code{\FINAL{} $v$ = $e$;} always induces an implicit getter function with signature
-
-\GET{} $v$
-
-whose invocation evaluates as described below (\ref{evaluationOfImplicitVariableGetters}).
-
-\LMHash{}
-A non-final variable declaration of the form \code{{} $T$ $v$;} or the form \code{$T$ $v$ = $e$;} always induces an implicit setter function (\ref{setters}) with signature
-
- \VOID{} \SET{} $v=(T$ $x)$
-
-whose execution sets the value of $v$ to the incoming argument $x$.
-
-\LMHash{}
-A non-final variable declaration of the form \code{\VAR{} $v$;} or the form \code{\VAR{} $v$ = $e$;} always induces an implicit setter function with signature
-
-\SET{} $v=(x)$
-
-whose execution sets the value of $v$ to the incoming argument $x$.
+In checked mode,
+it is a dynamic type error if $o$ is not the null object (\ref{null})
+and the interface of the class of $o$ is not a subtype of the actual type of the variable $v$
+(\ref{actualTypeOfADeclaration}).
 
 
 \subsection{Evaluation of Implicit Variable Getters}
@@ -804,23 +862,50 @@
 
 \LMHash{}
 Let $d$ be the declaration of a static or instance variable $v$.
-If $d$ is an instance variable, then the invocation of the implicit getter of $v$ evaluates to the value stored in $v$.
-If $d$ is a static or library variable then the implicit getter method of $v$ executes as follows:
+If $d$ is an instance variable,
+then the invocation of the implicit getter of $v$ evaluates to
+the value stored in $v$.
+If $d$ is a static variable
+(\commentary{which can be a library variable})
+then the implicit getter method of $v$ executes as follows:
 \begin{itemize}
 \item {\bf Non-constant variable declaration with initializer}.
-If $d$ is of one of the forms \code{\VAR{} $v$ = $e$;}, \code{$T$ $v$ = $e$;}, \code{\FINAL{} $v$ = $e$;}, \code{\FINAL{} $T$ $v$ = $e$;}, \code{\STATIC{} $v$ = $e$;}, \code{\STATIC{} $T$ $v$ = $e$; }, \code{\STATIC{} \FINAL{} $v$ = $e$; } or \code{\STATIC{} \FINAL{} $T$ $v$ = $e$;} and no value has yet been stored into $v$ then the initializer expression $e$ is evaluated.
-If, during the evaluation of $e$, the getter for $v$ is invoked, a \code{CyclicInitializationError} is thrown.
-If the evaluation succeeded yielding an object $o$, let $r$ be $o$, otherwise let $r$ be the null object (\ref{null}).
-In any case, $r$ is stored into $v$.
-The result of executing the getter is $r$.
+If $d$ is of one of the forms
+\code{\VAR{} $v$ = $e$;},
+\code{$T$ $v$ = $e$;},
+\code{\FINAL{} $v$ = $e$;},
+\code{\FINAL{} $T$ $v$ = $e$;},
+\code{\STATIC{} $v$ = $e$;},
+\code{\STATIC{} $T$ $v$ = $e$; },
+\code{\STATIC{} \FINAL{} $v$ = $e$; } or
+\code{\STATIC{} \FINAL{} $T$ $v$ = $e$;}
+and no value has yet been stored into $v$
+then the initializing expression $e$ is evaluated.
+If, during the evaluation of $e$, the getter for $v$ is invoked,
+a \code{CyclicInitializationError} is thrown.
+If the evaluation of $e$ throws an exception $e$ and stack trace $s$,
+the null object (\ref{null}) is stored into $v$;
+the execution of the getter then throws $e$ and stack trace $s$.
+Otherwise, the evaluation of $e$ succeeded yielding an object $o$;
+then $o$ is stored into $v$ and
+the execution of the getter completes by returning $o$.
+Otherwise,
+(\commentary{when a value $o$ has been stored in $v$})
+execution of the getter completes by returning $o$.
 \item {\bf Constant variable declaration}.
-If $d$ is of one of the forms \code{\CONST{} $v$ = $e$;}, \code{\CONST{} $T$ $v$ = $e$;}, \code{\STATIC{} \CONST{} $v$ = $e$;} or \code{\STATIC{} \CONST{} $T$ $v$ = $e$;} the result of the getter is the value of the compile-time constant $e$.
+If $d$ is of one of the forms
+\code{\CONST{} $v$ = $e$;},
+\code{\CONST{} $T$ $v$ = $e$;},
+\code{\STATIC{} \CONST{} $v$ = $e$;} or
+\code{\STATIC{} \CONST{} $T$ $v$ = $e$;}
+the result of the getter is the value of the compile-time constant $e$.
 \commentary{
-Note that a compile-time constant cannot depend on itself, so no cyclic references can occur.
+Note that a compile-time constant cannot depend on itself,
+so no cyclic references can occur.
 }
-Otherwise
 \item {\bf Variable declaration without initializer}.
 The result of executing the getter method is the value stored in $v$.
+\commentary{This may be the initial value, that is, the null object.}
 \end{itemize}
 
 
@@ -867,27 +952,29 @@
 \begin{itemize}
 \item A block statement (\ref{blocks}) containing the statements (\ref{statements}) executed by the function, optionally marked with one of the modifiers: \ASYNC, \ASYNC* or \SYNC*.
 
-\commentary{
-Because Dart is optionally typed, we cannot guarantee that a function that does not return a value will not be used in the context of an expression.
-Therefore, every function must return a value.
-A function body that ends without doing a throw or return will cause the function to return the null object (\ref{null}), as will a \RETURN{} without an expression.
-For generator functions, the situation is more subtle.
-See further discussion in section \ref{return}.
-}
+  \commentary{
+  Because Dart is optionally typed, we cannot guarantee that a function that does not return a value will not be used in the context of an expression.
+  Therefore, every function must return a value.
+  A function body that ends without doing a throw or return will cause the function to return the null object (\ref{null}),
+  as will a \RETURN{} without an expression.
+  For generator functions, the situation is more subtle.
+  See further discussion in section \ref{return}.
+  }
 
 OR
 \item of the form \code{=> $e$} or the form \code{\ASYNC{} => $e$}, which both return the value of the expression $e$ as if by a \code{return $e$}.
-\commentary{
-The other modifiers do not apply here, because they apply only to generators, discussed below, and generators do not allow to return a value, values are added to the generated stream or iterable using \YIELD{} instead.
-}
-Let $R$ be the static type of $e$
-and let $T$ be the actual return type (\ref{actualTypeOfADeclaration})
-of the function that has this body.
-It is a compile-time error if $T$ is not \VOID{} and either
-the function is synchronous and the static type of $R$ is not assignable to $T$,
-or the function is asynchronous and \code{Future<$flatten(R)$>}
-is not assignable to $T$.
-
+  \commentary{
+  The other modifiers do not apply here, because they apply only to generators, discussed below,
+  and generators are not allowed to return a value, values are added to the generated stream or iterable using \YIELD{} instead.
+  }
+  Let $R$ be the static type of $e$
+  and let $T$ be the declared return type of the function that has this body.
+  It is a compile-time error unless one of the following conditions hold:
+  \begin{itemize}
+  \item $T$ is \VOID{}.
+  \item The function is synchronous and $R$ is assignable to $T$.
+  \item The function is asynchronous and \code{Future<\flatten{R}>} is assignable to $T$.
+  \end{itemize}
 \end{itemize}
 
 \LMHash{}
@@ -897,7 +984,8 @@
 
 \commentary{
 Whether a function is synchronous or asynchronous is orthogonal to whether it is a generator or not.
-Generator functions are a sugar for functions that produce collections in a systematic way, by lazily applying a function that {\em generates} individual elements of a collection.
+Generator functions are a sugar for functions that produce collections in a systematic way,
+by lazily applying a function that {\em generates} individual elements of a collection.
 Dart provides such a sugar in both the synchronous case, where one returns an iterable, and in the asynchronous case, where one returns a stream.
 Dart also allows both synchronous and asynchronous functions that produce a single value.
 }
@@ -906,9 +994,10 @@
 It is a compile-time error if an \ASYNC, \ASYNC* or \SYNC* modifier is attached to the body of a setter or constructor.
 
 \rationale{
-An asynchronous setter would be of little use, since setters can only be used in the context of an assignment (\ref{assignment}), and an assignment expression always evaluates to the value of the assignment's right hand side.
-If the setter actually did its work asynchronously, one might imagine that one would return a future that resolved to the assignment's right hand side after the setter did its work.
-However, this would require dynamic tests at every assignment, and so would be prohibitively expensive.
+An asynchronous setter would be of little use, since setters can only be used in the context of an assignment (\ref{assignment}),
+and an assignment expression always evaluates to the value of the assignment's right hand side.
+If the setter actually did its work asynchronously,
+one might imagine that one would return a future that resolved to the assignment's right hand side after the setter did its work.
 
 An asynchronous constructor would, by definition, never return an instance of the class it purports to construct, but instead return a future.
 Calling such a beast via \NEW{} would be very confusing.
@@ -919,6 +1008,7 @@
 No other scenario makes sense because the object returned by the factory would be of the wrong type.
 This situation is very unusual so it is not worth making an exception to the general rule for constructors in order to allow it.
 }
+
 \LMHash{}
 It is a compile-time error if the declared return type of a function marked \ASYNC{} is not a supertype of \code{Future<$T$>} for some type $T$.
 It is a compile-time error if the declared return type of a function marked \SYNC* is not a supertype of \code{Iterable<$T$>} for some type $T$.
@@ -1234,7 +1324,7 @@
 
 \begin{grammar}
 {\bf classDefinition:}metadata \ABSTRACT{}? \CLASS{} identifier typeParameters?
-  \gnewline{} (superclass mixins?)? interfaces?
+  \gnewline{} superclass? mixins? interfaces?
   \gnewline{} `\{' (metadata classMemberDefinition)* `\}';
   metadata \ABSTRACT{}? \CLASS{} mixinApplicationClass
   .
@@ -1289,7 +1379,7 @@
 \LMHash{}
 A class has constructors, instance members and static members.
 The instance members of a class are its instance methods, getters, setters and instance variables.
-The static members of a class are its static methods, getters, setters and static variables.
+The static members of a class are its static methods, getters, setters and class variables.
 The members of a class are its static and instance members.
 
 \LMHash{}
@@ -1572,14 +1662,17 @@
 }
 
 \commentary{
-Invoking an abstract method, getter or setter results in an invocation of \code{noSuchMethod} exactly as if the declaration did not exist, unless a suitable member $a$ is available in a superclass, in which case $a$ is invoked.
-The normative specification for this appears under the definitions of lookup for methods, getters and setters.
+Invocation of an abstract method, getter, or setter cannot occur,
+because lookup (\ref{lookup}) will never yield an abstract member as its result.
+One way to think about this is that
+an abstract member declaration in a subclass
+does not override or shadow an inherited member implementation.
+It only serves to specify the signature of the given member that
+every concrete subtype must have an implementation of;
+that is, it contributes to the interface of the class,
+not to the class itself.
 }
 
-% so does an abstract method override a method in a superclass or not? Does the superclass method get inherited or not?  This generally makes the spec inconsistent, as there is no simple answer.
-% For example - if we say it does not override, then the superclass member is inherited, in which case the rules for errors break down, and also there is question of whether there are two definitions of the same name.
-% But if we do override, method lookup rules break down.  So several things need revisiting.
-
 \rationale{
 The purpose of an abstract method is to provide a declaration for purposes such as type checking and reflection.
 In classes used as mixins, it is often useful to introduce such declarations for methods that the mixin expects will be provided by the superclass the mixin is applied to.
@@ -1828,7 +1921,8 @@
 of the corresponding formal parameter in the declaration of $k$.
 It is a dynamic error if an actual argument passed to the redirectee $k'$ of a redirecting generative constructor
 is not a subtype of the actual type
-(\ref{actualTypeOfADeclaration}) of the corresponding formal parameter in the declaration of the redirectee.
+(\ref{actualTypeOfADeclaration})
+of the corresponding formal parameter in the declaration of the redirectee.
 
 
 \paragraph{Initializer Lists}
@@ -1836,12 +1930,16 @@
 
 \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.
+
+\commentary{
+There are three kinds of initializers.
 \begin{itemize}
-\item A {\em superinitializer} identifies a {\em superconstructor} - that is, a specific constructor of the superclass.
+\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.
+\item An assertion.
 \end{itemize}
+}
 
 \begin{grammar}
 {\bf initializers:}`{\escapegrammar :}' initializerListEntry (\gcomma{} initializerListEntry)*
@@ -1858,6 +1956,36 @@
 \end{grammar}
 
 \LMHash{}
+An initializer of the form \code{$v$ = $e$} is equivalent to
+an initializer of the form \code{\THIS{}.$v$ = $e$},
+both forms are called {\em instance variable initializers}.
+It is a compile-time error if the enclosing class does not declare an instance variable named $v$.
+Otherwise, let $T$ be the static type of $v$.
+It is a compile-time error unless the static type of $e$ is assignable to $T$.
+
+\LMHash{}
+Consider a {\em superinitializer} $s$ of the form
+
+\code{\SUPER{}($a_1, \ldots,\ a_n,\ x_{n+1}: a_{n+1}, \ldots,\ x_{n+k}$: $a_{n+k}$)}
+respectively
+
+\code{\SUPER{}.\id($a_1, \ldots,\ a_n,\ x_{n+1}: a_{n+1}, \ldots,\ x_{n+k}$: $a_{n+k}$)}.
+
+\noindent{}%
+Let $S$ be the superclass of the enclosing class of $s$.
+It is a compile-time error if class $S$ does not declare a generative constructor named $S$ (respectively \code{$S$.\id}).
+Otherwise, the static analysis of $s$ is performed as specified in Section~\ref{bindingActualsToFormals},
+as if \code{\SUPER{}} respectively \code{\SUPER{}.\id}
+had had the function type of the denoted constructor,
+%% TODO(eernst): The following is very imprecise, it just serves to remember
+%% that we must specify how to deal with the type variables in that parameter
+%%  part. One thing that we weasel over is that the superclass may be a mixin
+%% application.
+and substituting the formal type variables of the superclass
+for the corresponding actual type arguments passed to the superclass
+in the header of the current class.
+
+\LMHash{}
 Let $k$ be a generative constructor.
 Then $k$ may include at most one superinitializer in its initializer list or a compile-time error occurs.
 If no superinitializer is provided, an implicit superinitializer of the form \SUPER{}() is added at the end of $k$'s initializer list,
@@ -1885,10 +2013,15 @@
 \LMHash{}
 It is a compile-time error if a generative constructor of class \code{Object} includes a superinitializer.
 
+
+\paragraph{Execution of Generative Constructors}
+\LMLabel{executionOfGenerativeConstructors}
+
 \LMHash{}
 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$.
+and the type parameters of the immediately enclosing class bound to
+a set of actual type arguments of $T$, $t_1, \ldots, t_m$.
 
 \commentary{
 These bindings are usually determined by the instance creation expression that invoked the constructor (directly or indirectly).
@@ -1902,17 +2035,25 @@
 
 where $g$ identifies another  generative constructor of the immediately surrounding class.
 Then execution of $k$ to initialize $i$ proceeds by evaluating the argument list
-\code{($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
 \code{($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$.
+to an actual argument list $a$ of the form
+\code{($o_1, \ldots,\ o_n,\ x_{n+1}$: $o_{n+1}, \ldots,\ x_{n+k}$: $o_{n+k}$)}
+in an environment where the type parameters of the enclosing class are bound to
+$t_1, \ldots, t_m$.
 
 \LMHash{}
-Otherwise, execution proceeds as follows:
+Next, the body of $g$ is executed to initialize $i$ with respect to the bindings that map
+the formal parameters of $g$ to the corresponding objects in the actual argument list $a$,
+with \THIS{} bound to $i$,
+and the type parameters of the immediately enclosing class bound to $t_1, \ldots, t_m$.
+
+\LMHash{}
+Otherwise, $k$ is not redirecting.
+Execution then proceeds as follows:
 
 \LMHash{}
 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$; }
+For each such declaration $d$, if $d$ has the form \code{\metavar{finalConstVarOrType} $v$ = $e$; }
 then $e$ is evaluated to an object $o$
 and the instance variable $v$ of $i$ is bound to $o$.
 
@@ -1921,7 +2062,8 @@
 % In fact, this order is unobservable; this could be done any time prior to running the body, since
 % these only effect \THIS{}.
 Then, the initializers of $k$'s initializer list are executed to initialize $i$
-in the order they appear in the program.
+in the order they appear in the program, as described below
+(p.\,\pageref{executionOfInitializerLists}).
 
 \rationale{
 We could observe the order by side effecting external routines called.
@@ -1944,9 +2086,14 @@
 \rationale{
 This process ensures that no uninitialized final instance variable 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.
+an instance method cannot be directly invoked,
+nor can \THIS{} be passed into any other code being invoked in the initializer.
 }
 
+
+\paragraph{Execution of Initializer Lists}
+\LMLabel{executionOfInitializerLists}
+
 \LMHash{}
 During the execution of a generative constructor to initialize an instance $i$,
 execution of an initializer of the form \code{\THIS{}.$v$ = $e$}
@@ -1955,45 +2102,46 @@
 \LMHash{}
 First, the expression $e$ is evaluated to an object $o$.
 Then, the instance variable $v$ of $i$ is bound to $o$.
-In checked mode, it is a dynamic type error if $o$ is not the null object (\ref{null}) and the interface of the class of $o$ is not a subtype of the actual type of the instance variable $v$.
-
-\LMHash{}
-An initializer of the form \code{$v$ = $e$} is equivalent to an initializer of the form \code{\THIS{}.$v$ = $e$}.
+In checked mode,
+it is a dynamic type error if $o$ is not the null object
+(\ref{null})
+and the interface of the class of $o$ is not a subtype of the actual type
+(\ref{actualTypeOfADeclaration})
+of the instance variable $v$.
 
 \LMHash{}
 Execution of an initializer that is an assertion proceeds by executing the assertion (\ref{assert}).
 
 \LMHash{}
-Execution of a superinitializer of the form
+Consider a superinitializer $s$ of the form
 
 \code{\SUPER{}($a_1, \ldots,\ a_n,\ x_{n+1}: a_{n+1}, \ldots,\ x_{n+k}$: $a_{n+k}$)}
+respectively
 
-(respectively
-\code{\SUPER{}.\id($a_1, \ldots,\ a_n,\ x_{n+1}: a_{n+1}, \ldots,\ x_{n+k}$: $a_{n+k}$)})
-
-proceeds as follows:
+\code{\SUPER{}.\id($a_1, \ldots,\ a_n,\ x_{n+1}$: $a_{n+1}, \ldots,\ x_{n+k}$: $a_{n+k}$)}.
 
 \LMHash{}
-First, the argument list
+Let $C$ be the class in which $s$ appears and let $S$ be the superclass of $C$.
+If $S$ is generic (\ref{generics}),
+let $u_1, \ldots, u_p$ be the actual type arguments passed to $S$,
+obtained by substituting $t_1, \ldots, t_m$
+for the formal type parameters of $C$
+in the superclass as specified in the header of $C$, and
+$t_1, \ldots, t_m$
+are the actual bindings of the type variables of $C$.
+Let $k$ be the constructor declared in $S$ and named
+$S$ respectively \code{$S$.\id}.
+
+\LMHash{}
+Execution of $s$ proceeds as follows:
+The argument list
 \code{($a_1, \ldots,\ a_n,\ x_{n+1}$: $a_{n+1}, \ldots,\ x_{n+k}$: $a_{n+k}$)}
-is evaluated.
-
-\LMHash{}
-Then the superconstructor is executed as follows:
-
-\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_p$ be the actual type arguments passed to $S$,
-obtained by substituting $V_1, \ldots, V_m$ for the formal parameters in the superclass clause of $C$.
-
-\LMHash{}
-The generative constructor $S$ (respectively \code{$S$.\id}) of $S$ is executed
-to initialize $i$ with respect to the bindings that resulted from the evaluation of
-\code{($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_p$.
-
-\LMHash{}
-It is a compile-time error if class $S$ does not declare a generative constructor named $S$ (respectively \code{$S$.\id}).
+is evaluated to an actual argument list $a$ of the form
+\code{($o_1, \ldots,\ o_n,\ x_{n+1}$: $o_{n+1}, \ldots,\ x_{n+k}$: $o_{n+k}$)}.
+Then the body of the superconstructor $k$ is executed
+in an environment where the formal parameters of $k$ are bound to
+the corresponding actual arguments from $a$,
+and the formal type parameters of $S$ are bound to $u_1, \ldots, u_p$.
 
 
 \subsubsection{Factories}
@@ -2066,6 +2214,15 @@
 The {\em redirectee constructor} for this declaration is then the constructor denoted by $R$.
 
 \LMHash{}
+A redirecting factory constructor $q'$ is {\em redirection-reachable}
+from a redirecting factory constructor $q$ if{}f
+$q'$ is the redirectee constructor of $q$,
+or $q''$ is the redirectee constructor of $q$
+and $q'$ is redirection-reachable from $q''$.
+It is a compile-time error if a redirecting factory constructor
+is redirection-reachable from itself.
+
+\LMHash{}
 Let $\argumentList{T}$ be the static argument list type (\ref{actualArgumentLists})
 \code{($T_1 \ldots,\ T_{n+k}$)}
 when $k$ takes no named arguments, and
@@ -2214,7 +2371,7 @@
 }
 
 \LMHash{}
-It is a compile-time error if a constant constructor is declared by a class that has a non-final instance variable.
+It is a compile-time error if a constant constructor is declared by a class that has a mutable instance variable.
 
 \commentary{
 The above refers to both locally declared and inherited instance variables.
@@ -2355,51 +2512,6 @@
 }
 
 
-\subsection{Static Variables}
-\LMLabel{staticVariables}
-
-\LMHash{}
-{\em Static variables} are variables whose declarations are immediately contained within a class declaration and that are declared \STATIC{}.
-The static variables of a class $C$ are those static variables declared by $C$.
-
-%A static variable declaration of one of the forms \code{\STATIC{} $T$ $v$;}, \code{\STATIC{} $T$ $v$ = $e$;}, \code{\STATIC{} \CONST{} $T$ $v$ = $e$;} or \code{\STATIC{} \FINAL{} $T$ $v$ = $e$;} always induces an implicit static getter function (\ref{getters}) with signature
-
-%\STATIC{} $T$ \GET{} $v$
-
-%whose invocation evaluates as described below (\ref{evaluationOfStaticVariableGetters}).%to the value stored in $v$.
-
-%A static variable declaration of one of the forms \code{\STATIC{} \VAR{} $v$;}, \code{\STATIC{} \VAR{} $v$ = $e$;}, \code{\STATIC{} \CONST{} $v$ = $e$;} or \code{\STATIC{} \FINAL{} $v$ = $e$;} always induces an implicit static getter function with signature
-
-%\STATIC{} \GET{} $v$
-
-%whose invocation evaluates as described below (\ref{evaluationOfStaticVariableGetters}).%to the value stored in $v$.
-
-%A non-final static variable declaration of the form \code{\STATIC{} $T$ $v$;} or the form \code{\STATIC{} $T$ $v$ = $e$;} always induces an implicit static setter function (\ref{setters}) with signature
-
-%\STATIC{} \VOID{} \SET{} $v=(T$ $x)$
-
-%whose execution sets the value of $v$ to the incoming argument $x$.
-
-%A static variable declaration of the form \code{\STATIC{} \VAR{} $v$;} or the form \code{\STATIC{} \VAR{} $v$ = $e$;} always induces an implicit static setter function with signature
-
-%\STATIC{} \SET{} $v=(x)$
-
-%whose execution sets the value of $v$ to the incoming argument $x$.
-
-%Extrernal static functions, getters, setters
-
-%\subsubsection{Evaluation of Implicit Static Variable Getters}
-%\LMLabel{evaluationOfStaticVariableGetters}
-
-%Let $d$ be the declaration of a static variable $v$. The implicit getter method of $v$ executes as follows:
-%\begin{itemize}
-%\item If $d$ is of one of the forms \code{\STATIC{} \VAR{} $v$ = $e$;} , \code{\STATIC{} $T$ $v$ = $e$; }, \code{\STATIC{} \FINAL{} $v$ = $e$; } or \code{\STATIC{} \FINAL{} $T$ $v$ = $e$;} and no value has yet been stored into $v$ then the initializer expression $e$ is evaluated. If, during the evaluation of $e$, the getter for $v$ is referenced, a \code{CyclicInitializationError} is thrown. If the evaluation succeeded yielding an object $o$, let $r$ be $o$, otherwise let $r$ be the null object (\ref{null}). In any case, $r$ is stored into $v$. The result of executing the getter is $r$.
-%\item If $d$ is of one of the forms \code{\STATIC{} \CONST{} $v$ = $e$; } or \code{\STATIC{} \CONST{} $T$ $v$ = $e$;} the result of the getter is the value of the compile-time constant $e$.
-%Otherwise
-%\item The result of executing the getter method is the value stored in $v$.
-%\end{itemize}
-
-
 \subsection{Superclasses}
 \LMLabel{superclasses}
 
@@ -2449,6 +2561,8 @@
 \end{dartCode}
 
 \LMHash{}
+%% TODO(eernst): Consider replacing all occurrences of `a superclass`
+%% by `a direct or indirect superclass`, because it's too confusing.
 A class $S$ is {\em a superclass} of a class $C$ if{}f either:
 \begin{itemize}
 \item $S$ is the superclass of $C$, or
@@ -2463,11 +2577,11 @@
 \subsubsection{Inheritance and Overriding}
 \LMLabel{inheritanceAndOverriding}
 
-%A class $C$ {\em inherits} any accessible instance members of its superclass that are not overridden by members declared in $C$.
-
 \LMHash{}
-Let $C$ be a class, let $A$ be a superclass of $C$, and let $S_1, \ldots, S_k$ be superclasses of $C$ that are also subclasses of $A$.
-$C$ {\em inherits} all accessible instance members of $A$ that have not been overridden by a declaration in $C$ or in at least one of $S_1, \ldots, S_k$.
+Let $C$ be a class, let $A$ be a superclass of $C$, and
+let $S_1, \ldots, S_k$ be superclasses of $C$ that are also subclasses of $A$.
+$C$ {\em inherits} all concrete, accessible instance members of $A$
+that have not been overridden by a concrete declaration in $C$ or in at least one of $S_1, \ldots, S_k$.
 
 \rationale{
 It would be more attractive to give a purely local definition of inheritance, that depended only on the members of the direct superclass $S$.
@@ -2481,11 +2595,16 @@
 A class may override instance members that would otherwise have been inherited from its superclass.
 
 \LMHash{}
-Let $C = S_0$ be a class declared in library $L$, and let $\{S_1, \ldots, S_k\}$ be the set of all superclasses of $C$, where $S_i$ is the superclass of $S_{i-1}$ for $i \in 1 .. k$.
-Let $C$ declare a member $m$, and let $m'$ be a member of $S_j, j \in 1 .. k$, that has the same name as $m$, such that $m'$ is accessible to $L$.
-Then $m$ overrides $m'$ if $m'$ is not already overridden by a member of at least one of $S_1, \ldots, S_{j-1}$ and neither $m$ nor $m'$ are instance variables.
-
-%Let $C$ be a class declared in library $L$, with superclass $S$ and let $C$ declare an instance member $m$, and assume $S$ declares an instance member $m'$ with the same name as $m$. Then $m$ {\em overrides} $m'$ if{}f $m'$ is accessible (\ref{privacy}) to $L$, $m$ has the same name as $m'$ and neither $m$ nor $m'$ are fields.
+Let $C = S_0$ be a class declared in library $L$, and
+let $\{S_1, \ldots, S_k\}$ be the set of all superclasses of $C$,
+where $S_i$ is the superclass of $S_{i-1}$ for $i \in 1 .. k$.
+\commentary{This means that $S_k$ is the built-in class \code{Object}.}
+Let $C$ declare a concrete member $m$, and
+let $m'$ be a concrete member of $S_j, j \in 1 .. k$, that has the same name as $m$,
+such that $m'$ is accessible to $L$.
+Then $m$ overrides $m'$
+if $m'$ is not already overridden by a concrete member of at least one of $S_1, \ldots, S_{j-1}$
+and neither $m$ nor $m'$ are instance variables.
 
 \commentary{
 Instance variables never override each other.
@@ -2514,53 +2633,126 @@
 Finally, static members never override anything.
 }
 
+\LMHash{}
+Let $C$ be a concrete class
+whose interface has an accessible member $m$ named \id{}.
+It is a compile-time error if $C$ does not have
+a concrete member $m'$ named \id{} which is a correct override of $m$,
+unless $C$ has a concrete method named \code{noSuchMethod}
+which is different from the one in the built-in class \code{Object},
+and $C$ does not have a concrete member named \id.
+
 \commentary{
-For convenience, here is a summary of the relevant rules, using `error' to denote compile-time errors.
+So it is an error even if $C$ does have a concrete member $m'$ named \id{}
+if $m'$ is an \emph{incorrect} override of $m$,
+also when $C$ has a \code{noSuchMethod} which is not from \code{Object}.
+Note that it is allowed to let inaccessible methods remain unimplemented;
+invocations of such methods will be redirected to \code{noSuchMethod}.
+}
+
+%% TODO(eernst): Why don't we just get rid of this list entirely?
+%% It's 'for convenience', but that's not otherwise a priority in this
+%% document, it is more important that it is correct and consistent.
+\commentary{
+For convenience, here is a summary of the relevant rules,
+using `error' to denote compile-time errors.
 Remember that this is not normative.
 The controlling language is in the relevant sections of the specification.
 
 \begin{enumerate}
 
-\item There is only one namespace for getters, setters, methods and constructors (\ref{scoping}).
-  An instance or static variable $f$ introduces a getter $f$ and a non-final instance or static variable $f$ also introduces a setter $f=$ (\ref{instanceVariables}, \ref{staticVariables}).
-  When we speak of members here, we mean accessible instance or static variables, getters, setters, and methods (\ref{classes}).
-\item You cannot have two members with the same name in the same class - be they declared or inherited (\ref{scoping}, \ref{classes}).
+\item There is only one namespace
+  for getters, setters, methods and constructors (\ref{scoping}).
+  An instance or static variable $f$ introduces a getter $f$,
+  and a mutable instance or static variable $f$ also introduces a setter
+  \code{$f$=} (\ref{instanceVariables}, \ref{staticVariables}).
+  When we speak of members here, we mean
+  accessible instance or static variables, getters, setters, and methods
+  (\ref{classes}).
+\item You cannot have two members with the same name in the same class---be
+  they declared or inherited (\ref{scoping}, \ref{classes}).
 \item Static members are never inherited.
-\item It is an error if you have an static member named $m$ in your class and an instance member of the same name (\ref{classMemborConflicts}).
-\item It is an error if you have a static setter $v=$, and an instance member $v$ (\ref{setters}).
-\item It is an error if you have a static getter $v$ and an instance setter $v=$ (\ref{getters}).
-\item If you define an instance member named $m$, and your superclass has an instance member of the same name, they override each other.
-This may or may not be legal.
+\item It is an error if you have a static member named $m$ in your class
+  and an instance member of the same name (\ref{classMemberConflicts}).
+\item It is an error if you have a static setter \code{$v$=},
+  and an instance member $v$ (\ref{setters}).
+\item It is an error if you have a static getter $v$
+  and an instance setter \code{$v$=} (\ref{getters}).
+\item If you define an instance member named $m$,
+  and your superclass has an instance member of the same name,
+  they override each other.
+  This may or may not be legal.
 \item \label{typeSigAssignable}
-%% TODO(eernst): This is commentary, but we may need to adjust it to say 'correctly overrides'.
-If two members override each other, it is an error if their type signatures are not assignable to each other (\ref{instanceMethods}, \ref{getters}, \ref{setters}) (and since these are function types, this means the same as "subtypes of each other").
+  %% TODO(eernst): This is commentary, but we may need to adjust it
+  %% to say 'correctly overrides'.
+  If two members override each other,
+  it is an error if their type signatures are not assignable to each other
+  (\ref{instanceMethods}, \ref{getters}, \ref{setters})
+  %% TODO(eernst): Revisit relative to the new subtyping.md rules.
+  (and since these are function types, this means the same as
+  "subtypes of each other").
 \item \label{requiredParams}
-If two members override each other, it is an error if the overriding member has more required parameters than the overridden one (\ref{instanceMethods}).
+  If two members override each other,
+  it is an error if the overriding member has
+  more required parameters than the overridden one (\ref{instanceMethods}).
 \item \label{optionalPositionals}
-If two members override each other, it is an error if the overriding member has fewer positional parameters than the overridden one (\ref{instanceMethods}).
+  If two members override each other,
+  it is an error if the overriding member has
+  fewer positional parameters than the overridden one (\ref{instanceMethods}).
 \item \label{namedParams}
-If two members override each other, it is an error if the overriding member does not have all the named parameters that the overridden one has (\ref{instanceMethods}).
-\item Setters, getters and operators never have optional parameters of any kind; it's an error (\ref{operators}, \ref{getters}, \ref{setters}).
-\item It is an error if a member has the same name as its enclosing class (\ref{classes}).
+  If two members override each other,
+  it is an error if the overriding member does not have
+  all the named parameters that the overridden one has (\ref{instanceMethods}).
+\item Setters, getters and operators never have
+  optional parameters of any kind;
+  it's an error (\ref{operators}, \ref{getters}, \ref{setters}).
+\item
+  It is an error if a member has the same name as its enclosing class
+  (\ref{classes}).
 \item A class has an implicit interface (\ref{classes}).
-\item Superinterface members are not inherited by a class, but are inherited by its implicit interface.
-Interfaces have their own inheritance rules (\ref{interfaceInheritanceAndOverriding}).
-\item A member is abstract if it has no body and is not labeled \EXTERNAL{} (\ref{abstractInstanceMembers}, \ref{externalFunctions}).
-\item A class is abstract if{}f it is explicitly labeled \ABSTRACT{}.% or if it declares (not just inherits) an abstract member (\ref{classes}).
-\item It is an error if a concrete class has an abstract member (declared or inherited).
-\item It is an error to call a non-factory constructor of an abstract class using an instance creation expression (\ref{instanceCreation}),
-  such a constructor may only be invoked from another constructor using a super invocation (\ref{superinvocation}).
+\item Superinterface members are not inherited by a class,
+  but are inherited by its implicit interface.
+  Interfaces have their own inheritance rules
+  (\ref{interfaceInheritanceAndOverriding}).
+\item A member is abstract if
+  it has no body and is not labeled \EXTERNAL{}
+  (\ref{abstractInstanceMembers}, \ref{externalFunctions}).
+\item A class is abstract if{}f it is explicitly labeled \ABSTRACT{}.
+\item It is an error if a concrete class has an abstract member
+  (declared or inherited), and there is no \code{noSuchMethod}.
+\item It is an error to call a non-factory constructor of an abstract class
+  using an instance creation expression (\ref{instanceCreation}),
+  such a constructor may only be invoked from another constructor
+  using a super invocation (\ref{superInvocation}).
 \item If a class defines an instance member named $m$,
   and any of its superinterfaces have a member named $m$,
   the interface of the class contains the $m$ from the class itself.
-\item An interface inherits all members of its superinterfaces that are not overridden and not members of multiple superinterfaces.
-\item If multiple superinterfaces of an interface define a member with the same name $m$, then at most one member is inherited.
-%% TODO(eernst): Switch to use 'correctly overrides' terminology.
-That member (if it exists) is the one whose type is a subtype of all the others.
-If there is no such member, then an error occurs (\ref{interfaceInheritanceAndOverriding}).
-\item Rule \ref{typeSigAssignable} applies to interfaces as well as classes (\ref{interfaceInheritanceAndOverriding}).
-\item It is an error if a concrete class does not have an implementation for a method in any of its superinterfaces unless it has a concrete \code{noSuchMethod} method (\ref{superinterfaces}) distinct from the one in class \code{Object}.
-\item The identifier of a named constructor cannot be the same as the name of a member declared (as opposed to inherited) in the same class (\ref{constructors}).
+\item
+  %% TODO(eernst): This needs to be updated when we introduce the
+  %% new override/conflict rules.
+  An interface inherits all members of its superinterfaces
+  that are not overridden and not members of multiple superinterfaces.
+\item
+  %% TODO(eernst): This must be rewritten when we introduce the new
+  %% override/conflict rules.
+  If multiple superinterfaces of an interface
+  define a member with the same name $m$,
+  then at most one member is inherited.
+  %% TODO(eernst): Switch to use 'correctly overrides' terminology.
+  That member (if it exists) is the one whose type is a subtype
+  of all the others.
+  If there is no such member, then an error occurs
+  (\ref{interfaceInheritanceAndOverriding}).
+\item Rule \ref{typeSigAssignable} applies to interfaces as well as classes
+  (\ref{interfaceInheritanceAndOverriding}).
+\item It is an error if a concrete class does not have an implementation
+  for a method in any of its superinterfaces
+  unless it has a concrete \code{noSuchMethod} method
+  (\ref{superinterfaces})
+  distinct from the one in class \code{Object}.
+\item The identifier of a named constructor cannot be
+  the same as the name of a static member declared in the same class
+  (\ref{classMemberConflicts}).
 \end{enumerate}
 }
 
@@ -2785,7 +2977,7 @@
 A mixin application of the form \code{$S$ \WITH{} $M$;} for the name $N$ defines a class $C$ with superclass $S$ and name $N$.
 
 \LMHash{}
-A mixin application of the form \code{$S$ \WITH{} $M_1,\ \ldots, M_k$;} for the name $N$ defines a class $C$ whose superclass is the application of the mixin composition (\ref{mixinComposition}) $M_{k-1} * \ldots * M_1$ to $S$ of a name that is a fresh identifer, and whose name is $N$.
+A mixin application of the form \code{$S$ \WITH{} $M_1,\ \ldots,\ M_k$;} for the name $N$ defines a class $C$ whose superclass is the application of the mixin composition (\ref{mixinComposition}) $M_{k-1} * \ldots * M_1$ to $S$ of a name that is a fresh identifer, and whose name is $N$.
 \rationale{The name of the resulting class is necessary because it is part of the names of the introduced constructors.}
 
 \LMHash{}
@@ -2977,7 +3169,10 @@
 
 \commentary{
 This allows non-generic cases to be included implicitly as special cases.
-For example, an invocation of a non-generic function arises as the special case where the function takes zero type arguments, and zero type arguments are passed.
+For example,
+an invocation of a non-generic function arises as the special case
+where the function takes zero type arguments,
+and zero type arguments are passed.
 In this situation some operations are also omitted (have no effect), e.g.,
 operations where formal type parameters are replaced by actual type arguments.
 }
@@ -3679,7 +3874,7 @@
 \begin{itemize}
 \item A literal number (\ref{numbers}).
 \item A literal boolean (\ref{booleans}).
-\item A literal string (\ref{strings}) where any interpolated expression (\ref{stringInterpolation}) is a compile-time constant that evaluates to a numeric, string or boolean value or to the null object (\ref{null}).
+\item A literal string (\ref{strings}) where every interpolated expression (\ref{stringInterpolation}) is a compile-time constant that evaluates to a numeric, string or boolean value or to the null object (\ref{null}).
 \rationale{
 It would be tempting to allow string interpolation where the interpolated value is any compile-time constant.
 However, this would require running the \code{toString()} method for constant objects, which could contain arbitrary code.
@@ -3688,7 +3883,7 @@
 \item \NULL{} (\ref{null}).
 \item A qualified reference to a static constant variable (\ref{variables}) that is not qualified by a deferred prefix.
 \commentary{
-For example, If class C declares a constant static variable v, C.v is a constant.
+For example, if class C declares a constant variable v, C.v is a constant.
 The same is true if C is accessed via a prefix p; p.C.v is a constant unless p is a deferred prefix.
 }
 \item An identifier expression that denotes a constant variable.
@@ -3874,10 +4069,16 @@
 An {\em integer literal} is either a hexadecimal integer literal or a decimal integer literal.
 
 \LMHash{}
-An integer literal has static type \code{int},
-unless the surrounding static context type is a type
-which \code{int} is not assignable to, and \code{double} is.
-In that case the static type of the integer literal is \code{double}.
+Let $l$ be an integer literal that is not the operand
+of by a unary minus operator,
+and let $T$ be the static context type of $l$.
+If \code{double} is assignable to $T$ and \code{int} is not assignable to $T$,
+then the static type of $l$ is \code{double};
+otherwise the static type of $l$ is \code{int}.
+\commentary{
+  This means that an integer literal denotes a \code{double}
+  when it would satisfy the type requirement, and an \code{int} would not. Otherwise it is an \code{int}, even in situations where that is an error.
+}
 
 \LMHash{}
 A numeric literal that is not an integer literal is a {\em double literal}.
@@ -3885,19 +4086,20 @@
 The static type of a double literal is \code{double}.
 
 \LMHash{}
-If the \code{int} class is implemented as signed 64-bit two's complement integers,
-and a hexadecimal integer literal with static type \code{int}
-and numeric value $i \ge{} 2^{63}$ is not prefixed by a unary minus operator,
-then it is a compile-time error if $i \ge{} 2^{64}$, and otherwise
-the hexadecimal integer literal evaluates to an instance of the \code{int} class
-representing the value $i - 2^{64}$.
-
-\LMHash{}
-Otherwise an integer literal with static type \code{int}
-that is not prefixed by a unary minus operator,
-evaluates to an instance of the \code{int} class representing the integer value $i$,
-and it is a compile-time error if the integer $i$ cannot be represented exactly
-by an instance of \code{int}.
+If $l$ is an integer literal with numeric value $i$ and static type \code{int},
+and $l$ is not the operand of a unary minus operator,
+then evaluation of $l$ proceeds as follows:
+\begin{itemize}
+  \item{} If $l$ is a hexadecimal integer literal,
+  $2^{63} \le{} i \lt{} 2^{64}$ and the \code{int} class is implemented as
+  signed 64-bit two's complement integers,
+  then $l$ evaluates to an instance of the \code{int} class
+  representing the numeric value $i - 2^{64}$,
+  \item{} Otherwise $l$ evaluates to an instance of the \code{int} class
+  representing the numeric value $i$.
+  It is a compile-time error if the integer $i$ cannot be represented
+  exactly by an instance of \code{int}.
+\end{itemize}
 
 \commentary{
 Integers in Dart are designed to be implemented as
@@ -3918,7 +4120,7 @@
 An integer literal with static type \code{double} and numeric value $i$
 evaluates to an instance of the \code{double} class representing
 the value $i$. It is a compile-time error if the value $i$ cannot be
-represented {\em precisely} by the an instace of \code{double}.
+represented {\em precisely} by the an instance of \code{double}.
 \commentary{
 A 64 bit double precision floating point number
 is usually taken to represent a range of real numbers
@@ -4370,10 +4572,12 @@
 
 \LMHash{}
 It is a compile-time error if either a key or a value of an entry in a constant map literal is not a compile-time constant.
-It is a compile-time error if the key of an entry in a constant map literal is an instance of a class that implements the operator $==$ unless the key is a
-%symbol,
-string, an integer, a literal symbol or the result of invoking a constant constructor of class \code{Symbol}.
-It is a compile-time error if the type arguments of a constant map literal include a type parameter.
+It is a compile-time error if the key of an entry in a constant map literal is an instance of
+a class that has a concrete operator \code{==} declaration different from the one in \code{Object},
+unless the key is a string or an integer,
+or the key expression is a literal symbol or
+an invocation of a constant constructor of class \code{Symbol}.
+It is a compile-time error if the type arguments of a constant map literal include a type variable.
 
 \LMHash{}
 The value of a constant map literal \CONST{}$ <K, V>\{k_1:e_1, \ldots, k_n :e_n\}$ is an object $m$ whose class implements the built-in class $Map<K, V>$.
@@ -4524,16 +4728,16 @@
 
 \code{<$X_1\ B_1, \ldots,\ X_m\ B_m$>}
 
-\code{($T_1, \ldots,\ T_n, $ [$T_{n+1}\ x_{n+1}, \ldots,\ T_{n+k}\ x_{n+k}$]) $ \rightarrow$ Future<$flatten(T_0)$>},
+\code{($T_1, \ldots,\ T_n, $ [$T_{n+1}\ x_{n+1}, \ldots,\ T_{n+k}\ x_{n+k}$]) $ \rightarrow$ Future<\flatten{T_0}>},
 
 \noindent
 where $T_0$ is the static type of $e$.
 
 \LMHash{}
-In the previous two paragraphs, the type argument lists are omitted in the case where $m = 0$, and $flatten(T)$ is defined as follows:
+In the previous two paragraphs, the type argument lists are omitted in the case where $m = 0$, and \flatten{T} is defined as follows:
 
 \begin{itemize}
-\item If \code{$T =$ FutureOr<$S$>} then $flatten(T) = S$.
+\item If $T$ is \code{FutureOr<$S$>} for some $S$ then $\flatten{T} = S$.
 
 \item Otherwise if
 \code{$T <:$ Future}
@@ -4553,9 +4757,9 @@
 Note that $S$ is well-defined because of the requirements on superinterfaces.
 }
 
-Then $flatten(T) = S$.
+Then $\flatten{T} = S$.
 
-\item In any other circumstance, $flatten(T) = T$.
+\item In any other circumstance, $\flatten{T} = T$.
 \end{itemize}
 
 \LMHash{}
@@ -4585,7 +4789,7 @@
 
 \code{<$X_1 B_1, \ldots,\ X_m B_m$>}
 
-\code{($T_1, \ldots,\ T_n, $ \{$T_{n+1}\ x_{n+1}, \ldots,\ T_{n+k}\ x_{n+k}$\}) $ \rightarrow$ Future<$flatten(T_0)$>},
+\code{($T_1, \ldots,\ T_n, $ \{$T_{n+1}\ x_{n+1}, \ldots,\ T_{n+k}\ x_{n+k}$\}) $ \rightarrow$ Future<\flatten{T_0}>},
 
 \noindent
 where $T_0$ is the static type of $e$.
@@ -4719,7 +4923,17 @@
 \LMLabel{instanceCreation}
 
 \LMHash{}
-Instance creation expressions invoke constructors to produce instances.
+Instance creation expressions generally produce instances
+and invoke constructors to initialize them.
+
+\commentary{
+The exception is that
+a factory constructor invocation works like a regular function call.
+It may of course evaluate an instance creation expression and thus
+produce a fresh instance,
+but no fresh instances are created as a direct consequence of
+the factory constructor invocation.
+}
 
 %It is a compile-time error if any of the type arguments to a constructor of a generic type invoked by a new expression or a constant object expression do not denote types in the enclosing lexical scope.
 
@@ -4736,21 +4950,11 @@
 \code{\CONST{} $T$.\id($a_1, \ldots,\ a_n,\ x_{n+1}$: $a_{n+1}, \ldots,\ x_{n+k}$: $a_{n+k}$)},
 
 \code{\CONST{} $T$($a_1, \ldots,\ a_n,\ x_{n+1}$: $a_{n+1}, \ldots,\ x_{n+k}$: $a_{n+k}$)}
-is malformed (\ref{staticTypes}) or malbounded (\ref{parameterizedTypes}).
 
-\LMHash{}
-It is a compile-time error if the type $T$ in an instance creation expression of one of the forms
-
-\code{\NEW{} $T$.\id($a_1, \ldots,\ a_n,\ x_{n+1}$: $a_{n+1}, \ldots,\ x_{n+k}$: $a_{n+k}$)},
-
-\code{\NEW{} $T$($a_1, \ldots,\ a_n,\ x_{n+1}$: $a_{n+1}, \ldots,\ x_{n+k}$: $a_{n+k}$)},
-
-\code{\CONST{} $T$.\id($a_1, \ldots,\ a_n,\ x_{n+1}$: $a_{n+1}, \ldots,\ x_{n+k}$: $a_{n+k}$)},
-
-\code{\CONST{} $T$($a_1, \ldots,\ a_n,\ x_{n+1}$: $a_{n+1}, \ldots,\ x_{n+k}$: $a_{n+k}$)}
-
-is an enumerated type (\ref{enums}).
-%any of the type arguments to a constructor of a generic type $G$ invoked by a new expression or a constant object expression are not subtypes of the bounds of the corresponding formal type parameters of $G$.
+\noindent
+is malformed (\ref{staticTypes}),
+is malbounded (\ref{parameterizedTypes}),
+or is an enumerated type (\ref{enums}).
 
 
 \subsubsection{New}
@@ -4773,95 +4977,153 @@
 \code{\NEW{} $T$($a_1, \ldots,\ a_n,\ x_{n+1}$: $a_{n+1}, \ldots,\ x_{n+k}$: $a_{n+k}$)}.
 
 \LMHash{}
-If $T$ is a class or parameterized type accessible in the current scope then:
-\begin{itemize}
-\item
-If $e$ is of the form
-\code{\NEW{} $T$.\id($a_1, \ldots,\ a_n,\ x_{n+1}:\ a_{n+1}, \ldots,\ x_{n+k}:\ a_{n+k}$)}
-it is a compile-time error if \code{$T$.\id} is not the name of a constructor declared by the type $T$.
-\item
-If $e$ is of the form
-\code{\NEW{} $T$($a_1, \ldots,\ a_n,\ x_{n+1}$: $a_{n+1}, \ldots,\ x_{n+k}$: $a_{n+k}$)}
-it is a compile-time error if the type $T$ does not declare a constructor with the same name as the declaration of $T$.
-\end{itemize}
+It is a compile-time error if $T$ is not
+a class or a parameterized type accessible in the current scope,
+or if $T$ is a parameterized type which is not a class.
+\commentary{
+For instance, \code{\NEW{} F<int>()} is an error if \code{F} is a type alias.
+}
 
 \LMHash{}
 If $T$ is a parameterized type (\ref{parameterizedTypes})
 \code{$S$<$U_1, \ldots,\ U_m$>},
-let $R = S$.
-%It is a
-%compile-time CHANGED
-%run-time type
-%error if $S$ is not a generic (\ref{generics}) type with $m$ type parameters.
-If $T$ is not a parameterized type, let $R = T$.
-Furthermore, if $e$ is of the form
-\code{\NEW{} $T$.\id($a_1, \ldots,\ a_n,\ x_{n+1}$: $a_{n+1}, \ldots,\ x_{n+k}$: $a_{n+k}$)}
-then let $q$ be the constructor \code{$T$.\id}, otherwise let $q$ be the constructor $T$.
+let $R$ be the generic class $S$,
+and let
+\code{$X_1\ \EXTENDS\ B_1, \ldots,\ X_p\ \EXTENDS\ B_p$}
+be the formal type parameters of $S$.
+If $T$ is not a parameterized type, let $R$ be $T$.
 
-\LMHash{}
-If $R$ is a generic with $l = m$ type parameters then
 \begin{itemize}
-\item If $T$ is not a parameterized type, then for $ i \in 1 .. l$, let $V_i = \DYNAMIC{}$.
-\item If $T$ is a parameterized type then let $V_i = U_i$ for $ i \in 1 .. m$.
+\item
+  If $e$ is of the form
+  \code{\NEW{} $T$.\id($a_1, \ldots,\ a_n,\ x_{n+1}$: $a_{n+1}, \ldots,\ x_{n+k}$: $a_{n+k}$)}
+  it is a compile-time error if \code{$R$.\id} is not the name of
+  a constructor declared by $R$, or \id{} is not accessible.
+\item
+  If $e$ is of the form
+  \code{\NEW{} $T$($a_1, \ldots,\ a_n,\ x_{n+1}$: $a_{n+1}, \ldots,\ x_{n+k}$: $a_{n+k}$)}
+  it is a compile-time error if $R$ is not the name of
+  a constructor declared by $R$.
 \end{itemize}
 
 \LMHash{}
-If $R$ is a generic with $l \ne m$ type parameters then for $ i \in 1 .. l$, let $V_i = \DYNAMIC{}$.
-In any other case, let $V_i = U_i$ for $ i \in 1 .. m$.
+Let $q$ be the above-mentioned constructor named \code{$R$.\id} or $R$.
+
+\LMHash{}
+It is a compile-time error if $R$ is abstract
+and $q$ is not a factory constructor.
+It is a compile-time error if $R$ is a non-generic class
+and $T$ is a parameterized type.
+%% We assume that inference has taken place, so actual type arguments
+%% are always given explicitly.
+It is a compile-time error if $R$ is a generic class
+and $T$ is not a parameterized type.
+It is a compile-time error if $R$ is a generic class,
+$T$ is a parameterized type, and $m \not= p$.
+\commentary{That is, the number of type arguments is incorrect.}
+It is a compile-time error if $R$ is a generic class,
+$T$ is a parameterized type,
+and $T$ is not regular-bounded
+(\ref{superBoundedTypes}).
+
+\LMHash{}
+If $q$ is a redirecting factory constructor,
+it is a compile-time error if $q$ in some number of
+redirecting factory redirections redirects to itself.
+\commentary{
+It is possible and allowed for a redirecting factory $q'$
+to enter an infinite loop, e.g.,
+because $q'$ redirects to a non-redirecting factory constructor
+$q''$ whose body uses $q'$ in an instance creation expression.
+Only loops that consist exclusively of redirecting factory redirections
+are detected at compile time.
+}
+
+\LMHash{}
+Let $S_i$ be the static type of
+the formal parameter of the constructor \code{$R$.\id} (respectively $R$)
+corresponding to the actual argument $a_i$, $i \in 1 .. n+k$.
+It is a compile-time error if the static type of
+$a_i, i \in 1 .. n + k$
+is not assignable to $[U_1/X_1, \ldots, U_m/X_m]S_i$.
+\commentary{
+The non-generic case is covered with $m = 0$.
+}
+
+\LMHash{}
+The static type of $e$ is $T$.
 
 \LMHash{}
 Evaluation of $e$ proceeds as follows:
 
 \LMHash{}
-First, the argument list
-\code{($a_1, \ldots,\ a_n,\ x_{n+1}$: $a_{n+1}, \ldots,\ x_{n+k}$: $a_{n+k}$)}
-is evaluated.
+First, the argument part
+
+\code{<$U_1, \ldots,\ U_m$>($a_1, \ldots,\ a_n,\ x_{n+1}$: $a_{n+1}, \ldots,\ x_{n+k}$: $a_{n+k}$)}
+
+\noindent
+is evaluated, yielding the evaluated actual argument part
+
+\code{<$u_1, \ldots,\ u_m$>($o_1, \ldots,\ o_n,\ x_{n+1}$: $o_{n+1},\ \ldots,\ x_{n+k}$: $o_{n+k}$)}.
+
+\noindent
+\commentary{Note that the non-generic case is covered by letting $m = 0$.}
+If for any
+$j \in 1 .. n + k$
+the run-time type of $o_j$ is not a subtype of
+$[u_1/X_1, \ldots, u_m/X_m]S_j$,
+a dynamic error occurs.
 
 \LMHash{}
+\Case{Non-loaded deferred constructors}
 If $T$ is a deferred type with prefix $p$, then if $p$ has not been successfully loaded, a dynamic error occurs.
 
 \LMHash{}
-Then, if $q$ is a non-factory constructor of an abstract class then an \code{AbstractClassInstantiationError} is thrown.
+\Case{Generative constructors}
+When $q$ is a generative constructor
+(\ref{generativeConstructors})
+evaluation proceeds to allocate a fresh instance
+(\ref{generativeConstructors}), $i$, of class $T$.
+% We provide the type arguments as part of the class of the instance
+% because $T$ includes the type arguments; but we also provide them
+% as a binding accessible to the constructor: Otherwise we couldn't
+% access the type parameters in the initializing expressions of the
+% initializer list where there is no access to \THIS{}.
+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 $u_1, \ldots, u_m$.
 
 \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 fewer than $n$ positional parameters or more than $n$ required parameters,
-or if $q$ lacks any of the named 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 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.
-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$.
-
 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:
+\Case{Redirecting factory constructors}
+When $q$ is a redirecting factory constructor
+(\ref{factories})
+of the form \code{\CONST{}? $T$($p_1, \ldots,\ p_{n+k}$) = $c$;} or
+of the form \code{\CONST{}? $T$.\id($p_1, \ldots,\ p_{n+k}$) = $c$;}
+where \code{\CONST{}?} indicates that \CONST{} may be present or absent,
+the remaining evaluation of $e$ is equivalent to
+evaluating
+\code{\NEW{} $c$($v_1, \ldots,\ v_n,\ x_{n+1}$: $v_{n+1}, \ldots,\ x_{n+k}$: $v_{n+k}$)}
+in an environment where
+$v_j$ is a fresh variable bound to $o_j$ for $j \in 1 .. n + k$, and
+$X_j$ is bound to $u_j$ for $j \in 1 .. m$.
+\commentary{
+We need access to the type variables because $c$ may contain them.
+}
 
 \LMHash{}
-If $q$ is a redirecting factory constructor of the form $T(p_1, \ldots,\ p_{n+k}) = c;$ or of the form \code{$T$.\id($p_1, \ldots,\ p_{n+k}$) = $c$;} then the result of the evaluation of $e$ is equivalent to evaluating the expression
-
-\code{[$V_1/X_1, \ldots, V_m/X_m$](\NEW{} $c$($a_1, \ldots,\ a_n, x_{n+1}: a_{n+1}, \ldots,\ x_{n+k}: a_{n+k}$))}
-
-\noindent
-where $X_1, \ldots,\ X_m$ are the formal type parameters of $R$.
-If evaluation of $q$ causes $q$ to be re-evaluated cyclically, with only factory constructor redirections in-between, a run-time 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 with the type parameters (if any) of $q$ bound to the actual type arguments $V_1, \ldots, V_l$.
+\Case{Non-redirecting factory constructors}
+When $q$ is a non-redirecting factory constructor,
+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 $u_1, \ldots, u_m$.
 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,
@@ -4869,144 +5131,182 @@
 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 compile-time error if $q$ is a constructor of an abstract class and $q$ is not a factory constructor.
-
-\commentary{
-The above gives precise meaning to the idea that instantiating an abstract class leads to an error.
-A similar clause applies to constant object creation in the next section.
-}
-
 \rationale{
-In particular, a factory constructor can be declared in an abstract class and used safely,
+A factory constructor can be declared in an abstract class and used safely,
 as it will either produce a valid instance or throw.
 }
 
-\LMHash{}
-The static type of an instance creation expression of either the form
-
-\code{\NEW{} $T$.\id($a_1, \ldots,\ a_n,\ x_{n+1}:\ a_{n+1}, \ldots,\ x_{n+k}:\ a_{n+k}$)}
-
-or the form
-
-\code{\NEW{} $T$($a_1, \ldots,\ a_n,\ x_{n+1}:\ a_{n+1}, \ldots,\ x_{n+k}:\ a_{n+k}$)}
-
-is $T$.
-It is a compile-time error if the static type of $a_i, 1 \le i \le n + k$ may not be assigned to the type of the corresponding formal parameter of the constructor \code{$T$.\id} (respectively $T$).
-
 
 \subsubsection{Const}
 \LMLabel{const}
 
 \LMHash{}
-A {\em constant object expression} invokes a constant constructor (\ref{constantConstructors}).
+A {\em constant object expression} invokes a constant constructor
+(\ref{constantConstructors}).
 
 \begin{grammar}
-{\bf constObjectExpression:}\CONST{} type ('{\escapegrammar .}' identifier)? arguments
+{\bf constObjectExpression:}\NEW{} type (`{\escapegrammar .}' identifier)? arguments
   .
 \end{grammar}
 
 \LMHash{}
 Let $e$ be a constant object expression of the form
 
-\code{\CONST{} $T$.\id($a_1, \ldots,\ a_n,\ x_{n+1}:\ a_{n+1}, \ldots,\ x_{n+k}:\ a_{n+k}$)}
-
+\code{\CONST{} $T$.\id($a_1, \ldots,\ a_n,\ x_{n+1}$: $a_{n+1}, \ldots,\ x_{n+k}$: $a_{n+k}$)}
 or the form
-\code{\CONST{} $T$($a_1, \ldots,\ a_n,\ x_{n+1}:\ a_{n+1}, \ldots,\ x_{n+k}:\ a_{n+k}$)}.
-It is a compile-time error if $T$ does not denote a class accessible in the current scope.
-It is a compile-time error if $T$ is a deferred type (\ref{staticTypes}).
 
+\code{\CONST{} $T$($a_1, \ldots,\ a_n,\ x_{n+1}$: $a_{n+1}, \ldots,\ x_{n+k}$: $a_{n+k}$)}.
+
+\LMHash{}
+It is a compile-time error if $T$ is not
+a class or a parameterized type accessible in the current scope,
+or if $T$ is a parameterized type which is not a class.
+It is a compile-time error if $T$ is a deferred type
+(\ref{staticTypes}).
 \commentary{
-In particular, $T$ may not be a type variable.
+For instance, $T$ can not be a type variable.
 }
 
 \LMHash{}
-If $T$ is a parameterized type, it is a compile-time error if $T$ includes a type variable among its type arguments.
+It is a compile-time error if $a_i$ is not a constant expression
+for some $i \in 1 .. n + k$.
 
 \LMHash{}
-If $e$ is of the form
-\code{\CONST{} $T$.\id($a_1, \ldots,\ a_n,\ x_{n+1}:\ a_{n+1}, \ldots,\ x_{n+k}:\ a_{n+k}$)}
-it is a compile-time error if \code{$T$.\id} is not the name of a constant constructor declared by the type $T$.
-If $e$ is of the form
-\code{\CONST{} $T$($a_1, \ldots,\ a_n,\ x_{n+1}$: $a_{n+1}, \ldots,\ x_{n+k}$: $a_{n+k}$)}
-it is a compile-time error if the type $T$ does not declare a constant constructor with the same name as the declaration of $T$.
+If $T$ is a parameterized type (\ref{parameterizedTypes})
+\code{$S$<$U_1, \ldots,\ U_m$>},
+let $R$ be the generic class $S$,
+and let
+\code{$X_1\ \EXTENDS\ B_1, \ldots,\ X_p\ \EXTENDS\ B_p$}
+be the formal type parameters of $S$.
+If $T$ is not a parameterized type, let $R$ be $T$.
 
 \LMHash{}
-In all of the above cases, it is a compile-time error if $a_i, i\in 1 .. n + k$, is not a compile-time constant expression.
+If $T$ is a parameterized type,
+it is a compile-time error if $U_j$ contains a type variable for any
+$j \in 1 .. m$.
 
-%If $T$ is a parameterized type (\ref{parameterizedTypes}) $S<U_1, \ldots,\ U_m>$, let $R = S$.  It is a compile-time error if $T$ is malformed. If $T$ is not a parameterized type, let $R = T$.
-%Finally,
-% If $T$ is a generic with $l$ retype parameters, then for all $ i \in 1 .. l$, let $V_i = \DYNAMIC{}$.
+\begin{itemize}
+\item
+  If $e$ is of the form
+  \code{\CONST{} $T$.\id($a_1, \ldots,\ a_n,\ x_{n+1}$: $a_{n+1}, \ldots,\ x_{n+k}$: $a_{n+k}$)}
+  it is a compile-time error if \code{$R$.\id} is not the name of
+  a constant constructor declared by $R$, or \id{} is not accessible.
+\item
+  If $e$ is of the form
+  \code{\CONST{} $T$($a_1, \ldots,\ a_n,\ x_{n+1}$: $a_{n+1}, \ldots,\ x_{n+k}$: $a_{n+k}$)}
+  it is a compile-time error if $R$ is not the name of
+  a constant constructor declared by $R$.
+\end{itemize}
+
+\LMHash{}
+Let $q$ be the above-mentioned constant constructor named \code{$R$.\id} or $R$.
+
+%% TODO(eernst): These errors are the same as with `new`. Can we avoid
+%% stating them twice? We'd need to refer to an awkwardly shaped portion
+%% of text in the previous subsection, or just loosely say "exactly the
+%% same errors"..
+\LMHash{}
+It is a compile-time error if $R$ is abstract
+and $q$ is not a factory constructor.
+It is a compile-time error if $R$ is a non-generic class
+and $T$ is a parameterized type.
+%% We assume that inference has taken place, so actual type arguments
+%% are always given explicitly.
+It is a compile-time error if $R$ is a generic class
+and $T$ is not a parameterized type.
+It is a compile-time error if $R$ is a generic class,
+$T$ is a parameterized type, and $m \not= p$.
+\commentary{That is, the number of type arguments is incorrect.}
+It is a compile-time error if $R$ is a generic class,
+$T$ is a parameterized type,
+and $T$ is not regular-bounded
+(\ref{superBoundedTypes}).
+
+\LMHash{}
+Let $S_i$ be the static type of
+the formal parameter of the constructor \code{$R$.\id} (respectively $R$)
+corresponding to the actual argument $a_i$, $i \in 1 .. n+k$.
+It is a compile-time error if the static type of
+$a_i, i \in 1 .. n + k$
+is not assignable to $[U_1/X_1, \ldots, U_m/X_m]S_i$.
+\commentary{
+The non-generic case is covered with $m = 0$.
+}
+
+\LMHash{}
+The static type of $e$ is $T$.
 
 \LMHash{}
 Evaluation of $e$ proceeds as follows:
 
 \LMHash{}
-First, if $e$ is of the form
-
-\code{\CONST{} $T$.\id($a_1, \ldots,\ a_n,\ x_{n+1}:\ a_{n+1}, \ldots,\ x_{n+k}:\ a_{n+k}$)}
-
-then let $i$ be the value of the expression
-
-\code{\NEW{} $T$.\id($a_1, \ldots,\ a_n,\ x_{n+1}:\ a_{n+1}, \ldots,\ x_{n+k}:\ a_{n+k}$)}.
+If $e$ is of the form
+\code{\CONST{} $T$.\id($a_1, \ldots,\ a_n,\ x_{n+1}$: $a_{n+1}, \ldots,\ x_{n+k}$: $a_{n+k}$)}
+let $i$ be the value of the expression $e'$:
+\code{\NEW{} $T$.\id($a_1, \ldots,\ a_n,\ x_{n+1}$: $a_{n+1}, \ldots,\ x_{n+k}$: $a_{n+k}$)}.
+\commentary{
+Let $o$ be the result of an evaluation of $e'$,
+at some point in time of some execution of the program
+in the library $L$ where $e$ occurs.
+The result of an evaluation of $e'$ in $L$
+at some other time and/or in some other execution will
+yield a result $o'$, such that $o'$ would be replaced by $o$
+by canonicalization as described below.
+This means that the value is well-defined.
+}
 
 \LMHash{}
-Otherwise, $e$ must be of the form
-
+If $e$ is of the form
 \code{\CONST{} $T$($a_1, \ldots,\ a_n,\ x_{n+1}$: $a_{n+1}, \ldots,\ x_{n+k}$: $a_{n+k}$)},
-
-in which case let $i$ be the result of evaluating
-
+let $i$ be the value of
 \code{\NEW{} $T$($a_1, \ldots,\ a_n,\ x_{n+1}$: $a_{n+1}, \ldots,\ x_{n+k}$: $a_{n+k}$)}.
+\commentary{
+Which is well-defined for the same reason.
+}
 
 \LMHash{}
-Then:
 \begin{itemize}
-\item If during execution of the program, a constant object expression has already evaluated to an instance $j$ of class $R$ with type arguments $V_i, 1 \le i \le m$, then:
+\item If during execution of the program,
+  a constant object expression has already evaluated to
+  an instance $j$ of class $R$ with type arguments $U_i, 1 \le i \le m$, then:
 \begin{itemize}
-\item For each instance variable $f$ of $i$, let $v_{if}$ be the value of the instance variable $f$ in $i$, and let $v_{jf}$ be the value of the instance variable $f$ in $j$.
-  If \code{identical($v_{if}$, $v_{jf}$)} for all instance variables $f$ in $i$ then the value of $e$ is $j$, otherwise the value of $e$ is $i$.
+\item For each instance variable $f$ of $i$,
+  let $v_{if}$ be the value of the instance variable $f$ in $i$, and
+  let $v_{jf}$ be the value of the instance variable $f$ in $j$.
+  If \code{identical($v_{if}$, $v_{jf}$)} for all instance variables $f$ in $i$
+  then the value of $e$ is $j$, otherwise the value of $e$ is $i$.
 \end{itemize}
 \item Otherwise the value of $e$ is $i$.
 \end{itemize}
 
 \commentary{
 In other words, constant objects are canonicalized.
-In order to determine if an object is actually new, one has to compute it; then it can be compared to any cached instances.
-If an equivalent object exists in the cache, we throw away the newly created object and use the cached one.
-Objects are equivalent if they have identical type arguments and identical instance variables.
-Since the constructor cannot induce any side effects, the execution of the constructor is unobservable.
+In order to determine if an object is actually new, one has to compute it;
+then it can be compared to any cached instances.
+If an equivalent object exists in the cache,
+we throw away the newly created object and use the cached one.
+Objects are equivalent if
+they have identical type arguments and identical instance variables.
+Since the constructor cannot induce any side effects,
+the execution of the constructor is unobservable.
 The constructor need only be executed once per call site, at compile time.
 }
 
 \LMHash{}
-The static type of a constant object expression of either the form
-
-\code{\CONST{} $T$.\id($a_1, \ldots,\ a_n,\ x_{n+1}:\ a_{n+1}, \ldots,\ x_{n+k}:\ a_{n+k}$)}
-
-or the form
-
-\code{\CONST{} $T$($a_1, \ldots,\ a_n,\ x_{n+1}:\ a_{n+1}, \ldots,\ x_{n+k}:\ a_{n+k}$)}
-
-is $T$.
-It is a compile-time error if the static type of $a_i, 1 \le i \le n+ k$ may not be assigned to the type of the corresponding formal parameter of the constructor \code{$T$.\id} (respectively $T$).
-
-\LMHash{}
-It is a compile-time error if evaluation of a constant object results in an uncaught exception being thrown.
+It is a compile-time error if evaluation of a constant object
+results in an uncaught exception being thrown.
 
 \commentary{
 To see how such situations might arise, consider the following examples:
 }
 
+%% TODO(eernst): Delete some \CONST{} when integrating implicit-creation.md
 \begin{dartCode}
 \CLASS{} A \{
    \FINAL{} x;
    \CONST{} A(p): x = p * 10;
 \}
 
-\CONST{} A("x"); // compile-time error
-\CONST{} A(5); // legal
-
 \CLASS{} IntPair \{
   \CONST{} IntPair(\THIS{}.x, \THIS{}.y);
   \FINAL{} int x;
@@ -5014,16 +5314,22 @@
   \OPERATOR *(v) => \NEW{} IntPair(x*v, y*v);
 \}
 
-\CONST{} A(\CONST{} IntPair(1,2)); // compile-time error: illegal in a subtler way
+\CONST a1 = \CONST{} A(true); // compile-time error
+\CONST a2 = \CONST{} A(5); // legal
+\CONST a3 = \CONST{} A(\CONST{} IntPair(1,2)); // compile-time error
 \end{dartCode}
 
 \commentary{
-Due to the rules governing constant constructors, evaluating the constructor \code{A()} with the argument \code{"x"} or the argument \code{\CONST{} IntPair(1, 2)} would cause it to throw an exception, resulting in a compile-time error.
+Due to the rules governing constant constructors,
+evaluating the constructor \code{A()}
+with the argument \code{"x"} or the argument \code{\CONST{} IntPair(1, 2)}
+would cause it to throw an exception, resulting in a compile-time error.
+In the latter case, the error is caused by the fact that
+\code{\OPERATOR{} *} can only be used with a few ``well-known'' types,
+which is required in order to avoid running arbitrary code during
+the evaluation of constant expressions.
 }
 
-\LMHash{}
-Given an instance creation expression of the form \CONST{} $q(a_1, \ldots,\ a_n)$ it is a compile-time error if $q$ is a constructor of an abstract class (\ref{abstractInstanceMembers}) but $q$ is not a factory constructor.
-
 
 \subsection{Spawning an Isolate}
 \LMLabel{spawningAnIsolate}
@@ -5277,7 +5583,8 @@
 and binding of the results to the function's formal parameters.
 
 \LMHash{}
-When parsing an argument list, an ambiguity may arise because the same source code could be one generic function invocation, and it could be two or more relational expressions and/or shift expressions.
+When parsing an argument list, an ambiguity may arise because the same source code could be one generic function invocation,
+and it could be two or more relational expressions and/or shift expressions.
 In this situation, the expression is always parsed as a generic function invocation.
 
 % Should we specify the precise disambiguation rule here?:
@@ -5316,35 +5623,75 @@
 \subsubsection{Binding Actuals to Formals}
 \LMLabel{bindingActualsToFormals}
 
-\LMHash{}
-Let $f$ be a function with $s$ type parameters and $h$ required parameters;
-let $p_1, \ldots, p_n$ be the positional parameters of $f$;
-and let $p_{h+1}, \ldots, p_{h+k}$ be the optional parameters declared by $f$.
-
 \commentary{
-Note that the type argument lists in the following are omitted in the case where $s = 0$,
+In the following, the non-generic case is covered implicitly:
+When the number of actual type arguments is zero
+the entire type argument list \code{<\ldots{}>} is omitted,
 and similarly for empty type parameter lists (\ref{generics}).
 }
 
 \LMHash{}
-An evaluated actual argument part
-\code{<$t_1, \ldots,\ t_r$>($o_1, \ldots,\ o_{m+l}$)}
-derived from an actual argument part of the form
+Consider an invocation $i$ of a function $f$ with an actual argument part of the form
+\code{<$A_1, \ldots,\ A_r$>($a_1, \ldots,\ a_m,\ q_1$: $a_{m+1}, \ldots,\ q_l$: $a_{m+l}$)}.
 
-\code{<$A_1, \ldots,\ A_r$>($a_1, \ldots,\ a_m,\ q_1$: $a_{m+1}, \ldots,\ q_l$: $a_{m+l}$)}
+\commentary{
+Note that $f$ denotes a function in a semantic sense,
+rather than a syntactic construct.
+A reference to this section is used in other sections
+when the static analysis of an invocation is specified,
+and the static type of $f$ has been determined.
+The function itself may have been obtained from a function declaration,
+from an instance bound to \THIS{} and an instance method declaration,
+or as a function object obtained by evaluation of an expression.
+Because of that, we cannot indicate here which syntactic construct
+corresponds to $f$.
+%
+A reference to this section is also used in other sections
+when actual arguments are to be bound to the corresponding formal parameters,
+and $f$ is about to be invoked, to specify the dynamic semantics.
+}
 
-\noindent
-is bound to the formal type parameters and formal parameters of $f$ as follows:
+\commentary{
+We do not call $f$ a `function object' here, because we do not wish to imply
+that every function invocation must involve a separate evaluation
+of an expression that yields a function object,
+followed by an invocation of that function object.
+For instance, an implementation should be allowed to compile the invocation
+of a top-level function as a series of steps whereby a stack frame is
+created, followed by a low-level jump to the generated code for the body.
+So, in this section,
+the word `function' is more low-level than `function object',
+but `function' still denotes a semantic entity
+which is associated with a function declaration,
+even though there may not be corresponding entity in the heap at run time.
+}
+
+\LMHash{}
+% We cannot pass the same named parameter twice.
+It is a compile-time error if $q_j = q_k$ for any $j \ne k$.
+
+\LMHash{}
+If the static type of $f$ is \DYNAMIC{} or the built-in class \FUNCTION{},
+no further static checks are performed and the static type of $i$ is \DYNAMIC{};
+otherwise, it is a compile-time error if the static type of $f$ is not a function type.
+
+\LMHash{}
+Otherwise, the static type of $f$ is a function type $F$.
+Let $S_0$ be the return type of $F$,
+let $X_1\ \EXTENDS\ B_1, \ldots, X_s\ \EXTENDS\ B_s$
+be the formal type parameters,
+let $h$ be the number of required parameters,
+let $p_1, \ldots, p_n$ be the positional parameters,
+and let $p_{h+1}, \ldots, p_{h+k}$ be the optional parameters of $F$.
+Let $S_i$ be the static type of the formal parameters $p_i, i \in 1 .. h+k$,
+and for each $q$ let $S_q$ be the type of the parameter named $q$,
+where each parameter type is obtained by replacing $X_j$ by $A_j, j \in 1 .. s$, in the given parameter type annotation.
+Finally, let $T_i$ be the static type of $a_i$.
 
 \commentary{
 We have an actual argument list consisting of $r$ type arguments, $m$ positional arguments, and $l$ named arguments.
 We have a function with $s$ type parameters, $h$ required parameters, and $k$ optional parameters.
-The number of type arguments must match the number of type parameters.
-The number of positional arguments must be at least as large as the number of required parameters, and no larger than the number of positional parameters.
-All named arguments must have a corresponding named parameter.
-A given named argument cannot be provided more than once.
-If an optional parameter has no corresponding argument, it gets its default value.
-In checked mode, all arguments must belong to subtypes of the type of their corresponding formal.
+Figure~\ref{fig:argumentsAndParameters} shows how this situation may arise.
 }
 
 % View on declaration:
@@ -5357,7 +5704,99 @@
 % Actual argument part:
 %
 %     |**   ...        *|**           ...          *|**     ...       *|
-%      <-r type par.s--> <----m positional arg.s---> <--l named arg.s->
+%      <-r type arg.s--> <----m positional arg.s---> <--l named arg.s->
+\begin{figure}[h]
+  \def\A#1{\mbox{\commentary{{#1} arguments}}}
+  \def\P#1{\mbox{\commentary{{#1} parameters}}}
+  %
+  \flushleft{\commentary{Actual arguments:}}
+  \begin{displaymath}
+    \begin{array}{rl}
+      \left<\A{$r$ type}\right>
+      \left(
+      \begin{array}{r@{,\;}l}
+        \A{$m$ positional}&\A{$l$ named}
+      \end{array}
+      \right)
+    \end{array}
+  \end{displaymath}
+  %
+  \flushleft{\commentary{Declaration with named parameters: $n = h$}}
+  \begin{displaymath}
+    \begin{array}{rl}
+      \left<\P{$s$ type}\right>
+      \left(
+      \begin{array}{r@{,\;}l}
+        \P{$h$ required}&\P{$k$ optional}\\
+        \multicolumn{2}{c}{\mbox{\scriptsize\textit{which may also be viewed as}}}\\
+        \P{$n$ positional}&\P{$k$ named}\\
+      \end{array}
+      \right)
+    \end{array}
+  \end{displaymath}
+  %
+  \flushleft{\commentary{Declaration with optional positional parameters: $n = h + k$}}
+  \begin{displaymath}
+    \begin{array}{rl}
+      \left<\P{$s$ type}\right>
+      \left(
+      \begin{array}{r@{,\;}l}
+        \P{$h$ required}&\P{$k$ optional}\\
+        \multicolumn{2}{c}{\mbox{\scriptsize\textit{which may also be viewed as}}}\\
+        \multicolumn{2}{c}{\P{$n$ positional}}
+      \end{array}
+      \right)
+    \end{array}
+  \end{displaymath}
+  %
+  \caption{Possible actual argument parts and formal parameter parts}
+  \label{fig:argumentsAndParameters}
+\end{figure}
+
+\LMHash{}
+% Type inference is assumed complete, so we must have the correct number of type arguments.
+It is a compile-time error if $r \not= s$.
+It is a compile-time error if $r = s$ and for some $j \in 1 .. s$,
+$A_j \not<: [A_1/X_1, \ldots, A_r/X_s]B_j$.
+It is a compile-time error unless $h \le m \le n$.
+If $l > 0$,
+it is a compile-time error unless $F$ has named parameters and
+$q_j \in \{p_{h+1}, \ldots, p_{h+k}\}, j \in 1 .. l$.
+
+\commentary{
+That is, the number of type arguments must match the number of type parameters,
+and the bounds must be respected.
+We must receive at least the required number of positional arguments,
+and not more than the total number of positional parameters.
+For each named argument there must be a named parameter with the same name.
+}
+
+\LMHash{}
+The static type of $i$ is $[A_1/X_1, \ldots, A_r/X_s]S_0$.
+
+\LMHash{}
+It is a compile-time error if $T_j$ may not be assigned to $S_j, j \in 1 .. m$.
+It is a compile-time error if $T_{m+j}$ may not be assigned to $S_{q_j}, j \in 1 .. l$.
+
+\LMHash{}
+For the dynamic semantics,
+let $f$ be a function with $s$ type parameters and $h$ required parameters;
+let $p_1, \ldots, p_n$ be the positional parameters of $f$;
+and let $p_{h+1}, \ldots, p_{h+k}$ be the optional parameters declared by $f$.
+
+\LMHash{}
+An evaluated actual argument part
+
+\code{<$t_1, \ldots,\ t_r$>($o_1, \ldots,\ o_m,\ q_1$: $o_{m+1},\ \ldots,\ q_l$: $o_{m+l}$)}
+
+\noindent
+derived from an actual argument part of the form
+
+\code{<$A_1, \ldots,\ A_r$>($a_1, \ldots,\ a_m,\ q_1$: $a_{m+1}, \ldots,\ q_l$: $a_{m+l}$)}
+
+\noindent
+is bound to the formal type parameters and formal parameters of $f$ as follows:
+
 \LMHash{}
 % Passing a wrong number of actual type arguments.
 If $r = 0$ and $s > 0$ then replace the actual type argument list:
@@ -5365,7 +5804,7 @@
 %% should be chosen based on the instantiate-to-bound algorithm, but we
 %% cannot yet refer to that because it hasn't yet been specified here.
 let $r$ be $s$ and $t_i = \DYNAMIC{}$ for $i \in 1 .. s$.
-If $r \not= s$, a \code{NoSuchMethodError} is thrown.
+Then, if $r \not= s$, a \code{NoSuchMethodError} is thrown.
 % Passing named arguments to a function with optional positional parameters.
 If $l > 0$ and $n \not= h$, a \code{NoSuchMethodError} is thrown.
 % Passing too few or too many positional arguments.
@@ -5394,32 +5833,6 @@
 % Check the types of named arguments.
 In checked mode, it is a dynamic type error if $o_{m+j}$ is not the null object and the actual type (\ref{actualTypeOfADeclaration}) of $q_j$ is not a supertype of the type of $o_{m+j}, j \in 1 .. l$.
 
-\LMHash{}
-% We cannot pass the same named parameter twice.
-It is a compile-time error if $q_i = q_j$ for any $i \ne j$.
-
-\LMHash{}
-Let $T_i$ be the static type of $a_i$.
-If the static type of $f$ is \DYNAMIC{} or the built-in class \FUNCTION{},
-no further static checks are performed.
-Otherwise, it is a compile-time error if the static type of $f$ is not a function type.
-
-\LMHash{}
-Otherwise, let $X_1, \ldots, X_s$ be the formal type parameters of the static type of $f$,
-let $S_i$ be the type of $p_i, i \in 1 .. h+k$,
-and let $S_q$ be the type of the named parameter $q$ of $f$,
-where each parameter type is obtained by replacing $X_j$ by $A_j, j \in 1 .. s$, in the given parameter type annotation.
-
-\commentary{
-Checks regarding the number of type parameters and their bounds is specified in (\ref{generics}).
-}
-
-\LMHash{}
-It is a compile-time error if $T_j$ may not be assigned to $S_j, j \in 1 .. m$.
-It is a compile-time error if $m < h$ or if $m > n$.
-Furthermore, each $q_i, i \in 1 .. l$, must have a corresponding named parameter in the set $\{p_{h+1}, \ldots, p_{h+k}\}$ or a compile-time error occurs.
-It is a compile-time error if $T_{m+j}$ may not be assigned to $S_{q_j}, j \in 1 .. l$.
-
 
 \subsubsection{Unqualified Invocation}
 \LMLabel{unqualifiedInvocation}
@@ -5437,36 +5850,45 @@
 }
 
 \LMHash{}
-If there exists a lexically visible declaration named \id, let $f_{id}$ be the innermost such declaration.
+It is a compile-time error if $i$ occurs inside a top-level or static function
+(be it function, method, getter, or setter)
+or a top-level or static variable initializer,
+and there is no lexically visible declaration named \id{} in scope.
+
+\LMHash{}
+If there exists a lexically visible declaration named \id,
+let $f_{id}$ be the innermost such declaration.
 Then:
 \begin{itemize}
+\item It is a compile-time error if $f_{id}$ denotes a type
+  (\commentary{that is, if \id{} is a type literal or type variable}),
+  unless \id{} denotes a constructor.
+\item It is a compile-time error if $f_{id}$ is an import directive
+  where \id{} is declared to be a library prefix.
 \item
-If \id{} is a type literal, then $i$ is interpreted as a function expression invocation (\ref{functionExpressionInvocation}) with $(\id)$ as the expression $e_f$.
-\commentary{
-The expression $(\id)$ where \id{} is a type literal always evaluates to an instance of class \code{Type} which is not a function.
-This ensures that a run-time error occurs when trying to call a type literal.
-}
+If $f_{id}$ is
+a local function,
+a library function,
+a library or static getter or a variable,
+$i$ is interpreted as a function expression invocation
+(\ref{functionExpressionInvocation}).
 \item
-If $f_{id}$ is a prefix object, a compile-time error occurs.
-\item
-If $f_{id}$ is a local function, a library function, a library or static getter or a variable then $i$ is interpreted as a function expression invocation (\ref{functionExpressionInvocation}).
-\item
-Otherwise, if $f_{id}$ is a static method of the enclosing class $C$, $i$ is equivalent to
-\code{$C$.\id<$A_1, \ldots,\ A_r$>($a_1, \ldots,\ a_n,\ x_{n+1}:\ a_{n+1}, \ldots,\ x_{n+k}:\ a_{n+k}$)}.
-\item Otherwise, $f_{id}$ is equivalent to the ordinary method invocation
+Otherwise, if $f_{id}$ is a static method of the enclosing class $C$,
+$i$ is equivalent to
+\code{$C$.\id<$A_1, \ldots,\ A_r$>($a_1, \ldots,\ a_n,\ x_{n+1}$: $a_{n+1}, \ldots,\ x_{n+k}$: $a_{n+k}$)}.
+\item Otherwise, if $i$ occurs in an instance method body,
+$i$ is equivalent to the ordinary method invocation
 
 \code{\THIS{}.\id<$A_1, \ldots,\ A_r$>($a_1, \ldots,\ a_n,\ x_{n+1}$: $a_{n+1}, \ldots,\ x_{n+k}$: $a_{n+k}$)}.
 \end{itemize}
 
-\LMHash{}
-Otherwise, if $i$ occurs inside a top level or static function (be it function, method, getter, or setter) or variable initializer, evaluation of $i$ causes a \code{NoSuchMethodError} to be thrown.
-
-\LMHash{}
-If $i$ does not occur inside a top level or static function, $i$ is equivalent to
-\code{\THIS{}.\id<$A_1, \ldots,\ A_r$>($a_1, \ldots,\ a_n,\ x_{n+1}$: $a_{n+1}, \ldots,\ x_{n+k}$: $a_{n+k}$)}.
-
-% Should also say:
-% It is a compile-time error if $i$ occurs inside a top level or static function (be it function, method, getter, or setter) or variable initializer and there is no lexically visible declaration named \id{} in scope.
+\commentary{
+Otherwise $i$ must occur inside a top-level or static function
+(be it function, method, getter, or setter)
+or a top-level or static variable initializer,
+in which case a compile-time error occurs
+(\ref{unqualifiedInvocation}).
+}
 
 
 \subsubsection{Function Expression Invocation}
@@ -5485,15 +5907,22 @@
 }
 
 \LMHash{}
-If $e_f$ is an identifier \id, then \id{} must necessarily denote a local function, a library function, a library or static getter or a variable as described above, or $i$ is not considered a function expression invocation.
-If $e_f$ is a type literal, then it is equivalent to the expression $(e_f)$.
+If $e_f$ is an identifier \id, then \id{} must necessarily denote
+a local function, a library function, a library or static getter or a variable as described above,
+or $i$ is not considered a function expression invocation.
+It is a compile-time error if $e_f$ is a type literal,
+unless $e_f$ denotes a constructor.
 
 \commentary{
-The expression $(e_f)$ where $e_f$ is a type literal always evaluates to an instance of class \code{Type} which is not a function.
-This ensures that a run-time error occurs when trying to call a type literal.
+This error was already specified elsewhere
+(\ref{unqualifiedInvocation})
+for the case where $e_f$ is an identifier,
+but $e_f$ may also have other forms, e.g., \code{p.C}.
 }
 
-If $e_f$ is a property extraction expression (\ref{propertyExtraction}), then $i$ isn't a function expression invocation and is instead recognized as an ordinary method invocation (\ref{ordinaryInvocation}).
+\LMHash{}
+If $e_f$ is a property extraction expression (\ref{propertyExtraction}),
+then $i$ isn't a function expression invocation and is instead recognized as an ordinary method invocation (\ref{ordinaryInvocation}).
 
 \commentary{
 \code{$a.b(x)$} is parsed as a method invocation of method \code{$b()$} on object \code{$a$}, not as an invocation of getter \code{$b$} on \code{$a$} followed by a function call \code{$(a.b)(x)$}.
@@ -5503,103 +5932,62 @@
 }
 
 \LMHash{}
-Otherwise, evaluation of a function expression invocation
+Let $F$ be the static type of $e_f$.
+The static analysis of $i$ is performed as specified in Section~\ref{bindingActualsToFormals},
+and the static type of $i$ is as specified there.
+
+\LMHash{}
+Evaluation of a function expression invocation
 
 \code{$e_f$<$A_1, \ldots,\ A_r$>($a_1, \ldots,\ a_n,\ x_{n+1}$: $a_{n+1}, \ldots,\ x_{n+k}$: $a_{n+k}$)}
 
 \noindent
 proceeds to evaluate $e_f$, yielding an object $o$.
 Let $f$ be a fresh variable bound to $o$.
-If $o$ is a function object then the following function invocation is evaluated
-and its result is the result of evaluating $i$:
+If $o$ is a function object then the function invocation
 
 \code{$f$<$A_1, \ldots,\ A_r$>($a_1, \ldots,\ a_n,\ x_{n+1}$: $a_{n+1}, \ldots,\ x_{n+k}$: $a_{n+k}$)}.
 
-\noindent
-Otherwise, if $o$ has a method named \CALL{},
-the following method invocation is evaluated and its result is the result of evaluating $i$:
+is evaluated by binding actuals to formals as specified in Section~\ref{bindingActualsToFormals},
+and executing the body of $f$ with those bindings;
+the returned result is then the result of evaluating $i$.
+
+\LMHash{}
+Otherwise $o$ is not a function object.
+If $o$ has a method named \CALL{}
+the following ordinary method invocation is evaluated,
+and its result is then the result of evaluating $i$:
 
 \code{$f$.call<$A_1, \ldots,\ A_r$>($a_1, \ldots,\ a_n,\ x_{n+1}$: $a_{n+1}, \ldots,\ x_{n+k}$: $a_{n+k}$)}.
 
-\noindent
-Otherwise, when $o$ has no method named \CALL{},
-a new instance $im$ of the predefined class \code{Invocation} is created, such that:
+\LMHash{}
+Otherwise $o$ has no method named \CALL{}.
+A new instance $im$ of the predefined class \code{Invocation} is created, such that:
 \begin{itemize}
-\item \code{im.isMethod} evaluates to \code{\TRUE{}}.
-\item \code{im.memberName} evaluates to the symbol \code{\#call}.
-\item \code{im.positionalArguments} evaluates to an unmodifiable list with the values
+\item \code{$im$.isMethod} evaluates to \code{\TRUE{}}.
+\item \code{$im$.memberName} evaluates to the symbol \code{\#call}.
+\item \code{$im$.positionalArguments} evaluates to an unmodifiable list with the values
 resulting from evaluation of
 \code{<Object>[$a_1, \ldots,\ a_n$]}.
-\item \code{im.namedArguments} evaluates to an unmodifiable map
+\item \code{$im$.namedArguments} evaluates to an unmodifiable map
 with the keys and values resulting from evaluation of
 
-\code{<Symbol, Object>\{$\#x_{n+1}$: $a_{n+1}, \ldots,\ x_{n+k}$: $\#a_{n+k}$\}}.
-\item \code{im.typeArguments} evaluates to an unmodifiable list
+\code{<Symbol, Object>\{$\#x_{n+1}$: $a_{n+1}, \ldots,\ \#x_{n+k}$: $a_{n+k}$\}}.
+\item \code{$im$.typeArguments} evaluates to an unmodifiable list
 with the values resulting from evaluation of
 \code{<Type>[$A_1, \ldots,\ A_r$]}.
 \end{itemize}
 
 \LMHash{}
 Then the method invocation \code{f.noSuchMethod($im$)} is evaluated,
-and its result is the result of evaluating $i$.
-
-\LMHash{}
-Let $F$ be the static type of $e_f$.
-It is a compile-time error unless one of the following conditions is satisfied:
-\begin{enumerate}
-\item $F$ is \DYNAMIC{}.
-\item $F$ is \FUNCTION{}.
-\item\label{InvocationTypeListNamed}
-$F$ is a function type
-
-\code{<$X_1\ \EXTENDS\ B_1, \ldots,\ A_s\ \EXTENDS\ B_s$>}
-
-\code{($T_1, \ldots,\ T_n,\ $\{$T_{n+1}\ x_{n+1}, \ldots,\ T_{n+k}\ x_{n+k}, \ldots,\ T_{n+k+p}\ x_{n+k+p}$\}) $ \rightarrow T_0$}
-
-\noindent
-where $r = s$, and the static type of $a_j$ is assignable to
-$[A_1/X_1, \ldots, A_r/X_s]T_j$, for all $j \in 1 .. n+k$.
-
-\item\label{InvocationTypeListPositional}
-$k$ is zero, $0 \leq m \leq n$, and $F$ is a function type
-
-\code{<$X_1\ \EXTENDS\ B_1, \ldots,\ A_s\ \EXTENDS\ B_s$>}
-
-\code{($T_1, \ldots,\ T_m,\ $[$T_{m+1}, \ldots,\ T_n, \ldots,\ T_{n+p}$]) $ \rightarrow T_0$}
-
-\noindent
-where $r = s$, and the static type of $a_j$ is assignable to
-$[A_1/X_1, \ldots, A_r/X_s]T_j$,
-for all $j \in 1 .. n$.
-
-\item\label{InvocationTypeListCall}
-$F$ is an interface type that has a method named \CALL{}, and then,
-considering $F$ to denote the function type of that method,
-criterion~\ref{InvocationTypeListNamed} or~\ref{InvocationTypeListPositional}
-in this list is satisfied.
-\end{enumerate}
+and its result is then the result of evaluating $i$.
 
 \commentary{
-This means that the types of the actual arguments must match the declared types of the corresponding parameters,
-where the formal type parameters have been replaced by the actual type arguments.
-%
-Note that the type parameter lists are omitted when $s = 0$ (\ref{generics}),
-and that checks on the number of type arguments and their bounds is specified elsewhere (\ref{generics}).
-%
-Criterion~\ref{InvocationTypeListCall} ensures that
-a function expression invocation may amount to an invocation of the instance method \CALL{}
-when such a method is statically known,
-and the run-time semantics ensures that
-a function invocation may amount to an invocation of the instance method \CALL{}
-also for an invocation of a function of type \DYNAMIC{} or \FUNCTION{},
-but that an interface type with a method named \CALL{} is not itself a subtype of any function type.
+The run-time semantics ensures that
+a function invocation may amount to an invocation of the instance method \CALL{}.
+However, an interface type with a method named \CALL{} is not itself a subtype of any function type.
 }
 
-\LMHash{}
-If $F$ is not a function type or $r \not= s$, the static type of $i$ is \DYNAMIC{}.
-Otherwise, the static type of $i$ is the return type
-$[A_1/X_1, \ldots, A_r/X_s]T_0$ of $F$.
-
 
 \subsection{Function Closurization}
 \LMLabel{functionClosurization}
@@ -5643,38 +6031,79 @@
 \subsection{Lookup}
 \LMLabel{lookup}
 
-
-\subsubsection{Method Lookup}
-\LMLabel{methodLookup}
-
 \LMHash{}
-The result of a lookup of a method $m$ in object $o$ with respect to library $L$ is the result of a lookup of method $m$ in class $C$ with respect to library $L$, where $C$ is the class of $o$.
+A {\em lookup} is a procedure which selects
+a concrete instance member declaration based on a traversal of
+a sequence of classes, starting with a given class $C$
+and proceeding with the superclass of the current class at each step.
+A lookup may be part of the static analysis, and it may be performed
+at run time. It may succeed or fail.
 
-\LMHash{}
-The result of a lookup of method $m$ in class $C$ with respect to library $L$ is:
-If $C$ declares a concrete instance method named $m$ that is accessible to $L$, then that method is the result of the lookup, and we say that the method was {\em looked up in $C$}.
-Otherwise, if $C$ has a superclass $S$, then the result of the lookup is the result of looking up $m$ in $S$ with respect to $L$.
-Otherwise, we say that the method lookup has failed.
-
-\rationale{
-The motivation for skipping abstract members during lookup is largely to allow smoother mixin composition.
+\commentary{
+We define several kinds of lookup with a very similar structure.
+We spell out each of them in spite of the redundancy,
+in order to avoid introducing meta-level abstraction mechanisms just for this purpose.
+The point is that we must indicate for each lookup which kind of member it is looking for,
+because, e.g., a `method lookup' and a `getter lookup' are used in different situations.
 }
 
+{ % Scope for 'lookup' definition.
 
-\subsubsection{Getter and Setter Lookup}
-\LMLabel{getterAndSetterLookup}
+\def\LookupDefinitionWithStart#1{
+\LMHash{}
+The result of a
+{\em {#1} lookup for $m$ in $o$ with respect to $L$ starting in class $C$}
+is the result of a {#1} lookup for $m$ in $C$ with respect to $L$.
+The result of a {\em {#1} lookup for $m$ in $C$ with respect to $L$} is:
+If $C$ declares a concrete instance {#1} named $m$
+that is accessible to $L$,
+then that {#1} declaration is the result of the {#1} lookup,
+and we say that the {#1} was {\em looked up in $C$}.
+Otherwise, if $C$ has a superclass $S$,
+the result of the {#1} lookup is
+the result of a {#1} lookup for $m$ in $S$ with respect to $L$.
+Otherwise, we say that the {#1} lookup has failed.
+
+}
 
 \LMHash{}
-The result of a lookup of a getter (respectively setter) $m$ in object $o$ with respect to library $L$ is the result of looking up getter (respectively setter) $m$ in class $C$ with respect to $L$, where $C$ is the class of $o$.
+Let $m$ be an identifier, $o$ an object, $L$ a library,
+and $C$ a class which is the class of $o$ or a superclass thereof.
+
+\LookupDefinitionWithStart{method}
+\LookupDefinitionWithStart{getter}
+\LookupDefinitionWithStart{setter}
+
+\def\LookupDefinition#1{%
+The result of a
+{\em {#1} lookup for $m$ in $o$ with respect to $L$}
+is the result of a
+{#1} lookup for $m$ in $o$ with respect to $L$
+starting with the class of $o$.
+}
 
 \LMHash{}
-The result of a lookup of a getter (respectively setter) $m$ in class $C$ with respect to library $L$ is:
-If $C$ declares a concrete instance getter (respectively setter) named $m$ that is accessible to $L$, then that getter (respectively setter) is the result of the lookup, and we say that the getter (respectively setter) was {\em looked up in $C$}.
-Otherwise, if $C$ has a superclass $S$, then the result of the lookup is the result of looking up getter (respectively setter) $m$ in $S$ with respect to $L$.
-Otherwise, we say that the lookup has failed.
+Let $m$ be an identifier, $o$ an object, and $L$ a library.
+\LookupDefinition{method}
+\LookupDefinition{getter}
+\LookupDefinition{setter}
+
+} % End of scope for lookup definitions.
+
+\commentary{
+Note that for getter (setter) lookup, the result may be
+a getter (setter) which has been induced by an instance variable
+declaration.
+}
+
+\commentary{
+Note that we sometimes use phrases like `looking up method $m$'
+to indicate that a method lookup is performed,
+and similarly for setter lookups and getter lookups.
+}
 
 \rationale{
-The motivation for skipping abstract members during lookup is largely to allow smoother mixin composition.
+The motivation for ignoring abstract members during lookup is largely to allow smoother mixin composition.
 }
 
 
@@ -5706,6 +6135,14 @@
 \subsubsection{Ordinary Invocation}
 \LMLabel{ordinaryInvocation}
 
+\LMHash{}
+An ordinary method invocation can be {\em conditional} or {\em unconditional}.
+
+\LMHash{}
+\Case{\code{$e$?.$m$<$\cdots$>($\cdots$)}}
+Consider a {\em conditional ordinary method invocation} $i$ of the form
+\code{$e$?.$m$<$A_1, \ldots,\ A_r$>($a_1, \ldots,\ a_n,\ x_{n+1}$: $a_{n+1}, \ldots,\ x_{n+k}$: $a_{n+k}$)}.
+
 \commentary{
 Note that non-generic invocations arise as the special case where the number of type arguments is zero,
 in which case the type argument list is omitted,
@@ -5713,30 +6150,6 @@
 }
 
 \LMHash{}
-An ordinary method invocation can be {\em conditional} or {\em unconditional}.
-
-\LMHash{}
-Evaluation of a {\em conditional ordinary method invocation} $i$ of the form
-
-\code{$e$?.$m$<$A_1, \ldots,\ A_r$>($a_1, \ldots,\ a_n,\ x_{n+1}$: $a_{n+1}, \ldots,\ x_{n+k}$: $a_{n+k}$)}
-
-\noindent
-proceeds as follows:
-
-\LMHash{}
-If $e$ is a type literal, $i$ is equivalent to
-
-\code{$e.m$<$A_1, \ldots,\ A_r$>($a_1, \ldots,\ a_n,\ x_{n+1}$: $a_{n+1}, \ldots,\ x_{n+k}$: $a_{n+k}$)}.
-
-\LMHash{}
-Otherwise, evaluate $e$ to an object $o$.
-If $o$ is the null object, $i$ evaluates to the null object (\ref{null}).
-Otherwise let $v$ be a fresh variable bound to $o$ and evaluate
-\code{$v$.$m$<$A_1, \ldots,\ A_r$>($a_1, \ldots,\ a_n,\ x_{n+1}$: $a_{n+1}, \ldots,\ x_{n+k}$: $a_{n+k}$)}
-to a value $r$.
-Then $e$ evaluates to $r$.
-
-\LMHash{}
 The static type of $i$ is the same as the static type of
 
 \code{$e$.$m$<$A_1, \ldots,\ A_r$>($a_1, \ldots,\ a_n,\ x_{n+1}$: $a_{n+1}, \ldots,\ x_{n+k}$: $a_{n+k}$)}.
@@ -5747,106 +6160,141 @@
 \code{$e$.$m$<$A_1, \ldots,\ A_r$>($a_1, \ldots,\ a_n,\ x_{n+1}$: $a_{n+1}, \ldots,\ x_{n+k}$: $a_{n+k}$)}
 
 \noindent
-are also generated in the case of
-
-\code{$e$?.$m$<$A_1, \ldots,\ A_r$>($a_1, \ldots,\ a_n,\ x_{n+1}$: $a_{n+1}, \ldots,\ x_{n+k}$: $a_{n+k}$)}.
+are also generated in the case of $i$.
 
 \LMHash{}
-An {\em unconditional ordinary method invocation} $i$ has the form
+Evaluation of $i$ proceeds as follows:
+
+\LMHash{}
+If $e$ is a type literal, $i$ is equivalent to
 
 \code{$e$.$m$<$A_1, \ldots,\ A_r$>($a_1, \ldots,\ a_n,\ x_{n+1}$: $a_{n+1}, \ldots,\ x_{n+k}$: $a_{n+k}$)}.
 
 \LMHash{}
+Otherwise, evaluate $e$ to an object $o$.
+If $o$ is the null object, $i$ evaluates to the null object (\ref{null}).
+Otherwise let $v$ be a fresh variable bound to $o$ and evaluate
+\code{$v$.$m$<$A_1, \ldots,\ A_r$>($a_1, \ldots,\ a_n,\ x_{n+1}$: $a_{n+1}, \ldots,\ x_{n+k}$: $a_{n+k}$)}
+to a value $r$.
+Then $e$ evaluates to $r$.
+
+\LMHash{}
+\Case{\code{$e$.$m$<$\cdots$>($\cdots$)}}
+An {\em unconditional ordinary method invocation} $i$ has the form
+\code{$e$.$m$<$A_1, \ldots,\ A_r$>($a_1, \ldots,\ a_n,\ x_{n+1}$: $a_{n+1}, \ldots,\ x_{n+k}$: $a_{n+k}$)}.
+
+\commentary{
+Non-generic invocations again arise as the special case
+where the number of type arguments is zero (\ref{generics}).
+}
+
+\LMHash{}
+Let $T$ be the static type of $e$.
+It is a compile-time error if $T$ does not have an accessible (\ref{privacy}) instance member named $m$, unless either:
+\begin{itemize}
+\item
+%% TODO(eernst): This is metaclass stuff, should be deleted.
+$T$ is \code{Type}, $e$ is a constant type literal,
+and the class corresponding to $e$ has a static getter named $m$.
+Or
+\item $T$ is \DYNAMIC{}.
+Or
+\item $T$ is \FUNCTION{} and $m$ is \CALL.
+\rationale{
+This means that for invocations of an instance method named \CALL,
+a receiver of type \FUNCTION{} is treated like a receiver of type \DYNAMIC{}.
+The expectation is that any concrete subclass of \FUNCTION{} will implement \CALL,
+but there is no method signature which can be assumed for \CALL{} in \FUNCTION{}
+because every signature will conflict with some potential overriding declarations.
+Note that any use of \CALL{} on a subclass of \FUNCTION{} that fails to implement \CALL{} will provoke a compile-time error,
+as this exemption is limited to type \FUNCTION{}, and does not apply to its subtypes.
+}
+\end{itemize}
+
+\LMHash{}
+If $T$ did not have an accessible member named $m$ the static type of $i$ is \DYNAMIC{},
+and no further static checks are performed on $i$
+(\commentary{except that subexpressions of $i$ are subject to their own static analysis}).
+
+\LMHash{}
+Otherwise \code{$T$.$m$} denotes an instance member.
+Let $L$ be the library that contains $i$.
+Let $d$ be the result of method lookup for $m$ in $T$ with respect to $L$,
+and if the method lookup succeeded then let $F$ be the static type of $d$.
+Otherwise, let $d$ be the result of getter lookup for $m$ in $T$ with respect to $L$
+and let $F$ be the return type of $d$.
+(\commentary{Since \code{$T$.$m$} exists we cannot have a failure in both lookups.})
+
+\LMHash{}
+The static analysis of $i$ is performed as specified in Section~\ref{bindingActualsToFormals},
+and the static type of $i$ is as specified there.
+
+\LMHash{}
+It is a compile-time error to invoke any of the methods of class \code{Object} on a prefix object (\ref{imports})
+or on a constant type literal that is immediately followed by the token `.'\,.
+
+\rationale{
+The reason for the latter is that this syntax is reserved for invocation of static methods.
+For instance, \code{int.toString()} is similar to \code{C.someStaticMethod()}, and
+it would be confusing if just a couple of expressions of this form were instance method invocations.
+If needed, \code{(int).toString()} may be used instead.
+}
+
+\LMHash{}
 Evaluation of an unconditional ordinary method invocation $i$ of the form
 \code{$e$.$m$<$A_1, \ldots,\ A_r$>($a_1, \ldots,\ a_n,\ x_{n+1}$: $a_{n+1}, \ldots,\ x_{n+k}$: $a_{n+k}$)}
 proceeds as follows:
 
 \LMHash{}
 First, the expression $e$ is evaluated to a value $o$.
-Next, the argument part
-\code{<$A_1, \ldots,\ A_r$>($a_1, \ldots,\ a_n,\ x_{n+1}$: $a_{n+1}, \ldots,\ x_{n+k}$: $a_{n+k}$)}
-is evaluated yielding actual type arguments
-$t_1, \ldots, t_r$
-and actual argument objects $o_1, \ldots, o_{n+k}$.
-Let $f$ be the result of looking up (\ref{methodLookup}) method $m$ in $o$ with respect to the current library $L$.
+Let $f$ be the result of looking up (\ref{lookup}) method $m$ in $o$ with respect to the current library $L$.
 
 \LMHash{}
-Let $X_1, \ldots, X_s$ be the formal type parameters of $f$,
-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$.
-
-\commentary{
-We have an actual argument list consisting of $r$ type arguments, $n$ positional arguments, and $k$ named arguments.
-We have a function with $s$ type parameters, $h$ required parameters, and $l$ optional parameters.
-The number of type arguments must match the number of type parameters.
-The number of positional arguments must be at least as large as the number of required parameters, and no larger than the number of positional parameters.
-All named arguments must have a corresponding named parameter.
-A given named argument cannot be provided more than once.
-}
-
-% View on declaration:
-%
-%     |**   ...        *|**        ...         *|**     ...          *|
-%      <-s type par.s--> <--h required par.s---> <--l optional par.s->
-%                        <--m pos, par.s, h=m--> <---l named par.s---> NAMED
-%                        <----------m positional par.s, m=h+l--------> POS
-%
-% Actual argument part:
-%
-%     |**   ...        *|**           ...          *|**     ...       *|
-%      <-r type par.s--> <----n positional arg.s---> <--k named arg.s->
-\LMHash{}
-% Passing a wrong number of actual type arguments.
-If $r = 0$ and $s > 0$ then replace the actual type argument list:
-%% TODO[instantiate-to-bound]: The actual type arguments passed here
-%% should be chosen based on the instantiate-to-bound algorithm, but we
-%% cannot yet refer to that because it hasn't yet been specified here.
-let $r$ be $s$ and $t_i = \DYNAMIC{}$ for $i \in 1 .. s$.
-If $r \not= s$, the method lookup has failed.
-% Passing named arguments to a function with optional positional parameters.
-If $k > 0$ and $m \not= h$, the method lookup has failed.
-% Passing too few or too many positional arguments.
-If $n < h$, or $n > m$, the method lookup has failed.
-% When k>0, h=m and there are l named parameters p_{h+1} .. p_{h+l}.
-Furthermore, each
-$x_i, i \in n+1 .. n+k$, must have a corresponding named parameter in the set
-$\{p_{h+1}, \ldots, p_{h+l}\}$,
-or the method lookup also fails.
-
-\LMHash{}
-If $o$ is an instance of \code{Type} but $e$ is not a constant type literal,
+%% TODO(eernst): This is metaclass stuff, should be deleted.
+If method lookup succeeded,
+but $o$ is an instance of \code{Type} and $e$ is not a constant type literal,
 then if $m$ is a method that forwards (\ref{functionDeclarations}) to a static method,
-method lookup fails.
-Otherwise method lookup has succeeded.
+method lookup is considered to have failed.
 
 \LMHash{}
 If the method lookup succeeded,
-the body of $f$ is executed with respect to the bindings that resulted from the evaluation of the argument list,
+the binding of actual arguments to formal parameters is performed as specified in Section~\ref{bindingActualsToFormals}.
+The body of $f$ is then executed with respect to the bindings that resulted from the evaluation of the argument list,
 and with \THIS{} bound to $o$.
-The value of $i$ is the value returned after $f$ is executed.
+The value of $i$ is the value returned by the execution of $f$'s body.
 
 \LMHash{}
-If the method lookup has failed,
-then let $g$ be the result of looking up getter (\ref{getterAndSetterLookup}) $m$ in $o$ with respect to $L$.
-If $o$ is an instance of \code{Type} but $e$ is not a constant type literal,
-then if $g$ is a getter that forwards to a static getter, getter lookup fails.
-If the getter lookup succeeded,
-let $v_g$ be the value of the getter invocation $e.m$.
-Now repeat from finding $f$ above, this time with $o$ being $v_g$ and $m$ being \code{call}.
+If the method lookup failed,
+then let $g$ be the result of looking up getter (\ref{lookup}) $m$ in $o$ with respect to $L$.
+%% TODO(eernst): This is metaclass stuff, should be deleted.
+If getter lookup succeeded,
+but $o$ is an instance of \code{Type} and $e$ is not a constant type literal,
+then if $g$ is a getter that forwards to a static getter,
+getter lookup is considered to have failed.
+
+\LMHash{}
+If the getter lookup succeeded then invoke the getter $o.m$
+and let $v_g$ be the returned value.
+Then the value of $i$ is the value of
+
+\code{$v_g$<$A_1, \ldots,\ A_r$>($a_1,\ \ldots,\ a_n,\ x_{n+1}$: $a_{n+1},\ \ldots,\ x_{n+k}$: $a_{n+k}$)}.
 
 \LMHash{}
 If getter lookup has also failed,
 then a new instance $im$ of the predefined class \code{Invocation} is created, such that:
 \begin{itemize}
-\item \code{im.isMethod} evaluates to \code{\TRUE{}}.
-\item \code{im.memberName} evaluates to the symbol \code{m}.
-\item \code{im.positionalArguments} evaluates to an unmodifiable list with the same values as
-\code{<Object>[$o_1, \ldots, o_n$]}.
-\item \code{im.namedArguments} evaluates to an unmodifiable map with the same keys and values as
-\code{<Symbol, Object>\{$\#x_{n+1}$: $o_{n+1}, \ldots, \#x_{n+k}$: $o_{n+k}$\}}.
-\item \code{im.typeArguments} evaluates to an unmodifiable list with the same values as
-\code{<Type>[$t_1, \ldots, t_r$]}.
+\item \code{$im$.isMethod} evaluates to \code{\TRUE{}}.
+\item \code{$im$.memberName} evaluates to the symbol \code{m}.
+\item \code{$im$.positionalArguments} evaluates to an unmodifiable list
+  with the values resulting from the evaluation of
+  \code{<Object>[$a_1, \ldots,\ a_n$]}.
+\item \code{$im$.namedArguments} evaluates to an unmodifiable map
+  with the keys and values resulting from the evaluation of
+
+  \code{<Symbol, Object>\{$\#x_{n+1}$: $a_{n+1}, \ldots,\ \#x_{n+k}$: $a_{n+k}$\}}.
+\item \code{$im$.typeArguments} evaluates to an unmodifiable list
+  with the values resulting from the evaluation of
+  \code{<Type>[$A_1, \ldots,\ A_r$]}.
 \end{itemize}
 
 \LMHash{}
@@ -5854,47 +6302,18 @@
 and the result of this invocation is the result of evaluating $i$.
 
 \commentary{
+Notice that the wording avoids re-evaluating the receiver $o$ and the arguments $a_i$.
+Also note that there is no need to specify how to handle an invocation of \code{noSuchMethod}
+that fails because ``there is no such method'':
 It is not possible to override the \code{noSuchMethod} of class \code{Object}
 in such a way that it cannot be invoked with one argument of type \code{Invocation}.
-% .. leaving `noSuchMethod(covariant Null n) => n;` as an exercise for the reader.
+It can fail with a dynamic type error if the parameter type is overridden with a
+proper subtype of \code{Invocation},
+but that does not give rise to yet another invocation of \code{noSuchMethod}.
+% We might want to mention `noSuchMethod(covariant Null n) => n;`, but
+% `covariant` is not yet specified, and it is not a big problem to omit it.
 }
 
-\commentary{
-Notice that the wording carefully avoids re-evaluating the receiver $o$ and the arguments $a_i$.
-}
-
-\LMHash{}
-Let $T$ be the static type of $e$.
-It is a compile-time error if $T$ does not have an accessible (\ref{privacy}) instance member named $m$, unless either:
-\begin{itemize}
-\item $T$ is \code{Type}, $e$ is a constant type literal,
-and the class corresponding to $e$ has a static getter named $m$.
-Or
-\item $T$ is \FUNCTION{} and $m$ is \CALL.
-\rationale{
-This means that for invocations of an instance method named \code{call},
-a receiver of type \FUNCTION{} is treated like a receiver of type \DYNAMIC{}.
-The expectation is that any concrete subclass of \FUNCTION{} will implement \CALL,
-but there is no method signature which can be assumed for \CALL{} in \FUNCTION{}
-because every signature will conflict with some potential overriding declarations.
-}
-\end{itemize}
-
-\LMHash{}
-If $T.m$ exists, it is a compile-time error if the type $F$ of $T.m$ may not be assigned to a function type.
-If $T.m$ does not exist, or if $F$ is not a function type, the static type of $i$ is \DYNAMIC{}.
-Otherwise, let $X_1, \ldots, X_s$ be the formal type parameters of the type of $F$,
-and $T_0$ its declared return type.
-If $r \not= s$ the static type of $i$ is \DYNAMIC{};
-otherwise, the static type of $i$ is $[A_1/X_1, \ldots, A_r/X_s]T_0$.
-
-\commentary{
-That is, the declared return type where each formal type parameter has been replaced by the corresponding actual type argument.
-}
-
-\LMHash{}
-It is a compile-time error to invoke any of the methods of class \code{Object} on a prefix object (\ref{imports}) or on a constant type literal that is immediately followed by the token `.'\,.
-
 
 \subsubsection{Cascaded Invocations}
 \LMLabel{cascadedInvocations}
@@ -5941,12 +6360,6 @@
 \subsubsection{Super Invocation}
 \LMLabel{superInvocation}
 
-\commentary{
-Note that non-generic invocations arise as the special case where the number of type arguments is zero,
-in which case the type argument list is omitted,
-and similarly for formal type parameter lists (\ref{generics}).
-}
-
 % Conditional super invocation is meaningless: \THIS{} is not null.
 
 \LMHash{}
@@ -5954,101 +6367,12 @@
 
 \code{\SUPER{}.$m$<$A_1, \ldots,\ A_r$>($a_1, \ldots,\ a_n,\ x_{n+1}$: $a_{n+1}, \ldots,\ x_{n+k}$: $a_{n+k}$)}.
 
-\LMHash{}
-Evaluation of $i$ proceeds as follows:
-
-\LMHash{}
-First, the argument part
-
-\code{<$A_1, \ldots,\ A_r$>($a_1, \ldots,\ a_n,\ x_{n+1}$: $a_{n+1}, \ldots,\ x_{n+k}$: $a_{n+k}$)}
-
-\noindent
-is evaluated producing actual type arguments $t_1, \ldots, t_r$ and 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$.
-
-\LMHash{}
-Let $X_1, \ldots, X_s$ be the formal type parameters of $f$.
-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$.
-
 \commentary{
-We have an actual argument list consisting of $r$ type arguments, $n$ positional arguments, and $k$ named arguments.
-We have a function with $s$ type parameters, $h$ required parameters, and $l$ optional parameters.
-The number of type arguments must match the number of type parameters.
-The number of positional arguments must be at least as large as the number of required parameters, and no larger than the number of positional parameters.
-All named arguments must have a corresponding named parameter.
-A given named argument cannot be provided more than once.
+Note that non-generic invocations arise as the special case where the number of type arguments is zero,
+in which case the type argument list is omitted,
+and similarly for formal type parameter lists (\ref{generics}).
 }
 
-% View on declaration:
-%
-%     |**   ...        *|**        ...         *|**     ...          *|
-%      <-s type par.s--> <--h required par.s---> <--l optional par.s->
-%                        <--m pos, par.s, h=m--> <---l named par.s---> NAMED
-%                        <----------m positional par.s, m=h+l--------> POS
-%
-% Actual argument part:
-%
-%     |**   ...        *|**           ...          *|**     ...       *|
-%      <-r type par.s--> <----n positional arg.s---> <--k named arg.s->
-\LMHash{}
-% Passing a wrong number of actual type arguments.
-If $r \not= s$, the method lookup has failed.
-% Passing named arguments to a function with optional positional parameters.
-If $k > 0$ and $m \not= h$, the method lookup has failed.
-% Passing too few or too many positional arguments.
-If $n < h$, or $n > m$, the method lookup has failed.
-% When k>0, h=m and there are l named parameters p_{h+1} .. p_{h+l}.
-Furthermore, each
-$x_i, i \in n+1 .. n+k$, must have a corresponding named parameter in the set
-$\{p_{h+1}, \ldots, p_{h+l}\}$,
-or the method lookup also fails.
-Otherwise, method lookup has succeeded.
-
-\LMHash{}
-If the method lookup succeeded,
-the body of $f$ is executed with respect to the bindings that resulted from the evaluation of the argument list,
-and with \THIS{} bound to the current value of \THIS{}.
-The value of $i$ is the value returned after $f$ is executed.
-
-\LMHash{}
-If the method lookup has failed,
-then let $g$ be the result of looking up getter (\ref{getterAndSetterLookup}) $m$ in $S_{dynamic}$ with respect to $L$.
-If the getter lookup succeeded,
-let $v_g$ be the value of the getter invocation $\SUPER{}.m$.
-Now repeat from finding $f$ above, this time with $o$ being $v_g$ and $m$ being \code{call}.
-
-\LMHash{}
-If getter lookup has also failed,
-then a new instance $im$ of the predefined class \code{Invocation} is created, such that:
-\begin{itemize}
-\item \code{im.isMethod} evaluates to \code{\TRUE{}}.
-\item \code{im.memberName} evaluates to the symbol \code{m}.
-\item \code{im.positionalArguments} evaluates to an unmodifiable list with the same values as
-$\code{<Object>}[o_1, \ldots, o_n]$.
-\item \code{im.namedArguments} evaluates to an unmodifiable map with the same keys and values as
-$\code{<Symbol, Object>}\{\#x_{n+1}: o_{n+1}, \ldots, \#x_{n+k}: o_{n+k}\}$.
-\item \code{im.typeArguments} evaluates to an unmodifiable list with the same values as
-$\code{<Type>}[t_1, \ldots, t_r]$.
-\end{itemize}
-
-\LMHash{}
-Then the method \code{noSuchMethod()} is looked up in $S_{dynamic}$ and invoked on \THIS{} with argument $im$,
-and the result of this invocation is the result of evaluating $i$.
-
-% TODO(eernst): We have removed the description of how to invoke noSuchMethod
-% in Object if the overriding noSuchMethod does not accept one argument of
-% type Invocation, because that will be a compile-time error soon. At this
-% point we just keep a commentary ready to say that:
-%
-%% \commentary {
-%% It is a compile-time error to override the \code{noSuchMethod} of class \code{Object} in such a way that it cannot be invoked with one positional argument of type \code{Invocation}.
-%% }
-
 \LMHash{}
 It is a compile-time error if a super method invocation occurs in a top-level function or variable initializer,
 in an instance variable initializer or initializer list,
@@ -6056,24 +6380,70 @@
 in a factory constructor,
 or in a static method or variable initializer.
 
-\LMHash{}
-Let $S_{static}$ be the superclass of the immediately enclosing class.
-It is a compile-time error if $S_{static}$ does not have an accessible (\ref{privacy}) instance member named $m$.
+{ % Scope for superclass name.
+
+\def\SuperClass{\ensuremath{S_{\mbox{\scriptsize{}super}}}}
 
 \LMHash{}
-If $S_{static}.m$ exists, it is a compile-time error if the type $F$ of $S_{static}.m$ may not be assigned to a function type.
-If $S_{static}.m$ does not exist, or if $F$ is not a function type, the static type of $i$ is \DYNAMIC{};
-Otherwise, let $X_1, \ldots, X_s$ be the formal type parameters of the type of $F$,
-and $T_0$ its declared return type.
-If $r \not= s$ the static type of $i$ is \DYNAMIC{};
-otherwise, the static type of $i$ is $[A_1/X_1, \ldots, A_r/X_s]T_0$.
+Let \SuperClass{} be the superclass (\ref{superclasses})
+of the immediately enclosing class for $i$,
+and let $L$ be the library that contains $i$.
+Let the declaration $d$ be
+the result of looking up the method $m$ in \SuperClass{}
+with respect to $L$ (\ref{lookup}),
+and let $F$ be the static type of $d$.
+Otherwise, if the method lookup failed,
+let the declaration $d$ be the result of looking up
+the getter $m$ with respect to $L$ in \SuperClass{}
+(\ref{lookup}),
+and let $F$ be the return type of $d$.
+If both lookups failed, a compile-time error occurs.
+
+\LMHash{}
+Otherwise (\commentary{when one of the lookups succeeded}),
+the static analysis of $i$ is performed as specified in Section~\ref{bindingActualsToFormals},
+considering the function to have static type $F$,
+and the static type of $i$ is as specified there.
 
 \commentary{
-That is, the declared return type where each formal type parameter has been replaced by the corresponding actual type argument.
+Note that member lookups ignore abstract declarations,
+which means that there will be a compile-time error if the targeted member $m$ is abstract,
+as well as when it does not exist at all.
 }
 
-% The following is not needed because it is specified in 'Binding Actuals to Formals"
-%Let $T_i$ be the static type of $a_i, i \in 1 .. n+k$. It is a compile-time error if $F$ is not a supertype of $(T_1, \ldots, t_n, \{T_{n+1}\ x_{n+1}, \ldots, T_{n+k}\ x_{n+k}\}) \to \bot$.
+\LMHash{}
+Evaluation of $i$ proceeds as follows:
+Let $o$ be the current binding of \THIS{},
+let $C$ be the enclosing class for $i$,
+and let \SuperClass{} be the superclass (\ref{superclasses}) of $C$.
+Let the declaration $d$ be the result of looking up
+the method $m$ with respect to $L$ in $o$ starting with \SuperClass{}
+(\ref{lookup}).
+If the lookup succeeded,
+let $f$ denote the function associated with $d$.
+%
+Otherwise (\commentary{when method lookup failed}),
+let the declaration $d$ be the result of looking up
+the getter $m$ with respect to $L$ in $o$ starting with \SuperClass{}
+(\ref{lookup}).
+If the getter lookup succeeded,
+invoke said getter with \THIS{} bound to $o$,
+and let $f$ denote the returned object.
+
+\commentary{
+If both lookups failed, the exact same lookups would have failed
+at compile-time, and the program then has a compile-time error.
+}
+
+\LMHash{}
+Otherwise perform the binding of actual arguments to formal parameters for
+\code{$f$<$A_1, \ldots,\ A_r$>($a_1, \ldots,\ a_n,\ x_{n+1}$: $a_{n+1}, \ldots,\ x_{n+k}$: $a_{n+k}$)}
+as specified in Section~\ref{bindingActualsToFormals},
+and execute the body of $f$ with said bindings
+plus a binding of \THIS{} to $o$.
+The result returned by $f$ is then the result of evaluating $i$.
+
+} % End of scope for superclass name.
 
 
 \subsubsection{Sending Messages}
@@ -6104,7 +6474,7 @@
 \end{enumerate}
 
 \commentary{
-Function objects derived via closurization are colloquially known as tear-offs.
+Function objects derived from members via closurization are colloquially known as tear-offs.
 }
 
 Property extraction can be either {\em conditional} or {\em unconditional}.
@@ -6139,7 +6509,8 @@
 
 \LMHash{}
 First, the expression $e$ is evaluated to an object $o$.
-Let $f$ be the result of looking up (\ref{methodLookup}) method (\ref{instanceMethods}) $m$ in $o$ with respect to the current library $L$.
+Let $f$ be the result of looking up (\ref{lookup}) method (\ref{instanceMethods}) $m$ in $o$ with respect to the current library $L$.
+%% TODO(eernst): This is metaclass stuff, should be deleted.
 If $o$ is an instance of \code{Type} but $e$ is not a constant type literal, then if $f$ is a method that forwards (\ref{functionDeclarations}) to a static method, method lookup fails.
 If method lookup succeeds then $i$ evaluates to the closurization of method $f$ on object $o$ (\ref{ordinaryMemberClosurization}).
 
@@ -6152,22 +6523,23 @@
 
 \LMHash{}
 Otherwise, $i$ is a getter invocation.
-Let $f$ be the result of looking up (\ref{getterAndSetterLookup}) getter (\ref{getters}) $m$ in $o$ with respect to $L$.
+Let $f$ be the result of looking up (\ref{lookup}) getter (\ref{getters}) $m$ in $o$ with respect to $L$.
+%% TODO(eernst): This is metaclass stuff, should be deleted.
 If $o$ is an instance of \code{Type} but $e$ is not a constant type literal, then if $f$ is a getter that forwards to a static getter, getter lookup fails.
 Otherwise, the body of $f$ is executed with \THIS{} bound to $o$.
 The value of $i$ is the result returned by the call to the getter function.
 
 \LMHash{}
-If the getter lookup has failed, then a new instance $im$ of the predefined class \code{Invocation} is created, such that :
+If the getter lookup has failed, then a new instance $im$ of the predefined class \code{Invocation} is created, such that:
 \begin{itemize}
-\item \code{im.isGetter} evaluates to \code{\TRUE{}}.
-\item \code{im.memberName} evaluates to the symbol \code{m}.
-\item \code{im.positionalArguments} evaluates to an empty, unmodifiable instance of
+\item \code{$im$.isGetter} evaluates to \code{\TRUE{}}.
+\item \code{$im$.memberName} evaluates to the symbol \code{m}.
+\item \code{$im$.positionalArguments} evaluates to an empty, unmodifiable instance of
 \code{List<Object>}.
-\item \code{im.namedArguments} evaluates to an empty, unmodifiable instance of
+\item \code{$im$.namedArguments} evaluates to an empty, unmodifiable instance of
 
 \code{Map<Symbol, Object>}.
-\item \code{im.typeArguments} evaluates to an empty, unmodifiable instance of
+\item \code{$im$.typeArguments} evaluates to an empty, unmodifiable instance of
 
 \code{List<Type>}.
 \end{itemize}
@@ -6195,6 +6567,7 @@
 \LMHash{}
 Let $T$ be the static type of $e$.
 It is a compile-time error if $T$ does not have a method or getter named $m$,
+%% TODO(eernst): This is metaclass stuff, should be deleted.
 unless $T$ is \code{Type},
 $e$ is a constant type literal,
 and the class corresponding to $e$ has a static method or getter named $m$.
@@ -6202,10 +6575,18 @@
 \LMHash{}
 The static type of $i$ is:
 \begin{itemize}
-\item The declared return type of $T.m$, if $T$ has an accessible instance getter named $m$.
-\item The declared return type of $m$, if $T$ is \code{Type}, $e$ is a constant type literal and the class corresponding to $e$ declares an accessible static getter named $m$.
-\item The static type of function $T.m$ if $T$ has an accessible instance method named $m$.
-\item The static type of function $m$, if $T$ is \code{Type}, $e$ is a constant type literal and the class corresponding to $e$ declares an accessible static method named $m$.
+\item The declared return type of \code{$T$.$m$}, if $T$ has an accessible instance getter named $m$.
+\item
+%% TODO(eernst): This is metaclass stuff, should be deleted.
+The declared return type of $m$, if $T$ is \code{Type},
+$e$ is a constant type literal
+and the class corresponding to $e$ declares an accessible static getter named $m$.
+\item The static type of function \code{$T$.$m$} if $T$ has an accessible instance method named $m$.
+\item
+%% TODO(eernst): This is metaclass stuff, should be deleted.
+The static type of function $m$, if $T$ is \code{Type},
+$e$ is a constant type literal
+and the class corresponding to $e$ declares an accessible static method named $m$.
 \item The type \DYNAMIC{} otherwise.
 \end{itemize}
 
@@ -6231,14 +6612,14 @@
 \LMHash{}
 If the getter lookup has failed, then a new instance $im$ of the predefined class \code{Invocation} is created, such that:
 \begin{itemize}
-\item \code{im.isGetter} evaluates to \code{\TRUE{}}.
-\item \code{im.memberName} evaluates to the symbol \code{m}.
-\item \code{im.positionalArguments} evaluates to an empty, unmodifiable instance of
+\item \code{$im$.isGetter} evaluates to \code{\TRUE{}}.
+\item \code{$im$.memberName} evaluates to the symbol \code{m}.
+\item \code{$im$.positionalArguments} evaluates to an empty, unmodifiable instance of
 \code{List<Object>}.
-\item \code{im.namedArguments} evaluates to an empty, unmodifiable instance of
+\item \code{$im$.namedArguments} evaluates to an empty, unmodifiable instance of
 
 \code{Map<Symbol, Object>}.
-\item \code{im.typeArguments} evaluates to an empty, unmodifiable instance of
+\item \code{$im$.typeArguments} evaluates to an empty, unmodifiable instance of
 
 \code{List<Type>}.
 \end{itemize}
@@ -6287,8 +6668,8 @@
 \begin{itemize}
 %\item $(a) \{\RETURN{}$ $u$ $op$ $a;$\} if $f$ is named $op$ and $op$ is one of \code{<, >, <=, >=, ==, -, +, /, \~{}/, *, \%, $|$, \^{}, \&, $<<$, $>>$} (this precludes closurization of unary -).
 %\item $() \{\RETURN{}$ \~{} $u;$\} if $f$ is named \~{}.
-%\item $(a) \{\RETURN{}$ $u[a];$\} if $f$ is named $[]$.
-%\item $(a, b) \{\RETURN{}$ $u[a] = b;$\} if $f$ is named $[]=$.
+%\item $(a) \{\RETURN{}$ $u[a];$\} if $f$ is named \code{[]}.
+%\item $(a, b) \{\RETURN{}$ $u[a] = b;$\} if $f$ is named \code{[]=}.
 \item
 \begin{dartCode}
 <$X_1\ \EXTENDS\ B'_1, \ldots,\ X_s\ \EXTENDS\ B'_s$>
@@ -6367,7 +6748,10 @@
 obtained by closurization of $m$ on $o_1$ respectively $o_2$.
 Then \code{$c_1$ == $c_2$} evaluates to true if and only if $o_1$ and $o_2$ is the same object.
 
-%\item The static type of the property extraction is the static type of function $T.m$, where $T$ is the static type of $e$, if $T.m$ is defined. Otherwise the static type of $e.m$ is \DYNAMIC{}.
+%% TODO(eernst): This being a comment, it's presumably spelled out somewhere
+%% else. Find it and check that it does actually say that it is an error
+%% except when the type of $e$ is \DYNAMIC{}.
+%\item The static type of the property extraction is the static type of function \code{$T$.$m$}, where $T$ is the static type of $e$, if \code{$T$.$m$} is defined. Otherwise the static type of $e.m$ is \DYNAMIC{}.
 
 \commentary{
 % Spell out the consequences for `==` and for `identical`, for the receivers
@@ -6401,7 +6785,7 @@
 and there is no class $U$ which is a subclass of $S$ and a superclass of $T$ which implements $f$.
 
 \commentary{
-In short, consider a situation where a superinvocation of $f$ will execute $f$ as declared in $S$.
+In short, consider a situation where a super invocation of $f$ will execute $f$ as declared in $S$.
 }
 
 \LMHash{}
@@ -6415,8 +6799,8 @@
 \begin{itemize}
 %\item $(a) \{\RETURN{}$ \SUPER{} $op$ $a;$\} if $f$ is named $op$ and $op$ is one of \code{<, >, <=, >=, ==, -, +, /, \~{}/, *, \%, $|$, \^{}, \&, $<<$, $>>$}.
 %\item $() \{\RETURN{}$ \~{}\SUPER;\} if $f$ is named \~{}.
-%\item $(a) \{\RETURN{}$ $\SUPER[a];$\} if $f$ is named $[]$.
-%\item $(a, b) \{\RETURN{}$ $\SUPER[a] = b;$\} if $f$ is named $[]=$.
+%\item $(a) \{\RETURN{}$ $\SUPER[a];$\} if $f$ is named \code{[]}.
+%\item $(a, b) \{\RETURN{}$ $\SUPER[a] = b;$\} if $f$ is named \code{[]=}.
 \item
 \begin{dartCode}
 <$X_1\ \EXTENDS\ B'_1, \ldots,\ X_s\ \EXTENDS\ B'_s$>
@@ -6509,56 +6893,80 @@
 \end{grammar}
 
 \LMHash{}
-Evaluation of an assignment $a$ of the form $v$ \code{=} $e$ proceeds as follows:
-
-%If there is neither a local variable declaration with name $v$ nor a setter declaration with name $v=$ in the lexical scope enclosing $a$, then:
-%\begin{itemize}
-% \item If $a$ occurs inside a top level or static function (be it function, method, getter, or setter) or variable initializer, evaluation of $a$ causes $e$ to be evaluated, after which a \code{NoSuchMethodError} is thrown.
-% \item Otherwise, the assignment is equivalent to the assignment \code{\THIS{}.$v$ = $e$}.
-% \end{itemize}
-
-%Otherwise
+\Case{\code{$v$ = $e$}}
+Consider an assignment $a$ of the form \code{$v$ = $e$},
+where $v$ is an identifier or an identifier qualified by an import prefix,
+and $v$ denotes a variable (\ref{variables}) or \code{$v$=} denotes a setter
+(\commentary{which may be declared explicitly or induced by an instance variable, etc}).
+Let $T$ be the static type of $v$ when $v$ denotes a variable,
+otherwise let $T$ be the static type of the formal parameter of the setter \code{$v$=}.
+It is a compile-time error if the static type of $e$ may not be assigned to $T$.
+The static type of $a$ is the static type of $e$.
 
 \LMHash{}
-Let $d$ be the innermost declaration whose name is $v$ or $v=$, if it exists.
-It is a compile-time error if $d$ denotes a prefix object.
+It is a compile-time error if an assignment of the form \code{$v$ = $e$} occurs
+inside a top level or static function (be it function, method, getter, or setter) or variable initializer,
+and there is neither a mutable local variable declaration with name $v$
+nor a setter declaration with name \code{$v$=} in the lexical scope enclosing the assignment.
+
+\LMHash{}
+Evaluation of an assignment $a$ of the form \code{$v$ = $e$}
+proceeds as follows:
+%% TODO(eernst): $d$ is defined ambiguously: both getter & setter may exist.
+Let $d$ be the innermost declaration whose name is $v$ or \code{$v$=}, if it exists.
+It is a compile-time error if $d$ denotes
+a prefix object, type declaration, or function declaration.
 
 \LMHash{}
 If $d$ is the declaration of a local variable, the expression $e$ is evaluated to an object $o$.
-Then, the variable $v$ is bound to $o$ unless $v$ is \FINAL{} or \CONST{}, in which case a dynamic error occurs.
+Then, the variable $v$ is bound to $o$.
 If no error occurs, the value of the assignment expression is $o$.
 
+\commentary{
+If $v$ is a final variable, a compile-time error has occurred,
+but a type check may cause a dynamic error.
+}
+
 % add local functions per bug 23218
 
 \LMHash{}
+% TODO(eernst): $d$ defined ambiguously, re-check next sentence when fixing.
 If $d$ is the declaration of a library variable, top level getter or top level setter, the expression $e$ is evaluated to an object $o$.
-Then the setter $v=$ is invoked with its formal parameter bound to $o$.
+% TODO(eernst): $d$ defined ambiguously, re-check when fixing: Case $d$ is the getter and there is no setter.
+Then the setter \code{$v$=} is invoked with its formal parameter bound to $o$.
 The value of the assignment expression is $o$.
 
 \LMHash{}
-Otherwise, if $d$ is the declaration of a static variable, static getter or static setter in class $C$, then the assignment is equivalent to the assignment \code{$C.v$ = $e$}.
+Otherwise, if $d$ is the declaration of a class variable, static getter or static setter in class $C$,
+then the assignment is equivalent to the assignment \code{$C$.$v$ = $e$}.
+
+\commentary{
+Otherwise, if $a$ occurs inside a top level or static function
+(be it function, method, getter, or setter) or variable initializer,
+a compile-time error has occurred.
+}
 
 \LMHash{}
-Otherwise, If $a$ occurs inside a top level or static function (be it function, method, getter, or setter) or variable initializer, evaluation of $a$ causes $e$ to be evaluated, after which a \code{NoSuchMethodError} is thrown.
-
-\LMHash{}
+%% TODO(eernst): We don't want to transform code and than complain, see if this
+%% can be reworded to rely on static checks such that it only happens when it
+%% works, or maybe that's already true.
 Otherwise, the assignment is equivalent to the assignment \code{\THIS{}.$v$ = $e$}.
 
 \LMHash{}
-In checked mode, it is a dynamic type error if $o$ is not the null object (\ref{null}) and the interface of the class of $o$ is not a subtype of the actual type (\ref{actualTypeOfADeclaration}) of $v$.
+In checked mode, it is a dynamic type error if $o$ is not the null object (\ref{null})
+and the interface of the class of $o$ is not a subtype of the actual type (\ref{actualTypeOfADeclaration}) of $v$.
 
 \LMHash{}
-It is a compile-time error if the static type of $e$ may not be assigned to the static type of $v$.
-The static type of the expression $v$ \code{=} $e$ is the static type of $e$.
+\Case{\code{$e_1$?.$v$ = $e_2$}}
+Consider an assignment $a$ of the form \code{$e_1$?.$v$ = $e_2$}.
+Let $S$ be the static type of the formal parameter of the setter \code{$v$=}.
+It is a compile-time error if the static type of $e_2$ may not be assigned to $S$.
+The static type of $a$ is the static type of $e_2$.
 
 \LMHash{}
 Evaluation of an assignment $a$ of the form \code{$e_1$?.$v$ = $e_2$}
 proceeds as follows:
-
-\LMHash
 If $e_1$ is a type literal, $a$ is equivalent to \code{$e_1$.$v$ = $e_2$}.
-
-\LMHash{}
 Otherwise evaluate $e_1$ to an object $o$.
 If $o$ is the null object, $a$ evaluates to the null object (\ref{null}).
 Otherwise let $x$ be a fresh variable bound to $o$
@@ -6566,35 +6974,37 @@
 Then $a$ evaluates to $r$.
 
 \LMHash{}
+\Case{\code{$e_1$.$v$ = $e_2$}}
+Consider an assignment $a$ of the form \code{$e_1$.$v$ = $e_2$}.
+Let $S$ be the static type of the formal parameter of the setter \code{$v$=}.
+It is a compile-time error if the static type of $e_2$ may not be assigned to $S$.
 The static type of $a$ is the static type of $e_2$.
-Let $T$ be the static type of $e_1$ and let $y$ be a fresh variable of type $T$.
-Exactly the same compile-time errors that would be caused by \code{$y$.$v$ = $e_2$} are also generated in the case of \code{$e_1$?.$v$ = $e_2$}.
 
 \LMHash{}
-Evaluation of an assignment of the form \code{$e_1$.$v$ = $e_2$} proceeds as follows:
-
-\LMHash{}
+Evaluation of an assignment of the form \code{$e_1$.$v$ = $e_2$}
+proceeds as follows:
 The expression $e_1$ is evaluated to an object $o_1$.
 Then, the expression $e_2$ is evaluated to an object $o_2$.
-Then, the setter $v=$ is looked up (\ref{getterAndSetterLookup}) in $o_1$ with respect to the current library.
+Then, the setter \code{$v$=} is looked up (\ref{lookup}) in $o_1$ with respect to the current library.
+%% TODO(eernst): This is metaclass stuff, should be deleted.
 If $o_1$ is an instance of \code{Type} but $e_1$ is not a constant type literal,
-then if $v=$ is a setter that forwards (\ref{functionDeclarations}) to a static setter, setter lookup fails.
-Otherwise, the body of $v=$ is executed with its formal parameter bound to $o_2$ and \THIS{} bound to $o_1$.
+then if \code{$v$=} is a setter that forwards (\ref{functionDeclarations}) to a static setter, setter lookup fails.
+Otherwise, the body of \code{$v$=} is executed with its formal parameter bound to $o_2$ and \THIS{} bound to $o_1$.
 
 \LMHash{}
 If the setter lookup has failed, then a new instance $im$ of the predefined class \code{Invocation} is created, such that:
 \begin{itemize}
-\item \code{im.isSetter} evaluates to \code{\TRUE{}}.
-\item \code{im.memberName} evaluates to the symbol \code{v=}.
-\item \code{im.positionalArguments} evaluates to an unmodifiable list with the same values as
+\item \code{$im$.isSetter} evaluates to \code{\TRUE{}}.
+\item \code{$im$.memberName} evaluates to the symbol \code{v=}.
+\item \code{$im$.positionalArguments} evaluates to an unmodifiable list with the same values as
 $\code{<Object>}[o_2]$.
-\item \code{im.namedArguments} evaluates to an empty, unmodifiable instance of
+\item \code{$im$.namedArguments} evaluates to an empty, unmodifiable instance of
 
 \code{Map<Symbol, Object>}.
-\item \code{im.typeArguments} evaluates to an empty, unmodifiable instance of
+\item \code{$im$.typeArguments} evaluates to an empty, unmodifiable instance of
 
 \code{List<Type>}.
-m\end{itemize}
+\end{itemize}
 
 \LMHash{}
 Then the method \code{noSuchMethod()} is looked up in $o_1$ and invoked with argument $im$.
@@ -6616,30 +7026,40 @@
 
 \LMHash{}
 Let $T$ be the static type of $e_1$.
-It is a compile-time error if $T$ does not have an accessible instance setter named $v=$ unless $T$ is \code{Type}, $e_1$ is a constant type literal and the class corresponding to $e_1$ has a static setter named $v=$.
+It is a compile-time error if $T$ does not have an accessible instance setter named \code{$v$=}
+%% TODO(eernst): This is metaclass stuff, should be deleted.
+unless $T$ is \code{Type}, $e_1$ is a constant type literal and the class corresponding to $e_1$ has a static setter named \code{$v$=}.
 
 \LMHash{}
-It is a compile-time error if the static type of $e_2$ may not be assigned to the static type of the formal parameter of the setter $v=$.
-The static type of the expression $e_1.v$ \code{=} $e_2$ is the static type of $e_2$.
+\Case{\code{\SUPER.$v$ = $e$}}
+Consider an assignment $a$ of the form \code{\SUPER.$v$ = $e$}.
+Let $S_{static}$ be the superclass of the immediately enclosing class.
+It is a compile-time error if $S_{static}$ does not have an accessible instance setter named \code{$v$=}.
+Otherwise, it is a compile-time error if the static type of $e$ may not be assigned to the static type of the formal parameter of the setter \code{$v$=}.
+The static type of $a$ is the static type of $e$.
 
 \LMHash{}
-Evaluation of an assignment of the form $\SUPER.v$ \code{=} $e$ proceeds as follows:
-
-\LMHash{}
-Let $g$ be the method currently executing, and let $C$ be the class in which $g$ was looked up.
+Evaluation of an assignment of the form \code{\SUPER.$v$ = $e$}
+proceeds as follows:
+Let $g$ be the currently executing method, and let $C$ be the class in which $g$ was looked up.
 Let $S_{dynamic}$ be the superclass of $C$.
 The expression $e$ is evaluated to an object $o$.
-Then, the setter $v=$ is looked up (\ref{getterAndSetterLookup}) in $S_{dynamic}$ with respect to the current library.
-The body of $v=$ is executed with its formal parameter bound to $o$ and \THIS{} bound to \THIS{}.
+Then, the setter \code{$v$=} is looked up (\ref{lookup}) in $S_{dynamic}$ with respect to the current library.
+The body of \code{$v$=} is executed with its formal parameter bound to $o$
+and \THIS{} bound to the current value of \THIS{}.
 
 \LMHash{}
 If the setter lookup has failed, then a new instance $im$ of the predefined class \code{Invocation} is created, such that:
 \begin{itemize}
-\item \code{im.isSetter} evaluates to \code{\TRUE{}}.
-\item \code{im.memberName} evaluates to the symbol \code{v=}.
-\item \code{im.positionalArguments} evaluates to an unmodifiable list with the same values as \code{[$o$]}.
-\item \code{im.namedArguments} evaluates to an empty unmodifiable instance of \code{Map<Symbol, Object>}.
-\item \code{im.typeArguments} evaluates to an empty, unmodifiable instance of
+\item \code{$im$.isSetter} evaluates to \code{\TRUE{}}.
+\item \code{$im$.memberName} evaluates to the symbol \code{v=}.
+\item \code{$im$.positionalArguments} evaluates to an unmodifiable list
+with the same values as \code{<Object>[$o$]}.
+\item \code{$im$.namedArguments} evaluates to an empty unmodifiable instance of
+
+\code{Map<Symbol, Object>}.
+\item \code{$im$.typeArguments} evaluates to an empty, unmodifiable instance of
+
 \code{List<Type>}.
 \end{itemize}
 
@@ -6650,73 +7070,93 @@
 The value of the assignment expression is $o$ irrespective of whether setter lookup has failed or succeeded.
 
 \LMHash{}
-In checked mode, it is a dynamic type error if $o$ is not the null object (\ref{null}) and the interface of the class of $o$ is not a subtype of the actual type of $S.v$.
+In checked mode, it is a dynamic type error if $o$ is not the null object (\ref{null})
+and the interface of the class of $o$ is not a subtype of the actual type of $S.v$.
 
 \LMHash{}
-Let $S_{static}$ be the superclass of the immediately enclosing class.
-It is a compile-time error if $S_{static}$ does not have an accessible instance setter named $v=$ unless $S_{static}$.
+\Case{\code{$e_1$[$e_2$] = $e_3$}}
+Consider an assignment $a$ of the form \code{$e_1$[$e_2$] = $e_3$}.
+It is a compile-time error if the static type of $e_1$ does not have a method named \code{[]=}.
+Otherwise, let $S_2$ be the static type of the first formal parameter of the method \code{[]=}
+and $S_3$ the static type of the second.
+It is a compile-time error if the static type of $e_2$ may not be assigned to $S_2$,
+and if the static type of $e_3$ may not be assigned to $S_3$.
+The static type of $a$ is the static type of $e_3$.
 
 \LMHash{}
-It is a compile-time error if the static type of $e$ may not be assigned to the static type of the formal parameter of the setter $v=$.
-The static type of the expression $\SUPER.v$ \code{=} $e$ is the static type of $e$.
-
-\LMHash{}
-Evaluation of an assignment $e$ of the form \code{$e_1$[$e_2$] = $e_3$}
+Evaluation of an assignment $a$ of the form \code{$e_1$[$e_2$] = $e_3$}
 proceeds as follows:
-
-\LMHash{}
 Evaluate $e_1$ to an object $a$, then evaluate $e_2$ to an object $i$, and finally evaluate $e_3$ to an object $v$.
 Call the method \code{[]=} on $a$ with $i$ as first argument and $v$ as second argument.
-Then $e$ evaluates to $v$.
+Then $a$ evaluates to $v$.
+% Should we add: It is a dynamic error if $e_1$ evaluates to a constant list or map?
 
 \LMHash{}
-The static type of the expression \code{$e_1$[$e_2$] = $e_3$} is the static type of $e_3$.
+\Case{\code{\SUPER[$e_1$] = $e_2$}}
+Consider an assignment $a$ of the form \code{\SUPER[$e_1$] = $e_2$}.
+Let $S_{static}$ be the superclass of the immediately enclosing class.
+It is a compile-time error if $S_{static}$ does not have a method \code{[]=}.
+Otherwise, let $S_1$ be the static type of the first formal parameter of the method \code{[]=}
+and $S_2$ the static type of the second.
+It is a compile-time error if the static type of $e_1$ may not be assigned to $S_1$,
+and if the static type of $e_2$ may not be assigned to $S_2$.
+The static type of $a$ is the static type of $e_2$.
 
 \LMHash{}
-An assignment of the form \code{\SUPER[$e_1$] = $e_2$} is equivalent to the expression \code{\SUPER.[$e_1$] = $e_2$}.
-The static type of the expression \code{\SUPER[$e_1$] = $e_2$} is the static type of $e_2$.
+For evaluation, an assignment of the form \code{\SUPER[$e_1$] = $e_2$}
+is equivalent to the expression \code{\SUPER.[$e_1$] = $e_2$}.
 
-% Should we add: It is a dynamic error if $e_1$ evaluates to an constant list or map.
-
-\LMHash{}
-It is a compile-time error if an assignment of the form $v = e$ occurs inside a top level or static function (be it function, method, getter, or setter) or variable initializer,
-and there is neither a local variable (\commentary{which includes formal parameters}) with name $v$
-nor a setter declaration with name $v=$ in the lexical scope enclosing the assignment.
-
-\LMHash{}
-It is a compile-time error to invoke any of the setters of class \code{Object} on a prefix object (\ref{imports}) or on a constant type literal that is immediately followed by the token `.'.
 
 \subsubsection{Compound Assignment}
 \LMLabel{compoundAssignment}
 
 \LMHash{}
-Evaluation of a compound assignment $a$ of the form \code{$v$ ??= $e$}
-proceeds as follows:
+\Case{\code{$v$ ??= $e$}}
+Consider a compound assignment $a$ of the form \code{$v$ ??= $e$}
+where $v$ is an identifier or an identifier qualified by an import prefix,
+such that $v$ denotes a variable or $v$ denotes a getter, and \code{$v$=} denotes a setter.
+Exactly the same compile-time errors that would be caused by \code{$v$ = $e$} are also generated in the case of $a$.
+%% TODO(eernst): We should mention other cases, e.g., `v=` denotes a setter, but there is no getter.
+The static type of $a$ is the least upper bound of the static type of $v$ and the static type of $e$.
 
 \LMHash{}
+Evaluation of a compound assignment $a$ of the form \code{$v$ ??= $e$}
+proceeds as follows:
 Evaluate $v$ to an object $o$.
 If $o$ is not the null object (\ref{null}), $a$ evaluates to $o$.
 Otherwise evaluate \code{$v$ = $e$} to a value $r$,
 and then $a$ evaluates to $r$.
 
 \LMHash{}
-Evaluation of a compound assignment, $a$ of the form \code{$C$.$v$ ??= $e$}, where $C$ is a type literal, proceeds as follow:
+\Case{\code{$C$.$v$ ??= $e$}}
+Consider a compound assignment $a$ of the form \code{$C$.$v$ ??= $e$}
+where $C$ is a type literal
+that may or may not be qualified by an import prefix,
+such that \code{$C$.$v$} denotes a getter and \code{$C$.$v$=} denotes a setter.
+Exactly the same compile-time errors that would be caused by \code{$C$.$v$ = $e$} are also generated in the case of $a$.
+%% TODO(eernst): We should mention other cases, e.g., `C.v=` denotes a setter, but there is no getter.
+The static type of $a$ is the least upper bound of the static type of \code{$C$.$v$} and the static type of $e$.
 
 \LMHash{}
+Evaluation of a compound assignment $a$ of the form \code{$C$.$v$ ??= $e$}
+where $C$ is a type literal proceeds as follow:
 Evaluate \code{$C$.$v$} to an object $o$.
 If $o$ is not the null object (\ref{null}), $a$ evaluates to $o$.
 Otherwise evaluate \code{$C$.$v$ = $e$} to a value $r$,
 and then $a$ evaluates to $r$.
 
-\commentary{
-The two rules above also apply when the variable v or the type C is prefixed.
-}
+\LMHash{}
+\Case{\code{$e_1$.$v$ ??= $e_2$}}
+Consider a compound assignment $a$ of the form \code{$e_1$.$v$ ??= $e_2$}.
+Let $T$ be the static type of $e_1$ and let $x$ be a fresh variable of type $T$.
+Except for errors inside $e_1$ and references to the name $x$,
+exactly the same compile-time errors that would be caused by \code{$x$.$v$ = $e_2$} are also generated in the case of $a$.
+%% TODO(eernst): Also, we should mention other cases, e.g., there is no getter `z.v`.
+The static type of $a$ is the least upper bound of the static type of \code{$e_1$.$v$} and the static type of $e_2$.
 
 \LMHash{}
 Evaluation of a compound assignment $a$ of the form \code{$e_1$.$v$ ??= $e_2$}
 proceeds as follows:
-
-\LMHash{}
 Evaluate $e_1$ to an object $u$.
 Let $x$ be a fresh variable bound to $u$.
 Evaluate \code{$x$.$v$} to an object $o$.
@@ -6725,10 +7165,15 @@
 and then $a$ evaluates to $r$.
 
 \LMHash{}
-Evaluation of a compound assignment $a$ of the form \code{$e_1$[$e_2$] ??= $e_3$}
-proceeds as follows:
+\Case{\code{$e_1$[$e_2$] ??= $e_3$}}
+Consider a compound assignment $a$ of the form \code{$e_1$[$e_2$] ??= $e_3$}.
+Exactly the same compile-time errors that would be caused by \code{$e_1$[$e_2$] = $e_3$} are also generated in the case of $a$.
+%% TODO(eernst): We should mention other cases, e.g., there is no `operator []`.
+The static type of $a$ is the least upper bound of the static type of \code{$e_1$[$e_2$]} and the static type of $e_3$.
 
 \LMHash{}
+Evaluation of a compound assignment $a$ of the form \code{$e_1$[$e_2$] ??= $e_3$}
+proceeds as follows:
 Evaluate $e_1$ to an object $u$ and then evaluate $e_2$ to an object $i$.
 Call the \code{[]} method on $u$ with argument $i$, and let $o$ be the returned value.
 If $o$ is not the null object (\ref{null}), $a$ evaluates to $o$.
@@ -6737,73 +7182,102 @@
 Then $a$ evaluates to $v$.
 
 \LMHash{}
-Evaluation of a compound assignment $a$ of the form \code{\SUPER.$v$ ??= $e$}
-proceeds as follows:
+\Case{\code{\SUPER.$v$ ??= $e$}}
+Consider a compound assignment $a$ of the form \code{\SUPER.$v$ ??= $e$}.
+Exactly the same compile-time errors that would be caused by \code{\SUPER.$v$ = $e$} are also generated in the case of $a$.
+%% TODO(eernst): We should mention other cases, e.g., there is no getter `\SUPER.v`.
+The static type of $a$ is the least upper bound of the static type of \code{\SUPER.$v$} and the static type of $e$.
 
 \LMHash{}
+Evaluation of a compound assignment $a$ of the form \code{\SUPER.$v$ ??= $e$}
+proceeds as follows:
 Evaluate \code{\SUPER.$v$} to an object $o$.
 If $o$ is not the null object (\ref{null}) then $a$ evaluates to $o$.
 Otherwise evaluate \code{\SUPER.$v$ = $e$} to an object $r$,
 and then $a$ evaluates to $r$.
 
 \LMHash{}
-Evaluation of a compound assignment $a$ of the form \code{$e_1$?.$v$ ??= $e_2$}
-proceeds as follows:
+\Case{\code{$e_1$?.$v$ ??= $e_2$}}
+Consider a compound assignment $a$ of the form \code{$e_1$?.$v$ ??= $e_2$}.
+Exactly the same compile-time errors that would be caused by \code{$e_1$.$v$ ??= $e_2$} are also generated in the case of $a$.
+% Note: We use the static type of \code{$e_1$?.$v$} rather than \code{$e_1$.$v$} even
+% though the latter would be simpler. This is because the former will remain correct
+% if NNBD is introduced, and because it reduces the amount of synthetic syntax.
+The static type of $a$ is the least upper bound of the static type of \code{$e_1$?.$v$} and the static type of $e_2$.
 
 \LMHash{}
-Evaluate $e_1$ to an object $u$ and let $x$ be a fresh variable bound to $u$.
+Evaluation of a compound assignment $a$ of the form \code{$e_1$?.$v$ ??= $e_2$}
+proceeds as follows:
+Evaluate $e_1$ to an object $u$.
+If $u$ is the null object (\ref{null}) then $a$ evaluates to the null object.
+Otherwise, let $x$ be a fresh variable bound to $u$.
 Evaluate \code{$x$.$v$} to an object $o$.
 If $o$ is not the null object (\ref{null}) then $a$ evaluates to $o$.
 Otherwise evaluate \code{$x$.$v$ = $e_2$} to an object $r$,
 and then $a$ evaluates to $r$.
 
-% But what about C?.v ??= e
+\LMHash{}
+\Case{\code{$C$?.$v$ ??= $e_2$}}
+A compound assignment of the form \code{$C$?.$v$ ??= $e_2$}
+where $C$ is a type literal
+that may or may not be be qualified by an import prefix
+is equivalent to the expression \code{$C$.$v$ ??= $e$}.
 
 \LMHash{}
-A compound assignment of the form $C?.v$ {\em ??=} $e_2$ is equivalent to the expression $C.v$ {\em ??=} $e$.
+\Case{\code{$v$ $op$= $e$}}
+For any other valid operator $op$, a compound assignment of the form \code{$v$ $op$= $e$}
+is equivalent to \code{$v$ = $v$ $op$ $e$},
+where $v$ is an identifier or an identifier qualified by an import prefix.
 
 \LMHash{}
-The static type of a compound assignment of the form $v$ {\em ??=} $e$ is the least upper bound of the static type of $v$ and the static type of $e$.
-Exactly the same compile-time errors that would be caused by $v = e$ are also generated in the case of $v$ {\em ??=} $e$.
+\Case{\code{$C$.$v$ $op$= $e$}}
+A compound assignment of the form \code{$C$.$v$ $op$= $e$}
+where $C$ is a type literal
+that may or may not be qualified by an import prefix
+is equivalent to \code{$C$.$v$ = $C$.$v$ $op$ $e$}.
 
 \LMHash{}
-The static type of a compound assignment of the form $C.v$ {\em ??=} $e$ is the least upper bound of the static type of $C.v$ and the static type of $e$.
-Exactly the same compile-time errors that would be caused by $C.v = e$ are also generated in the case of $C.v$ {\em ??=} $e$.
+\Case{\code{$e_1$.$v$ $op$= $e_2$}}
+Consider a compound assignment $a$ of the form \code{$e_1$.$v$ $op$= $e_2$}.
+Let $x$ be a fresh variable whose static type is the static type of $e_1$.
+Except for errors inside $e_1$ and references to the name $x$,
+exactly the same compile-time errors that would be caused by \code{$x$.$v$ = $x$.$v$ $op$ $e_2$} are also generated in the case of $a$.
+The static type of $a$ is the static type of \code{$e_1$.$v$ $op$ $e_2$}.
 
 \LMHash{}
-The static type of a compound assignment of the form $e_1.v$ {\em ??=} $e_2$ is the least upper bound of the static type of $e_1.v$ and the static type of $e_2$.
-Let $T$ be the static type of $e_1$ and let $z$ be a fresh variable of type $T$.
-Exactly the same compile-time errors that would be caused by $z.v = e_2$ are also generated in the case of $e_1.v$ {\em ??=} $e_2$.
-
-\LMHash{}
-The static type of a compound assignment of the form $e_1[e_2]$ {\em ??=} $e_3$ is the least upper bound of the static type of $e_1[e_2]$ and the static type of $e_3$.
-Exactly the same compile-time errors that would be caused by $e_1[e_2] = e_3$ are also generated in the case of $e_1[e_2]$ {\em ??=} $e_3$.
-
-\LMHash{}
-The static type of a compound assignment of the form $\SUPER.v$ {\em ??=} $e$ is the least upper bound of the static type of $\SUPER.v$ and the static type of $e$.
-Exactly the same compile-time errors that would be caused by $\SUPER.v = e$ are also generated in the case of $\SUPER.v$ {\em ??=} $e$.
-
-\LMHash{}
-For any other valid operator $op$, a compound assignment of the form \code{$v$ $op$= $e$} is equivalent to \code{$v$ = $v$ $op$ $e$}.
-A compound assignment of the form \code{$C$.$v$ $op$= $e$} is equivalent to \code{$C$.$v$ = $C$.$v$ $op$ $e$}.
-
-\LMHash{}
-Evaluation of a compound assignment $a$ of the form \code{$e_1$.$v$ $op$= $e_2$} proceeds as follows:
+Evaluation of a compound assignment $a$ of the form \code{$e_1$.$v$ $op$= $e_2$}
+proceeds as follows:
 Evaluate $e_1$ to an object $u$ and let $x$ be a fresh variable bound to $u$.
 Evaluate \code{$x$.$v$ = $x$.$v$ $op$ $e_2$} to an object $r$
 and then $a$ evaluates to $r$.
 
 \LMHash{}
-Evaluation of s compound assignment $a$ of the form \code{$e_1$[$e_2$] $op$= $e_3$} proceeds as follows:
+\Case{\code{$e_1$[$e_2$] $op$= $e_3$}}
+Consider a compound assignment $a$ of the form \code{$e_1$[$e_2$] $op$= $e_3$}.
+Let $x$ and $i$ be fresh variables
+where the static type of the former is the static type of $e_1$
+and the static type of the latter is the static type of $e_2$.
+Except for errors inside $e_1$ and $e_2$ and references to the names $x$ and $i$,
+exactly the same compile-time errors that would be caused by \code{$x$[$i$] = $x$[$i$] $op$ $e_3$} are also generated in the case of $a$.
+The static type of $a$ is the static type of \code{$x$[$i$] $op$ $e_3$}.
+
+\LMHash{}
+Evaluation of s compound assignment $a$ of the form \code{$e_1$[$e_2$] $op$= $e_3$}
+proceeds as follows:
 Evaluate $e_1$ to an object $u$ and evaluate $e_2$ to an object $v$.
-Let $a$ and $i$ be fresh variables bound to $u$ and $v$ respectively.
-Evaluate \code{$a$[$i$] = $a$[$i$] $op$ $e_3$} to an object $r$,
+Let $x$ and $i$ be fresh variables bound to $u$ and $v$ respectively.
+Evaluate \code{$x$[$i$] = $x$[$i$] $op$ $e_3$} to an object $r$,
 and then $a$ evaluates to $r$.
 
 \LMHash{}
-Evaluation of a compound assignment $a$ of the form \code{$e_1$?.$v$ $op$ = $e_2$} proceeds as follows:
+\Case{\code{$e_1$?.$v$ $op$= $e_2$}}
+Consider a compound assignment $a$ of the form \code{$e_1$?.$v$ $op$= $e_2$}.
+Exactly the same compile-time errors that would be caused by \code{$e_1$.$v$ $op$= $e_2$} are also generated in the case of $a$.
+The static type of $a$ is the static type of \code{$e_1$.$v$ $op$= $e_2$}.
 
 \LMHash{}
+Evaluation of a compound assignment $a$ of the form \code{$e_1$?.$v$ $op$= $e_2$}
+proceeds as follows:
 Evaluate $e_1$ to an object $u$.
 If $u$ is the null object, then $a$ evaluates to the null object (\ref{null}).
 Otherwise let $x$ be a fresh variable bound to $u$.
@@ -6811,12 +7285,10 @@
 Then $a$ evaluates to $r$.
 
 \LMHash{}
-The static type of \code{$e_1$?.$v$ $op$= $e_2$} is the static type of \code{$e_1$.$v$ $op$ $e_2$}.
-Exactly the same compile-time errors that would be caused by \code{$e_1$.$v$ $op$= $e_2$} are also generated in the case of \code{$e_1$?.$v$ $op$= $e_2$}.
-
-\LMHash{}
-A compound assignment of the form $C?.v$ $op = e_2$ is equivalent to the expression
-$C.v$ $op = e_2$.
+\Case{\code{$C$?.$v$ $op$ = $e_2$}}
+A compound assignment of the form \code{$C$?.$v$ $op$ = $e_2$}
+where $C$ is a type literal
+is equivalent to the expression \code{$C$.$v$ $op$ = $e_2$}.
 
 \begin{grammar}
 {\bf compoundAssignmentOperator:}`*=';
@@ -6860,9 +7332,10 @@
 \LMHash{}
 If all of the following hold:
 \begin{itemize}
-\item $e_1$ shows that a variable $v$ has type $T$.
+\item $e_1$ shows that a local variable $v$ has type $T$.
 \item $v$ is not potentially mutated in $e_2$ or within a function.
-\item If the variable $v$ is accessed by a function in $e_2$ then the variable $v$ is not potentially mutated anywhere in the scope of $v$.
+\item If the variable $v$ is accessed by a function in $e_2$ then
+$v$ is not potentially mutated anywhere in the scope of $v$.
 \end{itemize}
 
 then the type of $v$ is known to be $T$ in $e_2$.
@@ -6929,12 +7402,12 @@
 Otherwise the result of evaluating $b$ is $o_2$.
 
 \LMHash{}
-A logical boolean expression $b$ of the form $e_1 \&\& e_2$ shows that a variable $v$ has type
-$T$ if all of the following conditions hold:
+A logical boolean expression $b$ of the form $e_1 \&\& e_2$
+shows that a local variable $v$ has type $T$
+if both of the following conditions hold:
 \begin{itemize}
 \item Either $e_1$ shows that $v$ has type $T$ or $e_2$ shows that $v$ has type $T$.
-\item $v$ is a local variable or formal parameter.
-\item The variable $v$ is not mutated in $e_2$ or within a function.
+\item $v$ is not mutated in $e_2$ or within a function.
 \end{itemize}
 
 \LMHash{}
@@ -6942,7 +7415,8 @@
 \begin{itemize}
 \item $e_1$ shows that $v$ has type $T$.
 \item $v$ is not mutated in either $e_1$, $e_2$ or within a function.
-\item If the variable $v$ is accessed by a function in $e_2$ then the variable $v$ is not potentially mutated anywhere in the scope of $v$.
+\item If $v$ is accessed by a function in $e_2$ then
+$v$ is not potentially mutated anywhere in the scope of $v$.
 \end{itemize}
 then the type of $v$ is known to be $T$ in $e_2$.
 
@@ -7212,23 +7686,27 @@
 \LMHash{}
 If $e$ is an expression of the form \code{-$l$}
 where $l$ is an integer literal (\ref{numbers}) with numeric integer value $i$,
-then the static type of $e$ is the same as the static type of an integer literal
-with the same context type,
-and evaluation of $e$ first proceeds as for an integer literal
-with numeric value $-i$, evaluating to a value $v$.
-Then, if the static type of the $e$ is \code{double} and $v$ is the \code{double} value 0.0, then $e$ evaluates to the \code{double} value -0.0,
-otherwise $e$ evaluates to $v$.
+and with static contex type $T$.
+If \code{double} is assignable to $T$ and \code{int} is not assignable to $T$,
+then the static type of $e$ is \code{double};
+otherwise the static type of $e$ is \code{int}.
+
+\LMHash{}
+If the static type of $e$ is \code{int} then $e$ evaluates to
+to an instance of the \code{int} class representing the numeric value $-i$.
+It is a compile-time error if the integer $-i$ cannot be represented
+exactly by an instance of \code{int}.
+
+\LMHash{}
+If the static type of $e$ is \code{double} then $e$ evaluates to
+to an instance of the \code{double} class representing the numeric value $-i$.
+It is a compile-time error if the integer $-i$ cannot be represented
+exactly by an instance of \code{double}.
 \commentary{
-We treat \code{-$l$} \emph{as if} it is a single integer literal with a negative
-numeric value. The specified semantics of integer literals (\ref{numbers})
-allows negative numeric values, so they can be applied as-is to the value $-i$,
-except that we want \code{-0} in a \code{double} context
-to evaluate to \code{-0.0}.
-The expression \code{-$l$} is not \emph{itself} an integer literal,
-it's merely treated as one,
-so this rule does not apply twice to \code{- -$l$}.
-It also does not apply to \code{-($l$)}
-since a parenthesized expression is not an integer literal expression.
+We treat \code{-$l$} \emph{as if} it is a single integer literal
+with a negative numeric value.
+We do not evaluate $l$ individually as an expression,
+or concern ourselves with its static type.
 }
 
 \LMHash{}
@@ -7285,7 +7763,7 @@
 }
 
 \LMHash{}
-The static type of $a$ is $flatten(T)$ (the $flatten$ function is defined in section \ref{functionExpressions}) where $T$ is the static type of $e$.
+The static type of $a$ is \flatten{T} (\flatten{} is defined in section \ref{functionExpressions}) where $T$ is the static type of $e$.
 
 
 \subsection{Postfix Expressions}
@@ -7332,7 +7810,7 @@
 
 \LMHash{}
 Evaluation of a postfix expression $e$ of the form \code{$C$.$v$++}
-proceeds as follows:
+where $C$ is a type literal proceeds as follows:
 
 \LMHash{}
 Evaluate \code{$C$.$v$} to a value $r$
@@ -7499,7 +7977,7 @@
 \LMHash{}
 An assignable expression of the form \id{} is evaluated as an identifier expression (\ref{identifierReference}).
 
-%An assignable expression of the form \code{$e$.\id($a_1, \ldots, a_n$)} is evaluated as a method invocation (\ref{methodInvocation}).
+%An assignable expression of the form \code{$e$.\id($a_1, \ldots,\ a_n$)} is evaluated as a method invocation (\ref{methodInvocation}).
 
 \LMHash{}
 An assignable expression of the form \code{$e$.\id} or \code{$e$?.\id} is evaluated as a property extraction (\ref{propertyExtraction}).
@@ -7603,7 +8081,6 @@
 \LMHash{}
 Let $d$ be the innermost declaration in the enclosing lexical scope whose name is \id{} or \code{\id=}.
 If no such declaration exists in the lexical scope, let $d$ be the declaration of the inherited member named \id{} if it exists.
-%If no such member exists, let $d$ be the declaration of the static member name \id{} declared in a superclass of the current class, if it exists.
 
 \begin{itemize}
 \item if $d$ is a prefix $p$, a compile-time error occurs unless the token immediately following $d$ is \code{'.'}.
@@ -7619,10 +8096,9 @@
 %  Otherwise
 %  \item $e$ evaluates to the current binding of \id.
 %  \end{itemize}
-\item If $d$ is a local variable or formal parameter then $e$ evaluates to the current binding of \id.
-%\item If $d$ is a library variable, local variable, or formal parameter, then $e$ evaluates to the current binding of \id. \commentary{This case also applies if d is a library or local function declaration, as these are equivalent to function-valued variable declarations.}
+\item If $d$ is a local variable (\commentary{which can be a formal parameter}) then $e$ evaluates to the current binding of \id.
 \item If $d$ is a static method, top-level function or local function then $e$ evaluates to the function object obtained by closurization (\ref{functionClosurization}) of the declaration denoted by $d$.
-\item If $d$ is the declaration of a static variable, static getter or static setter declared in class $C$, then evaluation of $e$ is equivalent to evaluation of the property extraction (\ref{propertyExtraction}) \code{$C$.\id}.
+\item If $d$ is the declaration of a class variable, static getter or static setter declared in class $C$, then evaluation of $e$ is equivalent to evaluation of the property extraction (\ref{propertyExtraction}) \code{$C$.\id}.
 \item If $d$ is the declaration of a library variable, top-level getter or top-level setter, then evaluation of $e$ is equivalent to evaluation of the top level getter invocation (\ref{topLevelGetterInvocation}) \id.
 \item Otherwise, if $e$ occurs inside a top level or static function (be it function, method, getter, or setter) or variable initializer, evaluation of $e$ causes a \code{NoSuchMethod} to be thrown.
 \item Otherwise, evaluation of $e$ is equivalent to evaluation of the property extraction (\ref{propertyExtraction}) \code{\THIS.\id}.
@@ -7633,12 +8109,19 @@
 
 \begin{itemize}
 \item If $d$ is a class, type alias or type parameter the static type of $e$ is \code{Type}.
-\item If $d$ is a local variable or formal parameter the static type of $e$ is the type of the variable \id, unless \id{} is known to have some type $T$, in which case the static type of $e$ is $T$, provided that $T$ is more specific than any other type $S$ such that $v$ is known to have type $S$.
+\item If $d$ is a local variable (\commentary{which can be a formal parameter})
+  the static type of $e$ is the type of the variable \id,
+  unless \id{} is known to have some type $T$,
+  in which case the static type of $e$ is $T$,
+  provided that $T$ is more specific than any other type $S$ such that $v$ is known to have type $S$.
 \item If $d$ is a static method, top-level function or local function the static type of $e$ is the function type defined by $d$.
-\item If $d$ is the declaration of a static variable, static getter or static setter declared in class $C$, the static type of $e$ is the static type of the getter invocation (\ref{propertyExtraction}) \code{$C$.\id}.
-\item If $d$ is the declaration of a library variable, top-level getter or top-level setter, the static type of $e$ is the static type of the top level getter invocation \id.
-\item Otherwise, if $e$ occurs inside a top level or static function (be it function, method, getter, or setter) or variable initializer, the static type of $e$ is \DYNAMIC{}.
-\item Otherwise, the static type of $e$ is the type of the property extraction (\ref{propertyExtraction}) \THIS{}.\id.
+\item If $d$ is the declaration of a class variable, static getter or static setter declared in class $C$,
+  the static type of $e$ is the static type of the getter invocation (\ref{propertyExtraction}) \code{$C$.\id}.
+\item If $d$ is the declaration of a library variable, top-level getter or top-level setter,
+  the static type of $e$ is the static type of the top level getter invocation \id.
+\item Otherwise, if $e$ occurs inside a top level or static function (be it function, method, getter, or setter) or variable initializer,
+  the static type of $e$ is \DYNAMIC{}.
+\item Otherwise, the static type of $e$ is the type of the property extraction (\ref{propertyExtraction}) \code{\THIS.\id}.
 \end{itemize}
 
 \commentary{
@@ -7696,7 +8179,7 @@
 % Add flow dependent types
 
 \LMHash{}
-Let $v$ be a local variable or a formal parameter.
+Let $v$ be a local variable (\commentary{which can be a formal parameter}).
 An is-expression of the form \code{$v$ \IS{} $T$} shows that $v$ has type $T$ if{}f $T$ is more specific than the type $S$ of the expression $v$ and both $T \ne \DYNAMIC{}$ and $S \ne \DYNAMIC{}$.
 
 \rationale{
@@ -7704,7 +8187,7 @@
 The rules in the current specification are deliberately kept simple.
 It would be upwardly compatible to refine these rules in the future; such a refinement would accept more code without errors, but not reject any code now error-free.
 
-The rule only applies to locals and parameters, as instance or static variables could be modified via side-effecting functions or methods that are not accessible to a local analysis.
+The rule only applies to locals and parameters, as instance and static variables could be modified via side-effecting functions or methods that are not accessible to a local analysis.
 
 It is pointless to deduce a weaker type than what is already known.
 Furthermore, this would lead to a situation where multiple types are associated with a variable at a given point, which complicates the specification.
@@ -7856,11 +8339,14 @@
 If the expression evaluates to a value, then the value is ignored
 and the execution completes normally.
 
+
 \subsection{Local Variable Declaration}
 \LMLabel{localVariableDeclaration}
 
 \LMHash{}
-A {\em variable declaration statement }declares a new local variable.
+A {\em variable declaration statement},
+also known as a {\em local variable declaration},
+has the following form:
 
 \begin{grammar}
 {\bf localVariableDeclaration:}initializedVariableDeclaration `{\escapegrammar ;}'
@@ -7868,37 +8354,153 @@
 \end{grammar}
 
 \LMHash{}
- Executing a variable declaration statement of one of the forms \VAR{} $v = e;$, $T$ $v = e; $, \CONST{} $v = e;$, \CONST{} $T$ $v = e;$, \FINAL{} $v = e;$ or \FINAL{} $T$ $v = e;$ proceeds as follows:
+Each local variable declaration introduces
+a {\em local variable} into the innermost enclosing scope.
+
+\commentary{
+Local variables do not induce getters and setters.
+Note that a formal parameter declaration also introduces
+a local variable into the associated formal parameter scope
+(\ref{formalParameters}).
+}
+
+\LMHash{}
+The properties of being
+{\em initialized}, {\em constant}, {\em final}, and {\em mutable}
+apply to local variables with the same definitions as for other variables
+(\ref{variables}).
+
+\LMHash{}
+We say that a local variable $v$ is {\em potentially mutated} in some scope $s$
+if $v$ is mutable, and an assignment to $v$ occurs in $s$.
+
+\LMHash{}
+A local variable declaration of the form \code{\VAR{} $v$;} is equivalent to \code{\VAR{} $v$ = \NULL{};}.
+A local variable declaration of the form \code{$T$ $v$;} is equivalent to \code{$T$ $v$ = \NULL{};}.
+
+\commentary{
+This holds regardless of the type $T$.
+E.g., \code{int i;} is equivalent to \code{int i = null;}.
+}
+
+\LMHash{}
+The type of a local variable with a declaration of one of the forms
+\code{$T$ $v$ = $e$;}
+\code{\CONST{} $T$ $v$ = $e$;}
+\code{\FINAL{} $T$ $v$ = $e$;}
+is $T$.
+The type of a local variable with a declaration of one of the forms
+\code{\VAR{} $v$ = $e$;}
+\code{\CONST{} $v$ = $e$;}
+\code{\FINAL{} $v$ = $e$;}
+is \DYNAMIC{}.
+
+\LMHash{}
+Let $v$ be an initialized local variable and let $e$ be the associated initializing expression.
+It is a compile-time error if the static type of $e$ is not assignable to the type of $v$.
+It is a compile-time error if a local variable $v$ is final and $v$ is not an initialized variable.
+
+\commentary{
+It is also a compile-time error to assign to a final local variable
+(\ref{assignment}).
+}
+
+\LMHash{}
+It is a compile-time error if
+a local variable is referenced at a source code location that is before
+the end of its initializing expression, if any,
+and otherwise before the identifier which names the variable.
+
+\commentary{
+The example below illustrates the expected behavior.
+A variable `\code{x}' is declared at the library level,
+and another `\code{x}' is declared inside the function `\code{f}'.
+}
+
+\begin{dartCode}
+\VAR{} x = 0;
+
+f(y) \{
+  \VAR{} z = x; // compile-time error
+  if (y) \{
+    x = x + 1; // two compile-time errors
+    print(x); // compile-time error
+  \}
+  \VAR{} x = x++; // compile-time error
+  print(x);
+\}
+\end{dartCode}
+
+\commentary{
+The declaration inside `\code{f}' hides the enclosing one.
+So all references to `\code{x}' inside `\code{f}'
+refer to the inner declaration of `\code{x}'.
+However, many of these references are illegal,
+because they appear before the declaration.
+The assignment to `\code{z}' is one such case.
+The assignment to `\code{x}' in the \IF{} statement
+suffers from multiple problems.
+The right hand side reads `\code{x}' before its declaration,
+and the left hand side assigns to `\code{x}' before its declaration.
+Each of these are, independently, compile-time errors.
+The print statement inside the \IF{} is also illegal.
+
+The inner declaration of `\code{x}' is itself erroneous
+because its right hand side attempts to
+read `\code{x}' before the declaration has terminated.
+The occurrence of `\code{x}' that declares and names the variable
+(that is, the one to the left of `\code{=}' in the inner declaration)
+is not a reference, and so is legal.
+The last print statement is perfectly legal as well.
+}
+
+\commentary{
+As another example \code{\VAR{} x = 3, y = x;} is legal,
+because \code{x} is referenced after its initializer.
+
+A particularly perverse example involves
+a local variable name shadowing a type.
+This is possible because Dart has a
+single namespace for types, functions and variables.
+}
+
+\begin{dartCode}
+\CLASS{} C \{\}
+perverse() \{
+   \VAR{} v = \NEW{} C(); // compile-time error
+   C aC; // compile-time error
+   \VAR{} C = 10;
+\}
+\end{dartCode}
+
+\commentary{
+Inside \code{perverse()}, `\code{C}' denotes a local variable.
+The type `\code{C}' is hidden by the variable of the same name.
+The attempt to instantiate `\code{C}' causes a compile-time error
+because it references a local variable prior to its declaration.
+Similarly, for the declaration of `\code{aC}'.
+}
+
+\LMHash{}
+Execution of a variable declaration statement of one of the forms
+\code{\VAR{} $v$ = $e$;}
+\code{$T$ $v$ = $e$;}
+\code{\CONST{} $v$ = $e$;}
+\code{\CONST{} $T$ $v$ = $e$;}
+\code{\FINAL{} $v$ = $e$;} or
+\code{\FINAL{} $T$ $v$ = $e$;}
+proceeds as follows:
 
 \LMHash{}
 The expression $e$ is evaluated to an object $o$.
 Then, the variable $v$ is set to $o$.
+A dynamic error occurs
+if the dynamic type of $o$ is not a subtype of the actual type
+(\ref{actualTypeOfADeclaration})
+of $v$.
 
-\LMHash{}
-A variable declaration statement of the form \code{\VAR{} $v$;} is equivalent to \code{\VAR{} $v$ = \NULL{};}.
-A variable declaration statement of the form \code{$T$ $v$;} is equivalent to \code{$T$ $v$ = \NULL{};}.
-
-\commentary{
-This holds regardless of the type $T$.
-For example, \code{int i;} does not cause \code{i} to be initialized to zero.
-Instead, \code{i} is initialized to the null object (\ref{null}), just as if we had written \VAR{} \code{i;} or \code{Object i;} or \code{Collection<String> i;}.
-}
-
-\rationale{
-To do otherwise would undermine the optionally typed nature of Dart, causing type annotations to modify program behavior.
-}
-
-%A variable declaration statement of one of the forms $T$ $v;$, $T$ $v = e;$, \CONST{} $T$ $v = e;$, or \FINAL{} $T$ $v = e;$ causes a new getter named $v$ with static return type $T$ to be added to the innermost enclosing scope at the point following the variable declaration statement. The result of executing this getter is the value stored in $v$.
-
-%A variable declaration statement \VAR{} $v;$, \VAR{} $v = e;$, \CONST{} $v = e;$ or \FINAL{} $v = e;$ causes a new getter named $v$ with static return type \DYNAMIC{} to be added to the innermost enclosing scope at the point following the variable declaration statement. The result of executing this getter is the value stored in $v$.
-
-%A variable declaration statement of one of the forms $T$ $v;$, or $T$ $v = e;$ causes a new setter named $v=$ with argument type $T$ to be added to the innermost enclosing scope at the point following the variable declaration statement. The effect of executing this setter is to store its argument in $v$.
-
-%A variable declaration statement \VAR{} $v;$, \VAR{} $v = e;$, \CONST{} $v = e;$ or \FINAL{} $v = e;$ causes a new setter named $v=$ with argument type \DYNAMIC{} to be added to the innermost enclosing scope at the point following the variable declaration statement. The effect of executing this setter is to store its argument in $v$.
-
-%\rationale{
- %The use of getters and setters here is a device to help make the specification more uniform. Introducing getters and setters for local variables has no performance consequences, since they can never be overridden, and so can always be optimized away.  It is not possible to declare a local getter or setter explicitly, since there is little reason to ever do so.
-%}
+% The local variable discussion does not mention how to read/write locals.
+% Consider spelling this out, in terms of storage.
 
 
 \subsection{Local Function Declaration}
@@ -7943,8 +8545,11 @@
 \end{dartCode}
 
 \commentary{
-There is no way to write a pair of mutually recursive local functions, because one always has to come before the other is declared.
-These cases are quite rare, and can always be managed by defining a pair of variables first, then assigning them appropriate function literals:
+There is no way to write a pair of mutually recursive local functions,
+because one always has to come before the other is declared.
+These cases are quite rare,
+and can always be managed by defining a pair of variables first,
+then assigning them appropriate function literals:
 }
 
 \begin{dartCode}
@@ -8011,9 +8616,10 @@
 \LMHash{}
 If:
 \begin{itemize}
-\item $b$ shows that a variable $v$ has type $T$.
+\item $b$ shows that a local variable $v$ has type $T$.
 \item $v$ is not potentially mutated in $s_1$ or within a function.
-\item If the variable $v$ is accessed by a function in $s_1$ then the variable $v$ is not potentially mutated anywhere in the scope of $v$.
+\item If $v$ is accessed by a function in $s_1$ then
+$v$ is not potentially mutated anywhere in the scope of $v$.
 \end{itemize}
 then the type of $v$ is known to be $T$ in $s_1$.
 
@@ -8084,12 +8690,15 @@
 
 \rationale{
 The definition above is intended to prevent the common error where users create a function object inside a for loop,
-intending to close over the current binding of the loop variable,
-and find (usually after a painful process of debugging and learning) that all the created function objects have captured the same value---the one current in the last iteration executed.
+intending to close over the current binding of the loop variable, and find
+(usually after a painful process of debugging and learning)
+that all the created function objects have captured the same value---the one current in the last iteration executed.
 
 Instead, each iteration has its own distinct variable.
 The first iteration uses the variable created by the initial declaration.
-The expression executed at the end of each iteration uses a fresh variable $v''$, bound to the value of the current iteration variable, and then modifies $v''$ as required for the next iteration.
+The expression executed at the end of each iteration uses a fresh variable $v''$,
+bound to the value of the current iteration variable,
+and then modifies $v''$ as required for the next iteration.
 }
 
 \LMHash{}
@@ -8310,7 +8919,7 @@
 \}
 \end{dartCode}
 
- or the form
+or the form
 
 \begin{dartCode}
 \SWITCH{} ($e$) \{
@@ -8320,7 +8929,7 @@
 \}
 \end{dartCode}
 
- it is a compile-time error if the expressions $e_k$ are not compile-time constants for all $k \in 1 .. n$.
+it is a compile-time error if the expressions $e_k$ are not compile-time constants for all $k \in 1 .. n$.
 It is a compile-time error if the values of the expressions $e_k$ are not either:
 \begin{itemize}
 \item instances of the same class $C$, for all $k \in 1 .. n$, or
@@ -8334,7 +8943,11 @@
 }
 
 \LMHash{}
-It is a compile-time error if the class $C$ has an implementation of the operator $==$ other than the one inherited from \code{Object} unless the value of the expression is a string, an integer, literal symbol or the result of invoking a constant constructor of class \code{Symbol}.
+It is a compile-time error if the class $C$ has an implementation of
+the operator \code{==} other than the one inherited from \code{Object},
+unless the expression evaluates to a string or an integer,
+or the expression is a literal symbol or
+an invocation of a constant constructor of class \code{Symbol}.
 
 \rationale{
 The prohibition on user defined equality allows us to implement the switch efficiently for user defined types.
@@ -8668,7 +9281,9 @@
 \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}
 {\bf returnStatement:}\RETURN{} expression? `{\escapegrammar ;}'
@@ -8676,38 +9291,14 @@
 \end{grammar}
 
 \LMHash{}
-Executing a return statement \code{\RETURN{} $e$;} proceeds as follows:
+Consider a return statement of the form \code{\RETURN{} $e$;}.
+Let $T$ be the static type of $e$, let $f$ be the immediately enclosing function,
+and let $S$ be the declared return type of $f$.
 
 \LMHash{}
-Let $T$ be the static type of $e$, let $f$ be the immediately enclosing function, and let $S$ be the actual return type (\ref{actualTypeOfADeclaration}) of $f$.
-
-\LMHash{}
-First the expression $e$ is evaluated, producing an object $o$.
-If the body of $f$ is marked \ASYNC{} (\ref{functions}) and the run-time type of $o$ is a subtype of \code{Future<$flatten(S)$>}, then let $r$ be the result of evaluating \code{await $v$} where $v$ is a fresh variable bound to $o$. Otherwise let $r$ be $o$.
-Then the return statement returns the value $r$ (\ref{completion}).
-
-\LMHash{}
-It is a compile-time error if the body of $f$ is marked \ASYNC{} and the type \code{Future<$flatten(T)$>} (\ref{functionExpressions}) may not be assigned to the declared return type of $f$.
-Otherwise, it is a compile-time error if $T$ may not be assigned to the declared return type of $f$.
-
-\LMHash{}
-Let $S$ be the run-time type of $o$.
-In checked mode:
-\begin{itemize}
-\item If the body of $f$ is marked \ASYNC{} (\ref{functions})
-it is a dynamic type error if $o$ is not the null object (\ref{null}),
-% TODO(lrn): Remove the next line when void is a proper supertype of all types.
-the actual return type (\ref{actualTypeOfADeclaration}) of $f$ is not \VOID,
-and \code{Future<$flatten(S)$>} is not a subtype of the actual return type of $f$.
-% TODO(lrn): The "void foo() async { return e }" case is somewhat speculative.
-% When we disallow "return e" in a void function, we might also want to revisit
-% this rule. Currently it also covers the "void foo() async => e;" case, which
-% we might want to allow.
-\item Otherwise, it is a dynamic type error if $o$ is not the null object (\ref{null}),
-% TODO(lrn): Remove the next line when void is a proper supertype of all types.
-the actual return type of $f$ is not \VOID{},
-and $S$ is not a subtype of the actual return type of $f$.
-\end{itemize}
+It is a compile-time error if the body of $f$ is marked \ASYNC{}
+and the type \code{Future<\flatten{T}>} (\ref{functionExpressions}) may not be assigned to $S$.
+Otherwise, it is a compile-time error if $T$ may not be assigned to $S$.
 
 \LMHash{}
 It is a compile-time error if a return statement of the form \code{\RETURN{} $e$;} appears in a generative constructor (\ref{generativeConstructors}).
@@ -8730,12 +9321,16 @@
 Let $f$ be the function immediately enclosing a return statement of the form \RETURN{};.
 It is a compile-time error if $f$ is neither a generator nor a generative constructor and either:
 \begin{itemize}
+%% TODO(eernst): Integrating generalized-void.md, "may not be assigned
+%% to void" is useless. Update, also considering invalid_returns.md.
 \item $f$ is synchronous and the return type of $f$ may not be assigned to \VOID{} (\ref{typeVoid}) or,
+%% TODO(eernst): Revisit when integrating invalid_returns.md.
 \item $f$ is asynchronous and the return type of $f$ may not be assigned to \code{Future<Null>}.
 \end{itemize}
 
 \commentary{
-Hence, a compile-time error will not be raised if $f$ has no declared return type, since the return type would be \DYNAMIC{} and \DYNAMIC{} may be assigned to \VOID{} and to \code{Future<Null>}.
+Hence, a compile-time error will not be raised if $f$ has no declared return type,
+since the return type would be \DYNAMIC{} and \DYNAMIC{} may be assigned to \VOID{} and to \code{Future<Null>}.
 However, any synchronous non-generator function that declares a return type must return an expression explicitly.
 }
 \rationale{
@@ -8752,6 +9347,65 @@
 }
 
 \LMHash{}
+Executing a return statement \code{\RETURN{} $e$;} proceeds as follows:
+
+\LMHash{}
+First the expression $e$ is evaluated, producing an object $o$.
+Let $T$ be the run-time type of $o$ and
+let $S$ be the actual return type of $f$
+(\ref{actualTypeOfADeclaration}).
+If the body of $f$ is marked \ASYNC{} (\ref{functions})
+and $T$ is a subtype of \code{Future<\flatten{S}>}
+then let $r$ be the result of evaluating \code{await $v$}
+where $v$ is a fresh variable bound to $o$.
+Otherwise let $r$ be $o$.
+Then the return statement returns the value $r$ (\ref{completion}).
+
+%% TODO(eernst): We have some special cases with the dynamic semantics
+%% specified above that we may wish to consider:
+%%
+%% Future<int> foo() async {
+%%   return new Future<Object>.value(42);
+%% }
+%%
+%% Statically we will allow this because `Future<flatten(Future<Object>)>`,
+%% i.e., `Future<Object>`, is assignable to `Future<int>`. But at run time
+%% we get an error because `Future<Object>` is is not a subtype of
+%% `Future<flatten(Future<int>)>` = `Future<int>`. We could have awaited
+%% the value just because we're about to return a `Future`, and it would
+%% then have succeeded. Are we doing the right thing? Might be fine, but
+%% it seems surprising that the compiler will sometimes insert `await`,
+%% and here we have to do it explicitly in order to succeed.
+%%
+%% Object /* or dynamic, etc. */ foo() async {
+%%   Object o;
+%%   if (someCondition) o = 42; else o = new Future<T>.value(42);
+%%   return o;
+%% }
+%%
+%% Here we will interject an `await` on the returned value whenever
+%% we return a future (for all `T`). This means that we will `await o`
+%% in some situations and not in others. It may surprise developers
+%% that we can have this dynamic variation at a location in the code
+%% where there is no static justification for expecting a future.
+
+\LMHash{}
+Let $U$ be the run-time type of $r$.
+In checked mode:
+\begin{itemize}
+\item If the body of $f$ is marked \ASYNC{} (\ref{functions})
+it is a dynamic type error if $o$ is not the null object (\ref{null}),
+% TODO(lrn): Remove the next line when void is a proper supertype of all types.
+$S$ is not \VOID,
+and \code{Future<$U$>} is not a subtype of $S$.
+\item Otherwise,
+it is a dynamic type error if $r$ is not the null object (\ref{null}),
+% TODO(lrn): Remove the next line when void is a proper supertype of all types.
+$S$ is not \VOID{},
+and $U$ is not a subtype of $S$.
+\end{itemize}
+
+\LMHash{}
 Executing a return statement with no expression, \code{\RETURN;} returns with no value (\ref{completion}).
 
 
@@ -9004,7 +9658,7 @@
 An assertion with a trailing comma is equivalent to one with that comma removed.
 
 \LMHash{}
-An assertion of the form \code{\ASSERT($e$))} is equivalent to an assertion of the form \code{\ASSERT($e$, \NULL{})}.
+An assertion of the form \code{\ASSERT($e$)} is equivalent to an assertion of the form \code{\ASSERT($e$, \NULL{})}.
 
 \LMHash{}
 Execution of an assert statement executes the assertion as described below
@@ -9290,7 +9944,7 @@
 then let $NS_i = \SHOW{}([\id_1, \ldots,\ \id_k], NS_{i-1}$)
 
 where $show(l,n)$ takes a list of identifiers $l$ and a namespace $n$, and produces a namespace that maps each name in $l$ to the same element that $n$ does.
-Furthermore, for each name $x$ in $l$, if $n$ defines the name $x=$ then the new namespace maps $x=$ to the same element that $n$ does.
+Furthermore, for each name $x$ in $l$, if $n$ defines the name \code{$x$=} then the new namespace maps \code{$x$=} to the same element that $n$ does.
 Otherwise the resulting mapping is undefined.
 
 \item If $C_i$ is of the form
@@ -9299,7 +9953,7 @@
 
 then let $NS_i = \HIDE{}([\id_1, \ldots,\ \id_k], NS_{i-1}$)
 
-where $hide(l, n)$ takes a list of identifiers $l$ and a namespace $n$, and produces a namespace that is identical to $n$ except that for each name $k$ in $l$, $k$ and $k=$ are undefined.
+where $hide(l, n)$ takes a list of identifiers $l$ and a namespace $n$, and produces a namespace that is identical to $n$ except that for each name $k$ in $l$, $k$ and \code{$k$=} are undefined.
 \end{itemize}
 
 \LMHash{}
@@ -9778,7 +10432,8 @@
 
 \LMHash{}
 The static type system ascribes a static type to every expression.
-In some cases, the types of local variables and formal parameters may be promoted from their declared types based on control flow.
+In some cases, the type of a local variable (\commentary{which can be a formal parameter})
+may be promoted from the declared type, based on control flow.
 
 \LMHash{}
 We say that a variable $v$ is known to have type $T$ whenever we allow the type of $v$ to be promoted.
@@ -10022,11 +10677,6 @@
 \subsection{Function Types}
 \LMLabel{functionTypes}
 
-\commentary{
-Note that the non-generic case is covered by using $s = 0$,
-in which case the type parameter declarations are omitted (\ref{generics}).
-}
-
 \LMHash{}
 Function types come in two variants:
 \begin{enumerate}
@@ -10046,15 +10696,10 @@
 \code{($T_1, \ldots,\ T_n,\ $\{$T_{x_1}\ x_1, \ldots,\ T_{x_k}\ x_k$\}) $ \rightarrow T$}.
 \end{enumerate}
 
-%$(T_1, \ldots, T_n) \rightarrow T$ is a subtype of  $(S_1, \ldots, S_n, ) \rightarrow S$, if all of the following conditions are met:
-%\begin{enumerate}
-%\item Either
-%\begin{itemize}
-%\item $S$ is \VOID{}, Or
-%\item $T \Longleftrightarrow S$.
-%\end{itemize}
-%\item$ \forall i \in 1 .. n, T_i \Longleftrightarrow S_i$.
-%\end{enumerate}
+\commentary{
+Note that the non-generic case is covered by using $s = 0$,
+in which case the type parameter declarations are omitted (\ref{generics}).
+}
 
 \LMHash{}
 Two function types are considered equal if consistent renaming of type
@@ -10063,7 +10708,9 @@
 \commentary{
 A common way to say this is that we do not distinguish function types which are alpha-equivalent.
 For the subtyping rule below this means we can assume that a suitable renaming has already taken place.
-In cases where this is not possible because the number of type parameters in the two types differ or the bounds are different, no subtype relationship exists.
+In cases where this is not possible
+because the number of type parameters in the two types differ or the bounds are different,
+no subtype relationship exists.
 }
 
 \LMHash{}
diff --git a/docs/language/informal/README.md b/docs/language/informal/README.md
index ed534fb..cd6c9f0 100644
--- a/docs/language/informal/README.md
+++ b/docs/language/informal/README.md
@@ -1,21 +1,29 @@
-This directory contains "informal specifications".
+### This directory contains feature specifications.
 
-**Note**: This directory is no longer where new language proposals are
-discussed. Instead, new language proposals should be submitted to
-[dart-lang/language](https://github.com/dart-lang/language).
+**Note**: This directory contains older feature specifications, new ones
+should be submitted to the language repository
+[here](https://github.com/dart-lang/language).
+
+The existing feature specifications in this directory will have their status
+updated as we proceed, and in particular each of them will become 'background'
+material as it is integrated into the language specification. When all feature
+specifications in this directory (that is, all other files than this one) have
+become background material, this directory will serve only as documentation for
+the process whereby each feature was designed and the associated motivation.
+
+That said, the following section contains a few words about what a feature
+specification is, and how it can be used.
+
+### What is a Feature Specification?
 
 In order to move faster and get better feedback, we implement and iterate on
 language changes before the full official specification has been written. Still,
 the implementers need *something* to go on.
 
-For that, the language team writes "informal specifications". These are
+For that, the language team writes _feature specifications_. These are
 intended to be precise enough for a good faith implementer to correctly
-understand the syntax and semantics of the language, but without all of the
-laborious detail of the complete specification.
-
-Once the feature has been implemented, tested, and we are confident in it, the
-language team will write the real text in the language specification and the
-document here becomes deprecated and no longer canonical.
-
-Until then, while the feature is in progress, a live pull request for the
-informal spec is the source of truth for the feature.
+understand the syntax and semantics of the language, but when the contents
+of a feature specification is integrated into the language specification we
+expect the extra processing to give rise to additional clarifications and
+corrections, which means that a feature specification is expected to be 
+_nearly_ as complete and correct as the language specification.
diff --git a/docs/language/informal/dynamic-members.md b/docs/language/informal/dynamic-members.md
index bf53190..07a8371 100644
--- a/docs/language/informal/dynamic-members.md
+++ b/docs/language/informal/dynamic-members.md
@@ -4,7 +4,7 @@
 
 **Version**: 0.2 (2018-09-04)
 
-**Status**: Under discussion.
+**Status**: Under implementation.
 
 **This document** is a Dart 2 feature specification of the static typing
 of instance members of a receiver whose static type is `dynamic`.
diff --git a/docs/language/informal/extreme-upper-lower-bounds.md b/docs/language/informal/extreme-upper-lower-bounds.md
index 93babb8..982dc4d 100644
--- a/docs/language/informal/extreme-upper-lower-bounds.md
+++ b/docs/language/informal/extreme-upper-lower-bounds.md
@@ -2,7 +2,7 @@
 
 **Owner**: eernst@
 
-**Status**: Under discussion.
+**Status**: Implemented.
 
 **Version**: 0.2 (2018-05-22)
 
diff --git a/docs/language/informal/generalized-void.md b/docs/language/informal/generalized-void.md
index ee59185..e3ae956 100644
--- a/docs/language/informal/generalized-void.md
+++ b/docs/language/informal/generalized-void.md
@@ -4,7 +4,7 @@
 
 **Version**: 0.10 (2018-07-10)
 
-**Status**: Under implementation.
+**Status**: Implemented.
 
 **This document** is a feature specification of the generalized support
 in Dart 2 for the type `void`.
diff --git a/docs/language/informal/generic-function-instantiation.md b/docs/language/informal/generic-function-instantiation.md
index d9ee68b..50098c2 100644
--- a/docs/language/informal/generic-function-instantiation.md
+++ b/docs/language/informal/generic-function-instantiation.md
@@ -4,7 +4,7 @@
 
 Version: 0.3 (2018-04-05)
 
-Status: Under discussion.
+Status: Under implementation.
 
 **This document** is a Dart 2 feature specification of _generic function
 instantiation_, which is the feature that implicitly coerces a reference to
diff --git a/docs/language/informal/implicit-creation.md b/docs/language/informal/implicit-creation.md
index d5fe36e..dfa46e1 100644
--- a/docs/language/informal/implicit-creation.md
+++ b/docs/language/informal/implicit-creation.md
@@ -4,7 +4,7 @@
 
 Version: 0.7 (2018-04-10)
 
-Status: Under implementation.
+Status: Implemented.
 
 **This document** is an informal specification of the *implicit creation*
 feature. **The feature** adds support for omitting some occurrences of the
diff --git a/docs/language/informal/instantiate-to-bound.md b/docs/language/informal/instantiate-to-bound.md
index 091c507..a847a39 100644
--- a/docs/language/informal/instantiate-to-bound.md
+++ b/docs/language/informal/instantiate-to-bound.md
@@ -4,7 +4,7 @@
 
 **Version**: 0.7 (2018-02-26)
 
-**Status**: Under implementation.
+**Status**: Implemented.
 
 Based on [this description](https://github.com/dart-lang/sdk/issues/27526#issuecomment-260021397) by leafp@.
 
diff --git a/docs/language/informal/int-to-double.md b/docs/language/informal/int-to-double.md
index d9cd340..c873a47 100644
--- a/docs/language/informal/int-to-double.md
+++ b/docs/language/informal/int-to-double.md
@@ -2,7 +2,7 @@
 
 **Author**: eernst@.
 
-**Version**: 0.4 (2018-08-14).
+**Version**: 0.5 (2018-09-12).
 
 **Status**: Background material, in language specification as of
 [d14b256](https://github.com/dart-lang/sdk/commit/d14b256e351464db352f361f1206e1415db65d9c).
@@ -91,12 +91,12 @@
 to add a specific, finite number of zeros.*
 
 *Consequently,
-`double d = 18446744073709551614;`
+`double d = 18446744073709551616;`
 has no error and it will initialize `d` to have the double value
 represented as 0x43F0000000000000. But
-`int i = 18446744073709551614;`
-is a compile-time error because 18446744073709551614 is too large to be
-represented as a 64 bit 2's complement number, and
+`int i = 18446744073709551616;`
+is a compile-time error because 18446744073709551616 is too large to be
+represented as a 64-bit 2's complement number, and
 `double d = 18446744073709551615;`
 is a compile-time error because it cannot be represented exactly using the
 IEEE 754 double-precision format.*
@@ -171,6 +171,7 @@
 
 
 ## Updates
+*   Version 0.5 (2018-09-12), Fix typo
 
 *   Version 0.4 (2018-08-14), adjusted rules to allow more expected types,
     such as `FutureOr<double>`, for double valued integer literals.
diff --git a/docs/language/informal/int64.md b/docs/language/informal/int64.md
index 4bf67d5..20d89ab 100644
--- a/docs/language/informal/int64.md
+++ b/docs/language/informal/int64.md
@@ -5,7 +5,7 @@
 
 **Version**: 2017-09-26.
 
-**Status**: Under implementation.
+**Status**: Implemented.
 
 This document discusses Dart's plan to switch the `int` type so that it represents 64-bit integers instead of bigints. It is part of our continued effort of changing the integer type to fixed size ([issue]).
 
diff --git a/docs/language/informal/invalid_returns.md b/docs/language/informal/invalid_returns.md
index 0dbf0e2..89215f6 100644
--- a/docs/language/informal/invalid_returns.md
+++ b/docs/language/informal/invalid_returns.md
@@ -1,11 +1,16 @@
 # Dart 2 function return checking
 
-leafp@google.com
+**Owner**: leafp@google.com
+
+**Status**: Implemented.
+
+Status: Ready for implementation
 
 **Note: Also see alternative presentation at the bottom for a dual presentation
 of these rules in terms of which things are errors, rather than which things are
 valid*.*
 
+
 ## Errors for sync and async function return values in Dart 2
 
 ### Expression bodied functions
diff --git a/docs/language/informal/mixin-declaration.md b/docs/language/informal/mixin-declaration.md
index bc21ce1..0521fc9 100644
--- a/docs/language/informal/mixin-declaration.md
+++ b/docs/language/informal/mixin-declaration.md
@@ -1,3 +1,5 @@
 # Dart 2 Mixin Declarations 
 
+**Status**: This is now background material.
+
 ## The canonical version of this document now resides [here](https://github.com/dart-lang/language/blob/master/working/0006.%20Super-invocations%20in%20mixins/0007.%20Mixin%20declarations/lrhn-strawman.md).
diff --git a/docs/language/informal/mixin-inference.md b/docs/language/informal/mixin-inference.md
index 5972c27..fa424af 100644
--- a/docs/language/informal/mixin-inference.md
+++ b/docs/language/informal/mixin-inference.md
@@ -1,8 +1,11 @@
 # Dart 2.X super mixin inference proposal
 
-leafp@google.com
+**Owner**: leafp@google.com
 
-Status: Draft
+**Status**: This is now background material.
+
+The current version of this document now resides
+[here](https://github.com/dart-lang/language/blob/master/working/0006.%20Super-invocations%20in%20mixins/0007.%20Mixin%20declarations/mixin-inference.md).
 
 This is intended to define a prototype approach to supporting inference of type
 arguments in super-mixin applications.  This is not an official part of Dart
diff --git a/docs/language/informal/nosuchmethod-forwarding.md b/docs/language/informal/nosuchmethod-forwarding.md
index e6d0fc8..68d1153 100644
--- a/docs/language/informal/nosuchmethod-forwarding.md
+++ b/docs/language/informal/nosuchmethod-forwarding.md
@@ -2,7 +2,7 @@
 
 Author: eernst@
 
-**Status**: Under implementation.
+**Status**: Implemented.
 
 **Version**: 0.7 (2018-07-10)
 
diff --git a/docs/language/informal/subtyping.md b/docs/language/informal/subtyping.md
index 20aa5aa..64c0f29 100644
--- a/docs/language/informal/subtyping.md
+++ b/docs/language/informal/subtyping.md
@@ -2,7 +2,7 @@
 
 leafp@google.com
 
-Status: Draft
+**Status**: Implemented.
 
 This is intended to define the core of the Dart 2.0 static and runtime subtyping
 relation.
diff --git a/pkg/analysis_server/lib/src/computer/computer_highlights.dart b/pkg/analysis_server/lib/src/computer/computer_highlights.dart
index 7805799..b0b5d40 100644
--- a/pkg/analysis_server/lib/src/computer/computer_highlights.dart
+++ b/pkg/analysis_server/lib/src/computer/computer_highlights.dart
@@ -463,6 +463,12 @@
   }
 
   @override
+  Object visitExtendsClause(ExtendsClause node) {
+    computer._addRegion_token(node.extendsKeyword, HighlightRegionType.KEYWORD);
+    return super.visitExtendsClause(node);
+  }
+
+  @override
   Object visitFieldDeclaration(FieldDeclaration node) {
     computer._addRegion_token(node.staticKeyword, HighlightRegionType.BUILT_IN);
     return super.visitFieldDeclaration(node);
@@ -595,6 +601,12 @@
   }
 
   @override
+  Object visitMixinDeclaration(MixinDeclaration node) {
+    computer._addRegion_token(node.mixinKeyword, HighlightRegionType.BUILT_IN);
+    return super.visitMixinDeclaration(node);
+  }
+
+  @override
   Object visitNativeClause(NativeClause node) {
     computer._addRegion_token(node.nativeKeyword, HighlightRegionType.BUILT_IN);
     return super.visitNativeClause(node);
@@ -607,6 +619,12 @@
   }
 
   @override
+  Object visitOnClause(OnClause node) {
+    computer._addRegion_token(node.onKeyword, HighlightRegionType.BUILT_IN);
+    return super.visitOnClause(node);
+  }
+
+  @override
   Object visitPartDirective(PartDirective node) {
     computer._addRegion_node(node, HighlightRegionType.DIRECTIVE);
     computer._addRegion_token(node.keyword, HighlightRegionType.BUILT_IN);
diff --git a/pkg/analysis_server/lib/src/computer/computer_highlights2.dart b/pkg/analysis_server/lib/src/computer/computer_highlights2.dart
index e14dcda..dad226c 100644
--- a/pkg/analysis_server/lib/src/computer/computer_highlights2.dart
+++ b/pkg/analysis_server/lib/src/computer/computer_highlights2.dart
@@ -554,6 +554,12 @@
   }
 
   @override
+  Object visitExtendsClause(ExtendsClause node) {
+    computer._addRegion_token(node.extendsKeyword, HighlightRegionType.KEYWORD);
+    return super.visitExtendsClause(node);
+  }
+
+  @override
   Object visitFieldDeclaration(FieldDeclaration node) {
     computer._addRegion_token(node.staticKeyword, HighlightRegionType.BUILT_IN);
     return super.visitFieldDeclaration(node);
@@ -692,6 +698,12 @@
   }
 
   @override
+  Object visitMixinDeclaration(MixinDeclaration node) {
+    computer._addRegion_token(node.mixinKeyword, HighlightRegionType.BUILT_IN);
+    return super.visitMixinDeclaration(node);
+  }
+
+  @override
   Object visitNativeClause(NativeClause node) {
     computer._addRegion_token(node.nativeKeyword, HighlightRegionType.BUILT_IN);
     return super.visitNativeClause(node);
@@ -704,6 +716,12 @@
   }
 
   @override
+  Object visitOnClause(OnClause node) {
+    computer._addRegion_token(node.onKeyword, HighlightRegionType.BUILT_IN);
+    return super.visitOnClause(node);
+  }
+
+  @override
   Object visitPartDirective(PartDirective node) {
     computer._addRegion_node(node, HighlightRegionType.DIRECTIVE);
     computer._addRegion_token(node.keyword, HighlightRegionType.BUILT_IN);
diff --git a/pkg/analysis_server/lib/src/edit/edit_domain.dart b/pkg/analysis_server/lib/src/edit/edit_domain.dart
index 80cb8d2..221af2e 100644
--- a/pkg/analysis_server/lib/src/edit/edit_domain.dart
+++ b/pkg/analysis_server/lib/src/edit/edit_domain.dart
@@ -1017,19 +1017,13 @@
           }
         }
 
-        // Canonicalize to ConstructorName.
-        var constructorName = _canonicalizeToConstructorName(node);
-        if (constructorName != null) {
-          node = constructorName;
-          element = constructorName.staticElement;
-          // Use the constructor name offset/length.
-          if (constructorName.name != null) {
-            feedbackOffset = constructorName.name.offset;
-            feedbackLength = constructorName.name.length;
-          } else {
-            feedbackOffset = -1;
-            feedbackLength = 0;
-          }
+        // Rename the class when on `new` in an instance creation.
+        if (node is InstanceCreationExpression) {
+          InstanceCreationExpression creation = node;
+          var typeIdentifier = creation.constructorName.type.name;
+          element = typeIdentifier.staticElement;
+          feedbackOffset = typeIdentifier.offset;
+          feedbackLength = typeIdentifier.length;
         }
 
         // do create the refactoring
@@ -1177,32 +1171,6 @@
     }
     return new RefactoringStatus();
   }
-
-  /**
-   * If the [node] is a constructor reference, return the corresponding
-   * [ConstructorName], or `null` otherwise.
-   */
-  static ConstructorName _canonicalizeToConstructorName(AstNode node) {
-    var parent = node.parent;
-    var parent2 = parent?.parent;
-
-    // "named" in "Class.named".
-    if (parent is ConstructorName) {
-      return parent;
-    }
-
-    // "Class" in "Class.named".
-    if (parent is TypeName && parent2 is ConstructorName) {
-      return parent2;
-    }
-
-    // Canonicalize "new Class.named()" to "Class.named".
-    if (node is InstanceCreationExpression) {
-      return node.constructorName;
-    }
-
-    return null;
-  }
 }
 
 /**
diff --git a/pkg/analysis_server/lib/src/services/correction/assist.dart b/pkg/analysis_server/lib/src/services/correction/assist.dart
index 5e797f0..1b98a13 100644
--- a/pkg/analysis_server/lib/src/services/correction/assist.dart
+++ b/pkg/analysis_server/lib/src/services/correction/assist.dart
@@ -12,6 +12,8 @@
       'dart.assist.addTypeAnnotation', 30, "Add type annotation");
   static const ASSIGN_TO_LOCAL_VARIABLE = const AssistKind(
       'dart.assist.assignToVariable', 30, "Assign value to new local variable");
+  static const CONVERT_CLASS_TO_MIXIN = const AssistKind(
+      'dart.assist.convert.classToMixin', 30, "Convert class to a mixin");
   static const CONVERT_DOCUMENTATION_INTO_BLOCK = const AssistKind(
       'dart.assist.convert.blockComment',
       30,
diff --git a/pkg/analysis_server/lib/src/services/correction/assist_internal.dart b/pkg/analysis_server/lib/src/services/correction/assist_internal.dart
index 4768ba4..2dad5df 100644
--- a/pkg/analysis_server/lib/src/services/correction/assist_internal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/assist_internal.dart
@@ -127,6 +127,7 @@
     await _addProposal_addTypeAnnotation_SimpleFormalParameter();
     await _addProposal_addTypeAnnotation_VariableDeclaration();
     await _addProposal_assignToLocalVariable();
+    await _addProposal_convertClassToMixin();
     await _addProposal_convertIntoFinalField();
     await _addProposal_convertIntoGetter();
     await _addProposal_convertDocumentationIntoBlock();
@@ -431,6 +432,60 @@
     }
   }
 
+  Future<void> _addProposal_convertClassToMixin() async {
+    ClassDeclaration classDeclaration =
+        node.getAncestor((n) => n is ClassDeclaration);
+    if (classDeclaration == null) {
+      return;
+    }
+    if (selectionOffset > classDeclaration.name.end ||
+        selectionEnd < classDeclaration.classKeyword.offset) {
+      return;
+    }
+    if (classDeclaration.members
+        .any((member) => member is ConstructorDeclaration)) {
+      return;
+    }
+    _SuperclassReferenceFinder finder = new _SuperclassReferenceFinder();
+    classDeclaration.accept(finder);
+    List<ClassElement> referencedClasses = finder.referencedClasses;
+    List<InterfaceType> superclassConstraints = <InterfaceType>[];
+    List<InterfaceType> interfaces = <InterfaceType>[];
+
+    ClassElement classElement = classDeclaration.declaredElement;
+    for (InterfaceType type in classElement.mixins) {
+      if (referencedClasses.contains(type.element)) {
+        superclassConstraints.add(type);
+      } else {
+        interfaces.add(type);
+      }
+    }
+    ExtendsClause extendsClause = classDeclaration.extendsClause;
+    if (extendsClause != null) {
+      if (referencedClasses.length > superclassConstraints.length) {
+        superclassConstraints.insert(0, classElement.supertype);
+      } else {
+        interfaces.insert(0, classElement.supertype);
+      }
+    }
+    interfaces.addAll(classElement.interfaces);
+
+    DartChangeBuilder changeBuilder = new DartChangeBuilder(session);
+    await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
+      builder.addReplacement(
+          range.startStart(
+              classDeclaration.classKeyword, classDeclaration.leftBracket),
+          (DartEditBuilder builder) {
+        builder.write('mixin ');
+        builder.write(classDeclaration.name.name);
+        builder.writeTypes(superclassConstraints, prefix: ' on ');
+        builder.writeTypes(interfaces, prefix: ' implements ');
+        builder.write(' ');
+      });
+    });
+    _addAssistFromBuilder(changeBuilder, DartAssistKind.CONVERT_CLASS_TO_MIXIN);
+  }
+
   Future<void> _addProposal_convertDocumentationIntoBlock() async {
     // TODO(brianwilkerson) Determine whether this await is necessary.
     await null;
@@ -3386,3 +3441,43 @@
     visitor(node);
   }
 }
+
+/**
+ * A visitor used to find all of the classes that define members referenced via
+ * `super`.
+ */
+class _SuperclassReferenceFinder extends RecursiveAstVisitor {
+  final List<ClassElement> referencedClasses = <ClassElement>[];
+
+  _SuperclassReferenceFinder();
+
+  @override
+  visitSuperExpression(SuperExpression node) {
+    AstNode parent = node.parent;
+    if (parent is BinaryExpression) {
+      _addElement(parent.staticElement);
+    } else if (parent is IndexExpression) {
+      _addElement(parent.staticElement);
+    } else if (parent is MethodInvocation) {
+      _addIdentifier(parent.methodName);
+    } else if (parent is PrefixedIdentifier) {
+      _addIdentifier(parent.identifier);
+    } else if (parent is PropertyAccess) {
+      _addIdentifier(parent.propertyName);
+    }
+    return super.visitSuperExpression(node);
+  }
+
+  void _addElement(Element element) {
+    if (element is ExecutableElement) {
+      Element enclosingElement = element.enclosingElement;
+      if (enclosingElement is ClassElement) {
+        referencedClasses.add(enclosingElement);
+      }
+    }
+  }
+
+  void _addIdentifier(SimpleIdentifier identifier) {
+    _addElement(identifier.staticElement);
+  }
+}
diff --git a/pkg/analysis_server/lib/src/services/correction/fix.dart b/pkg/analysis_server/lib/src/services/correction/fix.dart
index 769d2ca..dca6f25 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix.dart
@@ -42,6 +42,7 @@
     errorCode == StaticWarningCode.UNDEFINED_IDENTIFIER ||
     errorCode ==
         CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE ||
+    errorCode == CompileTimeErrorCode.INTEGER_LITERAL_IMPRECISE_AS_DOUBLE ||
     errorCode == CompileTimeErrorCode.INVALID_ANNOTATION ||
     errorCode == CompileTimeErrorCode.NO_DEFAULT_SUPER_CONSTRUCTOR_EXPLICIT ||
     errorCode == CompileTimeErrorCode.PART_OF_NON_PART ||
@@ -116,6 +117,10 @@
       50,
       "Add super constructor {0} invocation");
   static const CHANGE_TO = const FixKind('CHANGE_TO', 49, "Change to '{0}'");
+  static const CHANGE_TO_NEAREST_PRECISE_VALUE = const FixKind(
+      'CHANGE_TO_NEAREST_PRECISE_VALUE',
+      50,
+      'Change to nearest precise int-as-double value: {0}');
   static const CHANGE_TO_STATIC_ACCESS = const FixKind(
       'CHANGE_TO_STATIC_ACCESS', 50, "Change access to static using '{0}'");
   static const CHANGE_TYPE_ANNOTATION = const FixKind(
@@ -148,6 +153,8 @@
       const FixKind('CREATE_METHOD', 50, "Create method '{0}'");
   static const CREATE_MISSING_OVERRIDES = const FixKind(
       'CREATE_MISSING_OVERRIDES', 49, "Create {0} missing override(s)");
+  static const CREATE_MIXIN =
+      const FixKind('CREATE_MIXIN', 50, "Create mixin '{0}'");
   static const CREATE_NO_SUCH_METHOD = const FixKind(
       'CREATE_NO_SUCH_METHOD', 51, "Create 'noSuchMethod' method");
   static const CONVERT_TO_NAMED_ARGUMENTS = const FixKind(
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 0d9e95b..869e3b6 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
@@ -29,6 +29,7 @@
 import 'package:analyzer/src/dart/analysis/driver.dart';
 import 'package:analyzer/src/dart/analysis/session_helper.dart';
 import 'package:analyzer/src/dart/analysis/top_level_declaration.dart';
+import 'package:analyzer/src/dart/ast/ast.dart';
 import 'package:analyzer/src/dart/ast/token.dart';
 import 'package:analyzer/src/dart/ast/utilities.dart';
 import 'package:analyzer/src/dart/element/ast_provider.dart';
@@ -307,6 +308,10 @@
         errorCode == StaticWarningCode.UNDEFINED_IDENTIFIER_AWAIT) {
       await _addFix_addAsync();
     }
+    if (errorCode == CompileTimeErrorCode.INTEGER_LITERAL_IMPRECISE_AS_DOUBLE) {
+      await _addFix_changeToNearestPreciseValue();
+    }
+
     if (errorCode == CompileTimeErrorCode.INVALID_ANNOTATION ||
         errorCode == CompileTimeErrorCode.UNDEFINED_ANNOTATION) {
       if (node is Annotation) {
@@ -438,6 +443,7 @@
         errorCode == StaticWarningCode.UNDEFINED_CLASS) {
       await _addFix_importLibrary_withType();
       await _addFix_createClass();
+      await _addFix_createMixin();
       await _addFix_undefinedClass_useSimilar();
     }
     if (errorCode ==
@@ -461,6 +467,7 @@
       await _addFix_createField();
       await _addFix_createGetter();
       await _addFix_createFunction_forFunctionType();
+      await _addFix_createMixin();
       await _addFix_importLibrary_withType();
       await _addFix_importLibrary_withTopLevelVariable();
       await _addFix_createLocalVariable();
@@ -492,6 +499,7 @@
     if (errorCode == StaticTypeWarningCode.NON_TYPE_AS_TYPE_ARGUMENT) {
       await _addFix_importLibrary_withType();
       await _addFix_createClass();
+      await _addFix_createMixin();
     }
     if (errorCode == StaticTypeWarningCode.UNDEFINED_FUNCTION) {
       await _addFix_createClass();
@@ -508,6 +516,7 @@
       // TODO(brianwilkerson) The following were added because fasta produces
       // UNDEFINED_GETTER in places where analyzer produced UNDEFINED_IDENTIFIER
       await _addFix_createClass();
+      await _addFix_createMixin();
       await _addFix_createLocalVariable();
       await _addFix_importLibrary_withTopLevelVariable();
       await _addFix_importLibrary_withType();
@@ -1015,6 +1024,22 @@
     }
   }
 
+  Future<void> _addFix_changeToNearestPreciseValue() async {
+    IntegerLiteral integer = node;
+    String lexeme = integer.literal.lexeme;
+    BigInt precise = BigInt.from(IntegerLiteralImpl.nearestValidDouble(lexeme));
+    String correction = lexeme.toLowerCase().contains('x')
+        ? '0x${precise.toRadixString(16).toUpperCase()}'
+        : precise.toString();
+    DartChangeBuilder changeBuilder = new DartChangeBuilder(session);
+    await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
+      builder.addSimpleReplacement(range.node(integer), correction);
+    });
+    _addFixFromBuilder(
+        changeBuilder, DartFixKind.CHANGE_TO_NEAREST_PRECISE_VALUE,
+        args: [correction]);
+  }
+
   Future<void> _addFix_changeTypeAnnotation() async {
     // TODO(brianwilkerson) Determine whether this await is necessary.
     await null;
@@ -1797,7 +1822,7 @@
       if (target is Identifier) {
         Identifier targetIdentifier = target;
         Element targetElement = targetIdentifier.staticElement;
-        staticModifier = targetElement.kind == ElementKind.CLASS;
+        staticModifier = targetElement?.kind == ElementKind.CLASS;
       }
     } else {
       targetClassElement = getEnclosingClassElement(node);
@@ -2069,6 +2094,92 @@
     utils.targetExecutableElement = null;
   }
 
+  Future<void> _addFix_createMixin() async {
+    Element prefixElement = null;
+    String name = null;
+    SimpleIdentifier nameNode;
+    if (node is SimpleIdentifier) {
+      AstNode parent = node.parent;
+      if (parent is PrefixedIdentifier) {
+        if (parent.parent is InstanceCreationExpression) {
+          return;
+        }
+        PrefixedIdentifier prefixedIdentifier = parent;
+        prefixElement = prefixedIdentifier.prefix.staticElement;
+        if (prefixElement == null) {
+          return;
+        }
+        parent = prefixedIdentifier.parent;
+        nameNode = prefixedIdentifier.identifier;
+        name = prefixedIdentifier.identifier.name;
+      } else if (parent is TypeName &&
+          parent.parent is ConstructorName &&
+          parent.parent.parent is InstanceCreationExpression) {
+        return;
+      } else {
+        nameNode = node;
+        name = nameNode.name;
+      }
+      if (!_mayBeTypeIdentifier(nameNode)) {
+        return;
+      }
+    } else {
+      return;
+    }
+    // prepare environment
+    Element targetUnit;
+    String prefix = '';
+    String suffix = '';
+    int offset = -1;
+    String filePath;
+    if (prefixElement == null) {
+      targetUnit = unitElement;
+      CompilationUnitMember enclosingMember = node.getAncestor((node) =>
+          node is CompilationUnitMember && node.parent is CompilationUnit);
+      if (enclosingMember == null) {
+        return;
+      }
+      offset = enclosingMember.end;
+      filePath = file;
+      prefix = '$eol$eol';
+    } else {
+      for (ImportElement import in unitLibraryElement.imports) {
+        if (prefixElement is PrefixElement && import.prefix == prefixElement) {
+          LibraryElement library = import.importedLibrary;
+          if (library != null) {
+            targetUnit = library.definingCompilationUnit;
+            Source targetSource = targetUnit.source;
+            try {
+              offset = targetSource.contents.data.length;
+              filePath = targetSource.fullName;
+              prefix = '$eol';
+              suffix = '$eol';
+            } on FileSystemException {
+              // If we can't read the file to get the offset, then we can't
+              // create a fix.
+            }
+            break;
+          }
+        }
+      }
+    }
+    if (offset < 0) {
+      return;
+    }
+    DartChangeBuilder changeBuilder = new DartChangeBuilder(session);
+    await changeBuilder.addFileEdit(filePath, (DartFileEditBuilder builder) {
+      builder.addInsertion(offset, (DartEditBuilder builder) {
+        builder.write(prefix);
+        builder.writeMixinDeclaration(name, nameGroupName: 'NAME');
+        builder.write(suffix);
+      });
+      if (prefixElement == null) {
+        builder.addLinkedPosition(range.node(node), 'NAME');
+      }
+    });
+    _addFixFromBuilder(changeBuilder, DartFixKind.CREATE_MIXIN, args: [name]);
+  }
+
   Future<void> _addFix_createNoSuchMethod() async {
     // TODO(brianwilkerson) Determine whether this await is necessary.
     await null;
diff --git a/pkg/analysis_server/lib/src/services/search/hierarchy.dart b/pkg/analysis_server/lib/src/services/search/hierarchy.dart
index 909f3e8..8862eda 100644
--- a/pkg/analysis_server/lib/src/services/search/hierarchy.dart
+++ b/pkg/analysis_server/lib/src/services/search/hierarchy.dart
@@ -173,6 +173,10 @@
         queue.add(superType.element);
       }
     }
+    // append superclass constraints
+    for (InterfaceType interface in current.superclassConstraints) {
+      queue.add(interface.element);
+    }
     // append interfaces
     for (InterfaceType interface in current.interfaces) {
       queue.add(interface.element);
diff --git a/pkg/analysis_server/lib/src/status/element_writer.dart b/pkg/analysis_server/lib/src/status/element_writer.dart
index fcdc776..3b6ac79 100644
--- a/pkg/analysis_server/lib/src/status/element_writer.dart
+++ b/pkg/analysis_server/lib/src/status/element_writer.dart
@@ -54,6 +54,7 @@
       properties['isProxy'] = element.isProxy;
       properties['isValidMixin'] = element.isValidMixin;
       properties['mixins'] = element.mixins;
+      properties['superclassConstraints'] = element.superclassConstraints;
       properties['supertype'] = element.supertype;
     }
     if (element is ClassMemberElement) {
diff --git a/pkg/analysis_server/test/analysis/get_hover_test.dart b/pkg/analysis_server/test/analysis/get_hover_test.dart
index e2e60a6..ac43af1 100644
--- a/pkg/analysis_server/test/analysis/get_hover_test.dart
+++ b/pkg/analysis_server/test/analysis/get_hover_test.dart
@@ -40,7 +40,7 @@
     createProject();
   }
 
-  test_class() async {
+  test_class_declaration() async {
     addTestFile('''
 class A<E> {}
 class I1<K, V> {}
@@ -58,7 +58,7 @@
     expect(hover.propagatedType, isNull);
   }
 
-  test_class_abstract() async {
+  test_class_declaration_abstract() async {
     addTestFile('''
 class A {}
 abstract class B extends A {}
@@ -69,389 +69,90 @@
     expect(hover.propagatedType, isNull);
   }
 
-  test_dartdoc_clunky() async {
+  test_constructor_named() async {
     addTestFile('''
 library my.library;
-/**
- * doc aaa
- * doc bbb
- */
-main() {
-}
-''');
-    HoverInformation hover = await prepareHover('main() {');
-    expect(hover.dartdoc, '''doc aaa\ndoc bbb''');
-  }
-
-  test_dartdoc_elegant() async {
-    addTestFile('''
-library my.library;
-/// doc aaa
-/// doc bbb
-main() {
-}
-''');
-    HoverInformation hover = await prepareHover('main() {');
-    expect(hover.dartdoc, '''doc aaa\ndoc bbb''');
-  }
-
-  test_dartdoc_inherited_methodByMethod_fromInterface() async {
-    addTestFile('''
 class A {
   /// my doc
-  m() {} // in A
-}
-
-class B implements A {
-  m() {} // in B
-}
-''');
-    HoverInformation hover = await prepareHover('m() {} // in B');
-    expect(hover.dartdoc, '''my doc\n\nCopied from `A`.''');
-  }
-
-  test_dartdoc_inherited_methodByMethod_fromSuper_direct() async {
-    addTestFile('''
-class A {
-  /// my doc
-  m() {} // in A
-}
-
-class B extends A {
-  m() {} // in B
-}
-''');
-    HoverInformation hover = await prepareHover('m() {} // in B');
-    expect(hover.dartdoc, '''my doc\n\nCopied from `A`.''');
-  }
-
-  test_dartdoc_inherited_methodByMethod_fromSuper_indirect() async {
-    addTestFile('''
-class A {
-  /// my doc
-  m() {}
-}
-class B extends A {
-  m() {}
-}
-class C extends B {
-  m() {} // in C
-}''');
-    HoverInformation hover = await prepareHover('m() {} // in C');
-    expect(hover.dartdoc, '''my doc\n\nCopied from `A`.''');
-  }
-
-  test_dartdoc_inherited_methodByMethod_preferSuper() async {
-    addTestFile('''
-class A {
-  /// my doc
-  m() {}
-}
-class B extends A {
-}
-class I {
-  // wrong doc
-  m() {}
-}
-class C extends B implements I {
-  m() {} // in C
-}''');
-    HoverInformation hover = await prepareHover('m() {} // in C');
-    expect(hover.dartdoc, '''my doc\n\nCopied from `A`.''');
-  }
-
-  test_enum() async {
-    addTestFile('''
-enum MyEnum {AAA, BBB, CCC}
-''');
-    HoverInformation hover = await prepareHover('MyEnum');
-    expect(hover.elementDescription, 'enum MyEnum');
-    expect(hover.staticType, isNull);
-    expect(hover.propagatedType, isNull);
-  }
-
-  test_expression_function() async {
-    addTestFile('''
-library my.library;
-/// doc aaa
-/// doc bbb
-List<String> fff(int a, String b) {
-}
-''');
-    HoverInformation hover = await prepareHover('fff(int a');
-    // element
-    expect(hover.containingLibraryName, 'my.library');
-    expect(hover.containingLibraryPath, testFile);
-    expect(hover.containingClassDescription, isNull);
-    expect(hover.dartdoc, '''doc aaa\ndoc bbb''');
-    expect(hover.elementDescription, 'fff(int a, String b) → List<String>');
-    expect(hover.elementKind, 'function');
-    // types
-    expect(hover.staticType, isNull);
-    expect(hover.propagatedType, isNull);
-    // no parameter
-    expect(hover.parameter, isNull);
-  }
-
-  test_expression_literal_noElement() async {
-    addTestFile('''
-main() {
-  foo(123);
-}
-foo(Object myParameter) {}
-''');
-    HoverInformation hover = await prepareHover('123');
-    // literal, no Element
-    expect(hover.containingClassDescription, isNull);
-    expect(hover.elementDescription, isNull);
-    expect(hover.elementKind, isNull);
-    // types
-    expect(hover.staticType, 'int');
-    expect(hover.propagatedType, isNull);
-    // parameter
-    expect(hover.parameter, 'Object myParameter');
-  }
-
-  test_expression_method() async {
-    addTestFile('''
-library my.library;
-class A {
-  /// doc aaa
-  /// doc bbb
-  List<String> mmm(int a, String b) {
-  }
-}
-''');
-    HoverInformation hover = await prepareHover('mmm(int a');
-    // element
-    expect(hover.containingLibraryName, 'my.library');
-    expect(hover.containingLibraryPath, testFile);
-    expect(hover.containingClassDescription, 'A');
-    expect(hover.dartdoc, '''doc aaa\ndoc bbb''');
-    expect(hover.elementDescription, 'mmm(int a, String b) → List<String>');
-    expect(hover.elementKind, 'method');
-    // types
-    expect(hover.staticType, isNull);
-    expect(hover.propagatedType, isNull);
-    // no parameter
-    expect(hover.parameter, isNull);
-  }
-
-  test_expression_method_deprecated() async {
-    addTestFile('''
-class A {
-  @deprecated
-  static void test() {}
+  A.named() {}
 }
 main() {
-  A.test();
+  new A.named();
 }
 ''');
-    HoverInformation hover = await prepareHover('test();');
-    // element
-    expect(hover.containingLibraryPath, testFile);
-    expect(hover.elementDescription, 'test() → void');
-    expect(hover.elementKind, 'method');
-    expect(hover.isDeprecated, isTrue);
+    void onConstructor(HoverInformation hover) {
+      // range
+      expect(hover.offset, findOffset('new A'));
+      expect(hover.length, 'new A.named()'.length);
+      // element
+      expect(hover.dartdoc, 'my doc');
+      expect(hover.elementDescription, 'A.named() → A');
+      expect(hover.elementKind, 'constructor');
+    }
+
+    {
+      HoverInformation hover = await prepareHover('new A');
+      onConstructor(hover);
+    }
+    {
+      HoverInformation hover = await prepareHover('named();');
+      onConstructor(hover);
+    }
   }
 
-  test_expression_method_invocation() async {
+  test_constructor_noKeyword_const() async {
     addTestFile('''
 library my.library;
 class A {
-  List<String> mmm(int a, String b) {
-  }
+  const A(int i);
 }
-main(A a) {
-  a.mmm(42, 'foo');
+main() {
+  const a = A(0);
 }
 ''');
-    HoverInformation hover = await prepareHover('mm(42, ');
+    HoverInformation hover = await prepareHover('A(0)');
     // range
-    expect(hover.offset, findOffset('mmm(42, '));
-    expect(hover.length, 'mmm'.length);
+    expect(hover.offset, findOffset('A(0)'));
+    expect(hover.length, 'A(0)'.length);
     // element
     expect(hover.containingLibraryName, 'my.library');
     expect(hover.containingLibraryPath, testFile);
-    expect(hover.elementDescription, 'mmm(int a, String b) → List<String>');
-    expect(hover.elementKind, 'method');
-    expect(hover.isDeprecated, isFalse);
+    expect(hover.dartdoc, isNull);
+    expect(hover.elementDescription, '(const) A(int i) → A');
+    expect(hover.elementKind, 'constructor');
     // types
-    expect(hover.staticType, '(int, String) → List<String>');
+    expect(hover.staticType, isNull);
     expect(hover.propagatedType, isNull);
     // no parameter
     expect(hover.parameter, isNull);
   }
 
-  test_expression_method_invocation_genericMethod() async {
+  test_constructor_noKeyword_new() async {
     addTestFile('''
 library my.library;
-
-abstract class Stream<T> {
-  Stream<S> transform<S>(StreamTransformer<T, S> streamTransformer);
-}
-abstract class StreamTransformer<T, S> {}
-
-f(Stream<int> s) {
-  s.transform(null);
+class A {}
+main() {
+  var a = A();
 }
 ''');
-    HoverInformation hover = await prepareHover('nsform(n');
+    HoverInformation hover = await prepareHover('A()');
     // range
-    expect(hover.offset, findOffset('transform(n'));
-    expect(hover.length, 'transform'.length);
+    expect(hover.offset, findOffset('A()'));
+    expect(hover.length, 'A()'.length);
     // element
     expect(hover.containingLibraryName, 'my.library');
     expect(hover.containingLibraryPath, testFile);
-    expect(hover.elementDescription,
-        'Stream.transform<S>(StreamTransformer<int, S> streamTransformer) → Stream<S>');
-    expect(hover.elementKind, 'method');
-    expect(hover.isDeprecated, isFalse);
-    // types
-    expect(hover.staticType,
-        '(StreamTransformer<int, dynamic>) → Stream<dynamic>');
-    expect(hover.propagatedType, isNull);
-    // no parameter
-    expect(hover.parameter, isNull);
-  }
-
-  test_expression_parameter() async {
-    addTestFile('''
-library my.library;
-class A {
-  /// The method documentation.
-  m(int p) {
-  }
-}
-''');
-    HoverInformation hover = await prepareHover('p) {');
-    // element
-    expect(hover.containingLibraryName, isNull);
-    expect(hover.containingLibraryPath, isNull);
-    expect(hover.containingClassDescription, isNull);
-    expect(hover.dartdoc, 'The method documentation.');
-    expect(hover.elementDescription, 'int p');
-    expect(hover.elementKind, 'parameter');
-    // types
-    expect(hover.staticType, 'int');
-    expect(hover.propagatedType, isNull);
-    // no parameter
-    expect(hover.parameter, isNull);
-  }
-
-  test_expression_parameter_fieldFormal_declaration() async {
-    addTestFile('''
-class A {
-  /// The field documentation.
-  final int fff;
-  A({this.fff});
-}
-main() {
-  new A(fff: 42);
-}
-''');
-    HoverInformation hover = await prepareHover('fff});');
-    expect(hover.containingLibraryName, isNull);
-    expect(hover.containingLibraryPath, isNull);
-    expect(hover.containingClassDescription, isNull);
-    expect(hover.dartdoc, 'The field documentation.');
-    expect(hover.elementDescription, '{int fff}');
-    expect(hover.elementKind, 'parameter');
-    expect(hover.staticType, 'int');
-  }
-
-  test_expression_parameter_fieldFormal_use() async {
-    addTestFile('''
-class A {
-  /// The field documentation.
-  final int fff;
-  A({this.fff});
-}
-main() {
-  new A(fff: 42);
-}
-''');
-    HoverInformation hover = await prepareHover('fff: 42');
-    expect(hover.containingLibraryName, isNull);
-    expect(hover.containingLibraryPath, isNull);
-    expect(hover.containingClassDescription, isNull);
-    expect(hover.dartdoc, 'The field documentation.');
-    expect(hover.elementDescription, '{int fff}');
-    expect(hover.elementKind, 'parameter');
-    expect(hover.staticType, 'int');
-  }
-
-  test_expression_syntheticGetter_invocation() async {
-    addTestFile('''
-library my.library;
-class A {
-  /// doc aaa
-  /// doc bbb
-  String fff;
-}
-main(A a) {
-  print(a.fff);
-}
-''');
-    HoverInformation hover = await prepareHover('fff);');
-    // element
-    expect(hover.containingLibraryName, 'my.library');
-    expect(hover.containingLibraryPath, testFile);
-    expect(hover.containingClassDescription, 'A');
-    expect(hover.dartdoc, '''doc aaa\ndoc bbb''');
-    expect(hover.elementDescription, 'String fff');
-    expect(hover.elementKind, 'field');
-    // types
-    expect(hover.staticType, 'String');
-    expect(hover.propagatedType, isNull);
-  }
-
-  test_expression_variable_hasPropagatedType() async {
-    addTestFile('''
-library my.library;
-main() {
-  var vvv = 123;
-  print(vvv);
-}
-''');
-    HoverInformation hover = await prepareHover('vvv);');
-    // element
-    expect(hover.containingLibraryName, isNull);
-    expect(hover.containingLibraryPath, isNull);
-    expect(hover.containingClassDescription, isNull);
     expect(hover.dartdoc, isNull);
-    expect(hover.elementDescription, 'int vvv');
-    expect(hover.elementKind, 'local variable');
+    expect(hover.elementDescription, '(new) A() → A');
+    expect(hover.elementKind, 'constructor');
     // types
-    expect(hover.staticType, 'int');
-    expect(hover.propagatedType, null);
-  }
-
-  test_expression_variable_inMethod() async {
-    addTestFile('''
-library my.library;
-class A {
-  m() {
-    num vvv = 42;
-  }
-}
-''');
-    HoverInformation hover = await prepareHover('vvv = 42');
-    // element
-    expect(hover.containingLibraryName, isNull);
-    expect(hover.containingLibraryPath, isNull);
-    expect(hover.containingClassDescription, isNull);
-    expect(hover.dartdoc, isNull);
-    expect(hover.elementDescription, 'num vvv');
-    expect(hover.elementKind, 'local variable');
-    // types
-    expect(hover.staticType, 'num');
-    expect(hover.propagatedType, null);
+    expect(hover.staticType, isNull);
+    expect(hover.propagatedType, isNull);
     // no parameter
     expect(hover.parameter, isNull);
   }
 
-  test_instanceCreation_implicit() async {
+  test_constructor_synthetic() async {
     addTestFile('''
 library my.library;
 class A {
@@ -477,7 +178,7 @@
     expect(hover.parameter, isNull);
   }
 
-  test_instanceCreation_implicit_withTypeArgument() async {
+  test_constructor_synthetic_withTypeArgument() async {
     addTestFile('''
 library my.library;
 class A<T> {}
@@ -518,57 +219,266 @@
     }
   }
 
-  test_instanceCreation_named() async {
+  test_dartdoc_block() async {
     addTestFile('''
-library my.library;
+/**
+ * doc aaa
+ * doc bbb
+ */
+main() {
+}
+''');
+    HoverInformation hover = await prepareHover('main() {');
+    expect(hover.dartdoc, '''doc aaa\ndoc bbb''');
+  }
+
+  test_dartdoc_inherited_fromInterface() async {
+    addTestFile('''
 class A {
   /// my doc
-  A.named() {}
+  m() {} // in A
 }
-main() {
-  new A.named();
+
+class B implements A {
+  m() {} // in B
 }
 ''');
-    void onConstructor(HoverInformation hover) {
-      // range
-      expect(hover.offset, findOffset('new A'));
-      expect(hover.length, 'new A.named()'.length);
-      // element
-      expect(hover.dartdoc, 'my doc');
-      expect(hover.elementDescription, 'A.named() → A');
-      expect(hover.elementKind, 'constructor');
-    }
-
-    {
-      HoverInformation hover = await prepareHover('new A');
-      onConstructor(hover);
-    }
-    {
-      HoverInformation hover = await prepareHover('named();');
-      onConstructor(hover);
-    }
+    HoverInformation hover = await prepareHover('m() {} // in B');
+    expect(hover.dartdoc, '''my doc\n\nCopied from `A`.''');
   }
 
-  test_instanceCreation_noKeyword_const() async {
+  test_dartdoc_inherited_fromSuper_direct() async {
+    addTestFile('''
+class A {
+  /// my doc
+  m() {} // in A
+}
+
+class B extends A {
+  m() {} // in B
+}
+''');
+    HoverInformation hover = await prepareHover('m() {} // in B');
+    expect(hover.dartdoc, '''my doc\n\nCopied from `A`.''');
+  }
+
+  test_dartdoc_inherited_fromSuper_indirect() async {
+    addTestFile('''
+class A {
+  /// my doc
+  m() {}
+}
+class B extends A {
+  m() {}
+}
+class C extends B {
+  m() {} // in C
+}''');
+    HoverInformation hover = await prepareHover('m() {} // in C');
+    expect(hover.dartdoc, '''my doc\n\nCopied from `A`.''');
+  }
+
+  test_dartdoc_inherited_preferSuper() async {
+    addTestFile('''
+class A {
+  /// my doc
+  m() {}
+}
+class B extends A {
+}
+class I {
+  // wrong doc
+  m() {}
+}
+class C extends B implements I {
+  m() {} // in C
+}''');
+    HoverInformation hover = await prepareHover('m() {} // in C');
+    expect(hover.dartdoc, '''my doc\n\nCopied from `A`.''');
+  }
+
+  test_dartdoc_line() async {
+    addTestFile('''
+/// doc aaa
+/// doc bbb
+main() {
+}
+''');
+    HoverInformation hover = await prepareHover('main() {');
+    expect(hover.dartdoc, '''doc aaa\ndoc bbb''');
+  }
+
+  test_enum_declaration() async {
+    addTestFile('''
+enum MyEnum {AAA, BBB, CCC}
+''');
+    HoverInformation hover = await prepareHover('MyEnum');
+    expect(hover.elementDescription, 'enum MyEnum');
+    expect(hover.staticType, isNull);
+    expect(hover.propagatedType, isNull);
+  }
+
+  test_function_topLevel_declaration() async {
+    addTestFile('''
+library my.library;
+/// doc aaa
+/// doc bbb
+List<String> fff(int a, String b) {
+}
+''');
+    HoverInformation hover = await prepareHover('fff(int a');
+    // element
+    expect(hover.containingLibraryName, 'my.library');
+    expect(hover.containingLibraryPath, testFile);
+    expect(hover.containingClassDescription, isNull);
+    expect(hover.dartdoc, '''doc aaa\ndoc bbb''');
+    expect(hover.elementDescription, 'fff(int a, String b) → List<String>');
+    expect(hover.elementKind, 'function');
+    // types
+    expect(hover.staticType, isNull);
+    expect(hover.propagatedType, isNull);
+    // no parameter
+    expect(hover.parameter, isNull);
+  }
+
+  test_getter_synthetic() async {
     addTestFile('''
 library my.library;
 class A {
-  const A(int i);
+  /// doc aaa
+  /// doc bbb
+  String fff;
 }
-main() {
-  const a = A(0);
+main(A a) {
+  print(a.fff);
 }
 ''');
-    HoverInformation hover = await prepareHover('A(0)');
-    // range
-    expect(hover.offset, findOffset('A(0)'));
-    expect(hover.length, 'A(0)'.length);
+    HoverInformation hover = await prepareHover('fff);');
     // element
     expect(hover.containingLibraryName, 'my.library');
     expect(hover.containingLibraryPath, testFile);
+    expect(hover.containingClassDescription, 'A');
+    expect(hover.dartdoc, '''doc aaa\ndoc bbb''');
+    expect(hover.elementDescription, 'String fff');
+    expect(hover.elementKind, 'field');
+    // types
+    expect(hover.staticType, 'String');
+    expect(hover.propagatedType, isNull);
+  }
+
+  test_integerLiteral() async {
+    addTestFile('''
+main() {
+  foo(123);
+}
+foo(Object myParameter) {}
+''');
+    HoverInformation hover = await prepareHover('123');
+    // range
+    expect(hover.offset, findOffset('123'));
+    expect(hover.length, 3);
+    // element
+    expect(hover.containingClassDescription, isNull);
+    expect(hover.containingLibraryName, isNull);
+    expect(hover.containingLibraryPath, isNull);
     expect(hover.dartdoc, isNull);
-    expect(hover.elementDescription, '(const) A(int i) → A');
-    expect(hover.elementKind, 'constructor');
+    expect(hover.elementDescription, isNull);
+    expect(hover.elementKind, isNull);
+    // types
+    expect(hover.staticType, 'int');
+    expect(hover.propagatedType, isNull);
+    // parameter
+    expect(hover.parameter, 'Object myParameter');
+  }
+
+  test_integerLiteral_promoted() async {
+    addTestFile('''
+main() {
+  foo(123);
+}
+foo(double myParameter) {}
+''');
+    HoverInformation hover = await prepareHover('123');
+    // range
+    expect(hover.offset, findOffset('123'));
+    expect(hover.length, 3);
+    // element
+    expect(hover.containingClassDescription, isNull);
+    expect(hover.containingLibraryName, isNull);
+    expect(hover.containingLibraryPath, isNull);
+    expect(hover.dartdoc, isNull);
+    expect(hover.elementDescription, isNull);
+    expect(hover.elementKind, isNull);
+    // types
+    expect(hover.staticType, 'double');
+    expect(hover.propagatedType, isNull);
+    // parameter
+    expect(hover.parameter, 'double myParameter');
+  }
+
+  test_localVariable_declaration() async {
+    addTestFile('''
+library my.library;
+class A {
+  m() {
+    num vvv = 42;
+  }
+}
+''');
+    HoverInformation hover = await prepareHover('vvv = 42');
+    // element
+    expect(hover.containingLibraryName, isNull);
+    expect(hover.containingLibraryPath, isNull);
+    expect(hover.containingClassDescription, isNull);
+    expect(hover.dartdoc, isNull);
+    expect(hover.elementDescription, 'num vvv');
+    expect(hover.elementKind, 'local variable');
+    // types
+    expect(hover.staticType, 'num');
+    expect(hover.propagatedType, null);
+    // no parameter
+    expect(hover.parameter, isNull);
+  }
+
+  test_localVariable_reference_withPropagatedType() async {
+    addTestFile('''
+library my.library;
+main() {
+  var vvv = 123;
+  print(vvv);
+}
+''');
+    HoverInformation hover = await prepareHover('vvv);');
+    // element
+    expect(hover.containingLibraryName, isNull);
+    expect(hover.containingLibraryPath, isNull);
+    expect(hover.containingClassDescription, isNull);
+    expect(hover.dartdoc, isNull);
+    expect(hover.elementDescription, 'int vvv');
+    expect(hover.elementKind, 'local variable');
+    // types
+    expect(hover.staticType, 'int');
+    expect(hover.propagatedType, null);
+  }
+
+  test_method_declaration() async {
+    addTestFile('''
+library my.library;
+class A {
+  /// doc aaa
+  /// doc bbb
+  List<String> mmm(int a, String b) {
+  }
+}
+''');
+    HoverInformation hover = await prepareHover('mmm(int a');
+    // element
+    expect(hover.containingLibraryName, 'my.library');
+    expect(hover.containingLibraryPath, testFile);
+    expect(hover.containingClassDescription, 'A');
+    expect(hover.dartdoc, '''doc aaa\ndoc bbb''');
+    expect(hover.elementDescription, 'mmm(int a, String b) → List<String>');
+    expect(hover.elementKind, 'method');
     // types
     expect(hover.staticType, isNull);
     expect(hover.propagatedType, isNull);
@@ -576,31 +486,111 @@
     expect(hover.parameter, isNull);
   }
 
-  test_instanceCreation_noKeyword_new() async {
+  test_method_reference() async {
     addTestFile('''
 library my.library;
-class A {}
-main() {
-  var a = A();
+class A {
+  List<String> mmm(int a, String b) {
+  }
+}
+main(A a) {
+  a.mmm(42, 'foo');
 }
 ''');
-    HoverInformation hover = await prepareHover('A()');
+    HoverInformation hover = await prepareHover('mm(42, ');
     // range
-    expect(hover.offset, findOffset('A()'));
-    expect(hover.length, 'A()'.length);
+    expect(hover.offset, findOffset('mmm(42, '));
+    expect(hover.length, 'mmm'.length);
     // element
     expect(hover.containingLibraryName, 'my.library');
     expect(hover.containingLibraryPath, testFile);
-    expect(hover.dartdoc, isNull);
-    expect(hover.elementDescription, '(new) A() → A');
-    expect(hover.elementKind, 'constructor');
+    expect(hover.elementDescription, 'mmm(int a, String b) → List<String>');
+    expect(hover.elementKind, 'method');
+    expect(hover.isDeprecated, isFalse);
     // types
-    expect(hover.staticType, isNull);
+    expect(hover.staticType, '(int, String) → List<String>');
     expect(hover.propagatedType, isNull);
     // no parameter
     expect(hover.parameter, isNull);
   }
 
+  test_method_reference_deprecated() async {
+    addTestFile('''
+class A {
+  @deprecated
+  static void test() {}
+}
+main() {
+  A.test();
+}
+''');
+    HoverInformation hover = await prepareHover('test();');
+    // element
+    expect(hover.containingLibraryPath, testFile);
+    expect(hover.elementDescription, 'test() → void');
+    expect(hover.elementKind, 'method');
+    expect(hover.isDeprecated, isTrue);
+  }
+
+  test_method_reference_genericMethod() async {
+    addTestFile('''
+library my.library;
+
+abstract class Stream<T> {
+  Stream<S> transform<S>(StreamTransformer<T, S> streamTransformer);
+}
+abstract class StreamTransformer<T, S> {}
+
+f(Stream<int> s) {
+  s.transform(null);
+}
+''');
+    HoverInformation hover = await prepareHover('nsform(n');
+    // range
+    expect(hover.offset, findOffset('transform(n'));
+    expect(hover.length, 'transform'.length);
+    // element
+    expect(hover.containingLibraryName, 'my.library');
+    expect(hover.containingLibraryPath, testFile);
+    expect(hover.elementDescription,
+        'Stream.transform<S>(StreamTransformer<int, S> streamTransformer) → Stream<S>');
+    expect(hover.elementKind, 'method');
+    expect(hover.isDeprecated, isFalse);
+    // types
+    expect(hover.staticType,
+        '(StreamTransformer<int, dynamic>) → Stream<dynamic>');
+    expect(hover.propagatedType, isNull);
+    // no parameter
+    expect(hover.parameter, isNull);
+  }
+
+  test_mixin_declaration() async {
+    addTestFile('''
+mixin A on B, C implements D, E {}
+class B {}
+class C {}
+class D {}
+class E {}
+''');
+    HoverInformation hover = await prepareHover('A');
+    expect(hover.elementDescription, 'mixin A on B, C implements D, E');
+    expect(hover.staticType, isNull);
+    expect(hover.propagatedType, isNull);
+  }
+
+  @failingTest
+  test_mixin_reference() async {
+    addTestFile('''
+mixin A {}
+abstract class B {}
+class C with A implements B {}
+''');
+    HoverInformation hover = await prepareHover('A i');
+    expect(hover.elementDescription, 'mixin A');
+    expect(hover.staticType, isNull);
+    expect(hover.propagatedType, isNull);
+  }
+
   test_noHoverInfo() async {
     addTestFile('''
 library my.library;
@@ -611,4 +601,70 @@
     HoverInformation hover = await prepareHover('nothing');
     expect(hover, isNull);
   }
+
+  test_parameter_declaration_fieldFormal() async {
+    addTestFile('''
+class A {
+  /// The field documentation.
+  final int fff;
+  A({this.fff});
+}
+main() {
+  new A(fff: 42);
+}
+''');
+    HoverInformation hover = await prepareHover('fff});');
+    expect(hover.containingLibraryName, isNull);
+    expect(hover.containingLibraryPath, isNull);
+    expect(hover.containingClassDescription, isNull);
+    expect(hover.dartdoc, 'The field documentation.');
+    expect(hover.elementDescription, '{int fff}');
+    expect(hover.elementKind, 'parameter');
+    expect(hover.staticType, 'int');
+  }
+
+  test_parameter_declaration_required() async {
+    addTestFile('''
+library my.library;
+class A {
+  /// The method documentation.
+  m(int p) {
+  }
+}
+''');
+    HoverInformation hover = await prepareHover('p) {');
+    // element
+    expect(hover.containingLibraryName, isNull);
+    expect(hover.containingLibraryPath, isNull);
+    expect(hover.containingClassDescription, isNull);
+    expect(hover.dartdoc, 'The method documentation.');
+    expect(hover.elementDescription, 'int p');
+    expect(hover.elementKind, 'parameter');
+    // types
+    expect(hover.staticType, 'int');
+    expect(hover.propagatedType, isNull);
+    // no parameter
+    expect(hover.parameter, isNull);
+  }
+
+  test_parameter_reference_fieldFormal() async {
+    addTestFile('''
+class A {
+  /// The field documentation.
+  final int fff;
+  A({this.fff});
+}
+main() {
+  new A(fff: 42);
+}
+''');
+    HoverInformation hover = await prepareHover('fff: 42');
+    expect(hover.containingLibraryName, isNull);
+    expect(hover.containingLibraryPath, isNull);
+    expect(hover.containingClassDescription, isNull);
+    expect(hover.dartdoc, 'The field documentation.');
+    expect(hover.elementDescription, '{int fff}');
+    expect(hover.elementKind, 'parameter');
+    expect(hover.staticType, 'int');
+  }
 }
diff --git a/pkg/analysis_server/test/analysis/notification_highlights_test2.dart b/pkg/analysis_server/test/analysis/notification_highlights2_test.dart
similarity index 98%
rename from pkg/analysis_server/test/analysis/notification_highlights_test2.dart
rename to pkg/analysis_server/test/analysis/notification_highlights2_test.dart
index 4fef09a..54793b6 100644
--- a/pkg/analysis_server/test/analysis/notification_highlights_test2.dart
+++ b/pkg/analysis_server/test/analysis/notification_highlights2_test.dart
@@ -313,7 +313,16 @@
     assertNoRegion(HighlightRegionType.BUILT_IN, 'native = 42');
   }
 
-  test_BUILT_IN_on() async {
+  test_BUILT_IN_on_inMixin() async {
+    addTestFile('''
+mixin M on N {}
+class N {}
+''');
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.BUILT_IN, 'on N');
+  }
+
+  test_BUILT_IN_on_inTry() async {
     addTestFile('''
 main() {
   try {
@@ -782,6 +791,14 @@
     assertHasRegion(HighlightRegionType.KEYWORD, 'with A;');
   }
 
+  test_KEYWORD_mixin() async {
+    addTestFile('''
+mixin M {}
+''');
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.BUILT_IN, 'mixin');
+  }
+
   test_KEYWORD_void() async {
     addTestFile('''
 void main() {
diff --git a/pkg/analysis_server/test/analysis/notification_highlights_test.dart b/pkg/analysis_server/test/analysis/notification_highlights_test.dart
index a23abb2..f36e5d8 100644
--- a/pkg/analysis_server/test/analysis/notification_highlights_test.dart
+++ b/pkg/analysis_server/test/analysis/notification_highlights_test.dart
@@ -312,7 +312,16 @@
     assertNoRegion(HighlightRegionType.BUILT_IN, 'native = 42');
   }
 
-  test_BUILT_IN_on() async {
+  test_BUILT_IN_on_inMixin() async {
+    addTestFile('''
+mixin M on N {}
+class N {}
+''');
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.BUILT_IN, 'on N');
+  }
+
+  test_BUILT_IN_on_inTry() async {
     addTestFile('''
 main() {
   try {
@@ -772,6 +781,14 @@
     assertHasRegion(HighlightRegionType.KEYWORD, 'with A;');
   }
 
+  test_KEYWORD_mixin() async {
+    addTestFile('''
+mixin M {}
+''');
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.BUILT_IN, 'mixin');
+  }
+
   test_KEYWORD_void() async {
     addTestFile('''
 void main() {
diff --git a/pkg/analysis_server/test/analysis/test_all.dart b/pkg/analysis_server/test/analysis/test_all.dart
index a0217b6..9628319 100644
--- a/pkg/analysis_server/test/analysis/test_all.dart
+++ b/pkg/analysis_server/test/analysis/test_all.dart
@@ -14,10 +14,10 @@
     as notification_analyzedFiles_test;
 import 'notification_closingLabels_test.dart'
     as notification_closingLabels_test;
-import 'notification_folding_test.dart' as notification_folding_test;
 import 'notification_errors_test.dart' as notification_errors_test;
+import 'notification_folding_test.dart' as notification_folding_test;
+import 'notification_highlights2_test.dart' as notification_highlights2_test;
 import 'notification_highlights_test.dart' as notification_highlights_test;
-import 'notification_highlights_test2.dart' as notification_highlights_test2;
 import 'notification_implemented_test.dart' as notification_implemented_test;
 import 'notification_navigation_test.dart' as notification_navigation_test;
 import 'notification_occurrences_test.dart' as notification_occurrences_test;
@@ -41,8 +41,8 @@
     notification_closingLabels_test.main();
     notification_folding_test.main();
     notification_errors_test.main();
+    notification_highlights2_test.main();
     notification_highlights_test.main();
-    notification_highlights_test2.main();
     notification_implemented_test.main();
     notification_navigation_test.main();
     notification_occurrences_test.main();
diff --git a/pkg/analysis_server/test/edit/fixes_test.dart b/pkg/analysis_server/test/edit/fixes_test.dart
index 1be66ae..4d07618 100644
--- a/pkg/analysis_server/test/edit/fixes_test.dart
+++ b/pkg/analysis_server/test/edit/fixes_test.dart
@@ -45,9 +45,10 @@
     expect(error.severity, AnalysisErrorSeverity.WARNING);
     expect(error.type, AnalysisErrorType.STATIC_WARNING);
     List<SourceChange> fixes = errorFixes[0].fixes;
-    expect(fixes, hasLength(2));
+    expect(fixes, hasLength(3));
     expect(fixes[0].message, matches('Import library'));
     expect(fixes[1].message, matches('Create class'));
+    expect(fixes[2].message, matches('Create mixin'));
   }
 
   test_fromPlugins() async {
diff --git a/pkg/analysis_server/test/edit/refactoring_test.dart b/pkg/analysis_server/test/edit/refactoring_test.dart
index e3a0a33..b696ea8 100644
--- a/pkg/analysis_server/test/edit/refactoring_test.dart
+++ b/pkg/analysis_server/test/edit/refactoring_test.dart
@@ -25,10 +25,7 @@
     defineReflectiveTests(InlineLocalTest);
     defineReflectiveTests(InlineMethodTest);
     defineReflectiveTests(MoveFileTest);
-    // TODO(brianwilkerson) Re-enable these tests. They were commented out
-    // because they are non-deterministic under the new driver. I suspect that
-    // there is a future that isn't being waited for.
-//    defineReflectiveTests(RenameTest);
+    defineReflectiveTests(RenameTest);
   });
 }
 
@@ -1355,6 +1352,151 @@
 ''');
   }
 
+  test_class_fromFactoryRedirectingConstructor() {
+    addTestFile('''
+class A {
+  A() = Test.named;
+}
+class Test {
+  Test.named() {}
+}
+''');
+    return assertSuccessfulRefactoring(
+      () {
+        return sendRenameRequest('Test.named;', 'NewName');
+      },
+      '''
+class A {
+  A() = NewName.named;
+}
+class NewName {
+  NewName.named() {}
+}
+''',
+      feedbackValidator: (feedback) {
+        RenameFeedback renameFeedback = feedback;
+        expect(renameFeedback.offset, 18);
+        expect(renameFeedback.length, 4);
+      },
+    );
+  }
+
+  test_class_fromInstanceCreation() {
+    addTestFile('''
+class Test {
+  Test() {}
+}
+main() {
+  new Test();
+}
+''');
+    return assertSuccessfulRefactoring(
+      () {
+        return sendRenameRequest('Test();', 'NewName');
+      },
+      '''
+class NewName {
+  NewName() {}
+}
+main() {
+  new NewName();
+}
+''',
+      feedbackValidator: (feedback) {
+        RenameFeedback renameFeedback = feedback;
+        expect(renameFeedback.offset, 42);
+        expect(renameFeedback.length, 4);
+      },
+    );
+  }
+
+  test_class_fromInstanceCreation_namedConstructor() {
+    addTestFile('''
+class Test {
+  Test.named() {}
+}
+main() {
+  new Test.named();
+}
+''');
+    return assertSuccessfulRefactoring(
+      () {
+        return sendRenameRequest('Test.named();', 'NewName');
+      },
+      '''
+class NewName {
+  NewName.named() {}
+}
+main() {
+  new NewName.named();
+}
+''',
+      feedbackValidator: (feedback) {
+        RenameFeedback renameFeedback = feedback;
+        expect(renameFeedback.offset, 48);
+        expect(renameFeedback.length, 4);
+      },
+    );
+  }
+
+  test_class_fromInstanceCreation_onNew() {
+    addTestFile('''
+class Test {
+  Test() {}
+}
+main() {
+  new Test();
+}
+''');
+    return assertSuccessfulRefactoring(
+      () {
+        return sendRenameRequest('new Test();', 'NewName');
+      },
+      '''
+class NewName {
+  NewName() {}
+}
+main() {
+  new NewName();
+}
+''',
+      feedbackValidator: (feedback) {
+        RenameFeedback renameFeedback = feedback;
+        expect(renameFeedback.offset, 42);
+        expect(renameFeedback.length, 4);
+      },
+    );
+  }
+
+  test_class_fromInstanceCreation_onNew_namedConstructor() {
+    addTestFile('''
+class Test {
+  Test.named() {}
+}
+main() {
+  new Test.named();
+}
+''');
+    return assertSuccessfulRefactoring(
+      () {
+        return sendRenameRequest('new Test.named();', 'NewName');
+      },
+      '''
+class NewName {
+  NewName.named() {}
+}
+main() {
+  new NewName.named();
+}
+''',
+      feedbackValidator: (feedback) {
+        RenameFeedback renameFeedback = feedback;
+        expect(renameFeedback.offset, 48);
+        expect(renameFeedback.length, 4);
+      },
+    );
+  }
+
   test_class_options_fatalError() {
     addTestFile('''
 class Test {}
@@ -1591,18 +1733,18 @@
 ''');
   }
 
-  test_constructor_fromFactoryRedirectingConstructor_onClassName() {
+  test_constructor_fromFactoryRedirectingConstructor() {
     addTestFile('''
 class A {
-  A() = B;
+  A() = B.test;
 }
 class B {
-  B() {}
+  B.test() {}
 }
 ''');
     return assertSuccessfulRefactoring(
       () {
-        return sendRenameRequest('B;', 'newName');
+        return sendRenameRequest('test;', 'newName');
       },
       '''
 class A {
@@ -1614,8 +1756,8 @@
 ''',
       feedbackValidator: (feedback) {
         RenameFeedback renameFeedback = feedback;
-        expect(renameFeedback.offset, -1);
-        expect(renameFeedback.length, 0);
+        expect(renameFeedback.offset, 20);
+        expect(renameFeedback.length, 4);
       },
     );
   }
@@ -1649,64 +1791,6 @@
     );
   }
 
-  test_constructor_fromInstanceCreation_default_onClassName() {
-    addTestFile('''
-class A {
-  A() {}
-}
-main() {
-  new A();
-}
-''');
-    return assertSuccessfulRefactoring(
-      () {
-        return sendRenameRequest('A();', 'newName');
-      },
-      '''
-class A {
-  A.newName() {}
-}
-main() {
-  new A.newName();
-}
-''',
-      feedbackValidator: (feedback) {
-        RenameFeedback renameFeedback = feedback;
-        expect(renameFeedback.offset, -1);
-        expect(renameFeedback.length, 0);
-      },
-    );
-  }
-
-  test_constructor_fromInstanceCreation_default_onNew() {
-    addTestFile('''
-class A {
-  A() {}
-}
-main() {
-  new A();
-}
-''');
-    return assertSuccessfulRefactoring(
-      () {
-        return sendRenameRequest('new A();', 'newName');
-      },
-      '''
-class A {
-  A.newName() {}
-}
-main() {
-  new A.newName();
-}
-''',
-      feedbackValidator: (feedback) {
-        RenameFeedback renameFeedback = feedback;
-        expect(renameFeedback.offset, -1);
-        expect(renameFeedback.length, 0);
-      },
-    );
-  }
-
   test_feedback() {
     addTestFile('''
 class Test {}
diff --git a/pkg/analysis_server/test/integration/analysis/get_errors_nonStandard_sdk.dart b/pkg/analysis_server/test/integration/analysis/get_errors_nonStandard_sdk_test.dart
similarity index 100%
rename from pkg/analysis_server/test/integration/analysis/get_errors_nonStandard_sdk.dart
rename to pkg/analysis_server/test/integration/analysis/get_errors_nonStandard_sdk_test.dart
diff --git a/pkg/analysis_server/test/integration/analysis/highlights2_test.dart b/pkg/analysis_server/test/integration/analysis/highlights2_test.dart
new file mode 100644
index 0000000..d9f1ebc
--- /dev/null
+++ b/pkg/analysis_server/test/integration/analysis/highlights2_test.dart
@@ -0,0 +1,184 @@
+// 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:async';
+
+import 'package:analysis_server/protocol/protocol_generated.dart';
+import 'package:analyzer_plugin/protocol/protocol_common.dart';
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../support/integration_tests.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(AnalysisHighlightsTest);
+  });
+}
+
+@reflectiveTest
+class AnalysisHighlightsTest extends AbstractAnalysisServerIntegrationTest {
+  Map<HighlightRegionType, Set<String>> highlights;
+
+  void check(HighlightRegionType type, List<String> expected) {
+    expect(highlights[type], equals(expected.toSet()));
+    highlights.remove(type);
+  }
+
+  computeHighlights(String pathname, String text) async {
+    writeFile(pathname, text);
+    standardAnalysisSetup();
+    sendAnalysisSetSubscriptions({
+      AnalysisService.HIGHLIGHTS: [pathname]
+    });
+    // Map from highlight type to highlighted text
+    onAnalysisHighlights.listen((AnalysisHighlightsParams params) {
+      expect(params.file, equals(pathname));
+      highlights = <HighlightRegionType, Set<String>>{};
+      for (HighlightRegion region in params.regions) {
+        int startIndex = region.offset;
+        int endIndex = startIndex + region.length;
+        String highlightedText = text.substring(startIndex, endIndex);
+        HighlightRegionType type = region.type;
+        if (!highlights.containsKey(type)) {
+          highlights[type] = new Set<String>();
+        }
+        highlights[type].add(highlightedText);
+      }
+    });
+    await analysisFinished;
+  }
+
+  @override
+  Future startServer({
+    int diagnosticPort,
+    int servicesPort,
+  }) {
+    return server.start(
+        diagnosticPort: diagnosticPort,
+        servicesPort: servicesPort,
+        useAnalysisHighlight2: true);
+  }
+
+  test_highlights() async {
+    String pathname = sourcePath('test.dart');
+    String text = r'''
+import 'dart:async' as async;
+
+/**
+ * Doc comment
+ */
+class Class<TypeParameter> {
+  Class() {
+    field = {1.0: [].toList()};
+  }
+
+  Class.constructor() {
+    dynamic local = true;
+    field = {2: local};
+  }
+
+  Map field;
+  static int staticField;
+
+  method() {
+    // End of line comment
+    /* Block comment */
+  }
+
+  static staticMethod() {
+  }
+
+  get getter {
+  }
+
+  set setter(int parameter) {
+    print(parameter);
+  }
+}
+
+class Class2<TypeParameter> extends Class<TypeParameter> {
+  @override
+  method() {
+  }
+}
+
+typedef functionType();
+
+function(dynamicType) {
+  print('string');
+  unresolvedIdentifier = 42;
+  return async.Future.wait([]);
+}
+
+int topLevelVariable;
+''';
+    await computeHighlights(pathname, text);
+    // There should be 1 error due to the fact that unresolvedIdentifier is
+    // unresolved.
+    expect(currentAnalysisErrors[pathname], hasLength(1));
+    void check(HighlightRegionType type, List<String> expected) {
+      expect(highlights[type], equals(expected.toSet()));
+      highlights.remove(type);
+    }
+
+    check(HighlightRegionType.ANNOTATION, ['@override']);
+    check(HighlightRegionType.BUILT_IN,
+        ['as', 'get', 'import', 'set', 'static', 'typedef']);
+    check(
+        HighlightRegionType.CLASS, ['Class', 'Class2', 'Future', 'Map', 'int']);
+    check(HighlightRegionType.COMMENT_BLOCK, ['/* Block comment */']);
+    check(HighlightRegionType.COMMENT_DOCUMENTATION,
+        ['/**\n * Doc comment\n */']);
+    check(HighlightRegionType.COMMENT_END_OF_LINE, ['// End of line comment']);
+    check(HighlightRegionType.CONSTRUCTOR, ['constructor']);
+    check(HighlightRegionType.DIRECTIVE, ["import 'dart:async' as async;"]);
+    check(HighlightRegionType.DYNAMIC_PARAMETER_DECLARATION, ['dynamicType']);
+    check(HighlightRegionType.INSTANCE_FIELD_DECLARATION, ['field']);
+    check(HighlightRegionType.INSTANCE_SETTER_REFERENCE, ['field']);
+    check(HighlightRegionType.STATIC_FIELD_DECLARATION, ['staticField']);
+    check(HighlightRegionType.TOP_LEVEL_FUNCTION_REFERENCE, ['print']);
+    check(HighlightRegionType.TOP_LEVEL_FUNCTION_DECLARATION, ['function']);
+    check(HighlightRegionType.FUNCTION_TYPE_ALIAS, ['functionType']);
+    check(HighlightRegionType.INSTANCE_GETTER_DECLARATION, ['getter']);
+    check(HighlightRegionType.IDENTIFIER_DEFAULT, ['unresolvedIdentifier']);
+    check(HighlightRegionType.IMPORT_PREFIX, ['async']);
+    check(HighlightRegionType.KEYWORD, ['class', 'extends', 'true', 'return']);
+    check(HighlightRegionType.LITERAL_BOOLEAN, ['true']);
+    check(HighlightRegionType.LITERAL_DOUBLE, ['1.0']);
+    check(HighlightRegionType.LITERAL_INTEGER, ['2', '42']);
+    check(HighlightRegionType.LITERAL_LIST, ['[]']);
+    check(
+        HighlightRegionType.LITERAL_MAP, ['{1.0: [].toList()}', '{2: local}']);
+    check(HighlightRegionType.LITERAL_STRING, ["'dart:async'", "'string'"]);
+    check(HighlightRegionType.DYNAMIC_LOCAL_VARIABLE_DECLARATION, ['local']);
+    check(HighlightRegionType.DYNAMIC_LOCAL_VARIABLE_REFERENCE, ['local']);
+    check(HighlightRegionType.INSTANCE_METHOD_REFERENCE, ['toList']);
+    check(HighlightRegionType.INSTANCE_METHOD_DECLARATION, ['method']);
+    check(HighlightRegionType.STATIC_METHOD_DECLARATION, ['staticMethod']);
+    check(HighlightRegionType.STATIC_METHOD_REFERENCE, ['wait']);
+    check(HighlightRegionType.PARAMETER_DECLARATION, ['parameter']);
+    check(HighlightRegionType.PARAMETER_REFERENCE, ['parameter']);
+    check(HighlightRegionType.INSTANCE_SETTER_DECLARATION, ['setter']);
+    check(HighlightRegionType.TOP_LEVEL_GETTER_REFERENCE, ['override']);
+    check(HighlightRegionType.TOP_LEVEL_VARIABLE_DECLARATION,
+        ['topLevelVariable']);
+    check(HighlightRegionType.TYPE_NAME_DYNAMIC, ['dynamic']);
+    check(HighlightRegionType.TYPE_PARAMETER, ['TypeParameter']);
+    expect(highlights, isEmpty);
+  }
+
+  test_highlights_mixin() async {
+    String pathname = sourcePath('test.dart');
+    String text = r'''
+mixin M on A implements B {}
+class A {}
+class B {}
+''';
+    await computeHighlights(pathname, text);
+    expect(currentAnalysisErrors[pathname], hasLength(0));
+    check(HighlightRegionType.BUILT_IN, ['implements', 'mixin', 'on']);
+    check(HighlightRegionType.KEYWORD, ['class']);
+  }
+}
diff --git a/pkg/analysis_server/test/integration/analysis/highlights_test.dart b/pkg/analysis_server/test/integration/analysis/highlights_test.dart
index 3c9d09b..613a45d 100644
--- a/pkg/analysis_server/test/integration/analysis/highlights_test.dart
+++ b/pkg/analysis_server/test/integration/analysis/highlights_test.dart
@@ -17,7 +17,38 @@
 
 @reflectiveTest
 class AnalysisHighlightsTest extends AbstractAnalysisServerIntegrationTest {
-  test_highlights() {
+  Map<HighlightRegionType, Set<String>> highlights;
+
+  void check(HighlightRegionType type, List<String> expected) {
+    expect(highlights[type], equals(expected.toSet()));
+    highlights.remove(type);
+  }
+
+  computeHighlights(String pathname, String text) async {
+    writeFile(pathname, text);
+    standardAnalysisSetup();
+    sendAnalysisSetSubscriptions({
+      AnalysisService.HIGHLIGHTS: [pathname]
+    });
+    // Map from highlight type to highlighted text
+    onAnalysisHighlights.listen((AnalysisHighlightsParams params) {
+      expect(params.file, equals(pathname));
+      highlights = <HighlightRegionType, Set<String>>{};
+      for (HighlightRegion region in params.regions) {
+        int startIndex = region.offset;
+        int endIndex = startIndex + region.length;
+        String highlightedText = text.substring(startIndex, endIndex);
+        HighlightRegionType type = region.type;
+        if (!highlights.containsKey(type)) {
+          highlights[type] = new Set<String>();
+        }
+        highlights[type].add(highlightedText);
+      }
+    });
+    await analysisFinished;
+  }
+
+  test_highlights() async {
     String pathname = sourcePath('test.dart');
     String text = r'''
 import 'dart:async' as async;
@@ -69,78 +100,64 @@
 
 int topLevelVariable;
 ''';
-    writeFile(pathname, text);
-    standardAnalysisSetup();
-    sendAnalysisSetSubscriptions({
-      AnalysisService.HIGHLIGHTS: [pathname]
-    });
-    // Map from highlight type to highlighted text
-    Map<HighlightRegionType, Set<String>> highlights;
-    onAnalysisHighlights.listen((AnalysisHighlightsParams params) {
-      expect(params.file, equals(pathname));
-      highlights = <HighlightRegionType, Set<String>>{};
-      for (HighlightRegion region in params.regions) {
-        int startIndex = region.offset;
-        int endIndex = startIndex + region.length;
-        String highlightedText = text.substring(startIndex, endIndex);
-        HighlightRegionType type = region.type;
-        if (!highlights.containsKey(type)) {
-          highlights[type] = new Set<String>();
-        }
-        highlights[type].add(highlightedText);
-      }
-    });
-    return analysisFinished.then((_) {
-      // There should be 1 error due to the fact that unresolvedIdentifier is
-      // unresolved.
-      expect(currentAnalysisErrors[pathname], hasLength(1));
-      void check(HighlightRegionType type, List<String> expected) {
-        expect(highlights[type], equals(expected.toSet()));
-        highlights.remove(type);
-      }
+    await computeHighlights(pathname, text);
+    // There should be 1 error due to the fact that unresolvedIdentifier is
+    // unresolved.
+    expect(currentAnalysisErrors[pathname], hasLength(1));
 
-      check(HighlightRegionType.ANNOTATION, ['@override']);
-      check(HighlightRegionType.BUILT_IN,
-          ['as', 'get', 'import', 'set', 'static', 'typedef']);
-      check(HighlightRegionType.CLASS,
-          ['Class', 'Class2', 'Future', 'Map', 'int']);
-      check(HighlightRegionType.COMMENT_BLOCK, ['/* Block comment */']);
-      check(HighlightRegionType.COMMENT_DOCUMENTATION,
-          ['/**\n * Doc comment\n */']);
-      check(
-          HighlightRegionType.COMMENT_END_OF_LINE, ['// End of line comment']);
-      check(HighlightRegionType.CONSTRUCTOR, ['constructor']);
-      check(HighlightRegionType.DIRECTIVE, ["import 'dart:async' as async;"]);
-      check(HighlightRegionType.DYNAMIC_TYPE, ['dynamicType', 'local']);
-      check(HighlightRegionType.FIELD, ['field']);
-      check(HighlightRegionType.FIELD_STATIC, ['staticField']);
-      check(HighlightRegionType.FUNCTION, ['print']);
-      check(HighlightRegionType.FUNCTION_DECLARATION, ['function']);
-      check(HighlightRegionType.FUNCTION_TYPE_ALIAS, ['functionType']);
-      check(HighlightRegionType.GETTER_DECLARATION, ['getter']);
-      check(HighlightRegionType.IDENTIFIER_DEFAULT, ['unresolvedIdentifier']);
-      check(HighlightRegionType.IMPORT_PREFIX, ['async']);
-      check(HighlightRegionType.KEYWORD, ['class', 'true', 'return']);
-      check(HighlightRegionType.LITERAL_BOOLEAN, ['true']);
-      check(HighlightRegionType.LITERAL_DOUBLE, ['1.0']);
-      check(HighlightRegionType.LITERAL_INTEGER, ['2', '42']);
-      check(HighlightRegionType.LITERAL_LIST, ['[]']);
-      check(HighlightRegionType.LITERAL_MAP,
-          ['{1.0: [].toList()}', '{2: local}']);
-      check(HighlightRegionType.LITERAL_STRING, ["'dart:async'", "'string'"]);
-      //check(HighlightRegionType.LOCAL_VARIABLE, ['local']);
-      //check(HighlightRegionType.LOCAL_VARIABLE_DECLARATION, ['local']);
-      check(HighlightRegionType.METHOD, ['toList']);
-      check(HighlightRegionType.METHOD_DECLARATION, ['method']);
-      check(HighlightRegionType.METHOD_DECLARATION_STATIC, ['staticMethod']);
-      check(HighlightRegionType.METHOD_STATIC, ['wait']);
-      check(HighlightRegionType.PARAMETER, ['parameter']);
-      check(HighlightRegionType.SETTER_DECLARATION, ['setter']);
-      check(HighlightRegionType.TOP_LEVEL_VARIABLE,
-          ['override', 'topLevelVariable']);
-      check(HighlightRegionType.TYPE_NAME_DYNAMIC, ['dynamic']);
-      check(HighlightRegionType.TYPE_PARAMETER, ['TypeParameter']);
-      expect(highlights, isEmpty);
-    });
+    check(HighlightRegionType.ANNOTATION, ['@override']);
+    check(HighlightRegionType.BUILT_IN,
+        ['as', 'get', 'import', 'set', 'static', 'typedef']);
+    check(
+        HighlightRegionType.CLASS, ['Class', 'Class2', 'Future', 'Map', 'int']);
+    check(HighlightRegionType.COMMENT_BLOCK, ['/* Block comment */']);
+    check(HighlightRegionType.COMMENT_DOCUMENTATION,
+        ['/**\n * Doc comment\n */']);
+    check(HighlightRegionType.COMMENT_END_OF_LINE, ['// End of line comment']);
+    check(HighlightRegionType.CONSTRUCTOR, ['constructor']);
+    check(HighlightRegionType.DIRECTIVE, ["import 'dart:async' as async;"]);
+    check(HighlightRegionType.DYNAMIC_TYPE, ['dynamicType', 'local']);
+    check(HighlightRegionType.FIELD, ['field']);
+    check(HighlightRegionType.FIELD_STATIC, ['staticField']);
+    check(HighlightRegionType.FUNCTION, ['print']);
+    check(HighlightRegionType.FUNCTION_DECLARATION, ['function']);
+    check(HighlightRegionType.FUNCTION_TYPE_ALIAS, ['functionType']);
+    check(HighlightRegionType.GETTER_DECLARATION, ['getter']);
+    check(HighlightRegionType.IDENTIFIER_DEFAULT, ['unresolvedIdentifier']);
+    check(HighlightRegionType.IMPORT_PREFIX, ['async']);
+    check(HighlightRegionType.KEYWORD, ['class', 'extends', 'true', 'return']);
+    check(HighlightRegionType.LITERAL_BOOLEAN, ['true']);
+    check(HighlightRegionType.LITERAL_DOUBLE, ['1.0']);
+    check(HighlightRegionType.LITERAL_INTEGER, ['2', '42']);
+    check(HighlightRegionType.LITERAL_LIST, ['[]']);
+    check(
+        HighlightRegionType.LITERAL_MAP, ['{1.0: [].toList()}', '{2: local}']);
+    check(HighlightRegionType.LITERAL_STRING, ["'dart:async'", "'string'"]);
+    //check(HighlightRegionType.LOCAL_VARIABLE, ['local']);
+    //check(HighlightRegionType.LOCAL_VARIABLE_DECLARATION, ['local']);
+    check(HighlightRegionType.METHOD, ['toList']);
+    check(HighlightRegionType.METHOD_DECLARATION, ['method']);
+    check(HighlightRegionType.METHOD_DECLARATION_STATIC, ['staticMethod']);
+    check(HighlightRegionType.METHOD_STATIC, ['wait']);
+    check(HighlightRegionType.PARAMETER, ['parameter']);
+    check(HighlightRegionType.SETTER_DECLARATION, ['setter']);
+    check(HighlightRegionType.TOP_LEVEL_VARIABLE,
+        ['override', 'topLevelVariable']);
+    check(HighlightRegionType.TYPE_NAME_DYNAMIC, ['dynamic']);
+    check(HighlightRegionType.TYPE_PARAMETER, ['TypeParameter']);
+    expect(highlights, isEmpty);
+  }
+
+  test_highlights_mixin() async {
+    String pathname = sourcePath('test.dart');
+    String text = r'''
+mixin M on A implements B {}
+class A {}
+class B {}
+''';
+    await computeHighlights(pathname, text);
+    expect(currentAnalysisErrors[pathname], hasLength(0));
+    check(HighlightRegionType.BUILT_IN, ['implements', 'mixin', 'on']);
+    check(HighlightRegionType.KEYWORD, ['class']);
   }
 }
diff --git a/pkg/analysis_server/test/integration/analysis/highlights_test2.dart b/pkg/analysis_server/test/integration/analysis/highlights_test2.dart
deleted file mode 100644
index ce16391..0000000
--- a/pkg/analysis_server/test/integration/analysis/highlights_test2.dart
+++ /dev/null
@@ -1,162 +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:async';
-
-import 'package:analysis_server/protocol/protocol_generated.dart';
-import 'package:analyzer_plugin/protocol/protocol_common.dart';
-import 'package:test/test.dart';
-import 'package:test_reflective_loader/test_reflective_loader.dart';
-
-import '../support/integration_tests.dart';
-
-main() {
-  defineReflectiveSuite(() {
-    defineReflectiveTests(AnalysisHighlightsTest);
-  });
-}
-
-@reflectiveTest
-class AnalysisHighlightsTest extends AbstractAnalysisServerIntegrationTest {
-  Future startServer({
-    int diagnosticPort,
-    int servicesPort,
-  }) {
-    return server.start(
-        diagnosticPort: diagnosticPort,
-        servicesPort: servicesPort,
-        useAnalysisHighlight2: true);
-  }
-
-  test_highlights() {
-    String pathname = sourcePath('test.dart');
-    String text = r'''
-import 'dart:async' as async;
-
-/**
- * Doc comment
- */
-class Class<TypeParameter> {
-  Class() {
-    field = {1.0: [].toList()};
-  }
-
-  Class.constructor() {
-    dynamic local = true;
-    field = {2: local};
-  }
-
-  Map field;
-  static int staticField;
-
-  method() {
-    // End of line comment
-    /* Block comment */
-  }
-
-  static staticMethod() {
-  }
-
-  get getter {
-  }
-
-  set setter(int parameter) {
-    print(parameter);
-  }
-}
-
-class Class2<TypeParameter> extends Class<TypeParameter> {
-  @override
-  method() {
-  }
-}
-
-typedef functionType();
-
-function(dynamicType) {
-  print('string');
-  unresolvedIdentifier = 42;
-  return async.Future.wait([]);
-}
-
-int topLevelVariable;
-''';
-    writeFile(pathname, text);
-    standardAnalysisSetup();
-    sendAnalysisSetSubscriptions({
-      AnalysisService.HIGHLIGHTS: [pathname]
-    });
-    // Map from highlight type to highlighted text
-    Map<HighlightRegionType, Set<String>> highlights;
-    onAnalysisHighlights.listen((AnalysisHighlightsParams params) {
-      expect(params.file, equals(pathname));
-      highlights = <HighlightRegionType, Set<String>>{};
-      for (HighlightRegion region in params.regions) {
-        int startIndex = region.offset;
-        int endIndex = startIndex + region.length;
-        String highlightedText = text.substring(startIndex, endIndex);
-        HighlightRegionType type = region.type;
-        if (!highlights.containsKey(type)) {
-          highlights[type] = new Set<String>();
-        }
-        highlights[type].add(highlightedText);
-      }
-    });
-    return analysisFinished.then((_) {
-      // There should be 1 error due to the fact that unresolvedIdentifier is
-      // unresolved.
-      expect(currentAnalysisErrors[pathname], hasLength(1));
-      void check(HighlightRegionType type, List<String> expected) {
-        expect(highlights[type], equals(expected.toSet()));
-        highlights.remove(type);
-      }
-
-      check(HighlightRegionType.ANNOTATION, ['@override']);
-      check(HighlightRegionType.BUILT_IN,
-          ['as', 'get', 'import', 'set', 'static', 'typedef']);
-      check(HighlightRegionType.CLASS,
-          ['Class', 'Class2', 'Future', 'Map', 'int']);
-      check(HighlightRegionType.COMMENT_BLOCK, ['/* Block comment */']);
-      check(HighlightRegionType.COMMENT_DOCUMENTATION,
-          ['/**\n * Doc comment\n */']);
-      check(
-          HighlightRegionType.COMMENT_END_OF_LINE, ['// End of line comment']);
-      check(HighlightRegionType.CONSTRUCTOR, ['constructor']);
-      check(HighlightRegionType.DIRECTIVE, ["import 'dart:async' as async;"]);
-      check(HighlightRegionType.DYNAMIC_PARAMETER_DECLARATION, ['dynamicType']);
-      check(HighlightRegionType.INSTANCE_FIELD_DECLARATION, ['field']);
-      check(HighlightRegionType.INSTANCE_SETTER_REFERENCE, ['field']);
-      check(HighlightRegionType.STATIC_FIELD_DECLARATION, ['staticField']);
-      check(HighlightRegionType.TOP_LEVEL_FUNCTION_REFERENCE, ['print']);
-      check(HighlightRegionType.TOP_LEVEL_FUNCTION_DECLARATION, ['function']);
-      check(HighlightRegionType.FUNCTION_TYPE_ALIAS, ['functionType']);
-      check(HighlightRegionType.INSTANCE_GETTER_DECLARATION, ['getter']);
-      check(HighlightRegionType.IDENTIFIER_DEFAULT, ['unresolvedIdentifier']);
-      check(HighlightRegionType.IMPORT_PREFIX, ['async']);
-      check(HighlightRegionType.KEYWORD, ['class', 'true', 'return']);
-      check(HighlightRegionType.LITERAL_BOOLEAN, ['true']);
-      check(HighlightRegionType.LITERAL_DOUBLE, ['1.0']);
-      check(HighlightRegionType.LITERAL_INTEGER, ['2', '42']);
-      check(HighlightRegionType.LITERAL_LIST, ['[]']);
-      check(HighlightRegionType.LITERAL_MAP,
-          ['{1.0: [].toList()}', '{2: local}']);
-      check(HighlightRegionType.LITERAL_STRING, ["'dart:async'", "'string'"]);
-      check(HighlightRegionType.DYNAMIC_LOCAL_VARIABLE_DECLARATION, ['local']);
-      check(HighlightRegionType.DYNAMIC_LOCAL_VARIABLE_REFERENCE, ['local']);
-      check(HighlightRegionType.INSTANCE_METHOD_REFERENCE, ['toList']);
-      check(HighlightRegionType.INSTANCE_METHOD_DECLARATION, ['method']);
-      check(HighlightRegionType.STATIC_METHOD_DECLARATION, ['staticMethod']);
-      check(HighlightRegionType.STATIC_METHOD_REFERENCE, ['wait']);
-      check(HighlightRegionType.PARAMETER_DECLARATION, ['parameter']);
-      check(HighlightRegionType.PARAMETER_REFERENCE, ['parameter']);
-      check(HighlightRegionType.INSTANCE_SETTER_DECLARATION, ['setter']);
-      check(HighlightRegionType.TOP_LEVEL_GETTER_REFERENCE, ['override']);
-      check(HighlightRegionType.TOP_LEVEL_VARIABLE_DECLARATION,
-          ['topLevelVariable']);
-      check(HighlightRegionType.TYPE_NAME_DYNAMIC, ['dynamic']);
-      check(HighlightRegionType.TYPE_PARAMETER, ['TypeParameter']);
-      expect(highlights, isEmpty);
-    });
-  }
-}
diff --git a/pkg/analysis_server/test/integration/analysis/test_all.dart b/pkg/analysis_server/test/integration/analysis/test_all.dart
index e7a825d..99021da 100644
--- a/pkg/analysis_server/test/integration/analysis/test_all.dart
+++ b/pkg/analysis_server/test/integration/analysis/test_all.dart
@@ -6,15 +6,15 @@
 
 import 'analysis_options_test.dart' as analysis_options_test;
 import 'error_test.dart' as error_test;
-import 'get_errors_nonStandard_sdk.dart' as get_errors_nonStandard_sdk;
+import 'get_errors_nonStandard_sdk_test.dart' as get_errors_nonStandard_sdk;
 import 'get_errors_test.dart' as get_errors_test;
 import 'get_hover_test.dart' as get_hover_test;
 import 'get_imported_elements_test.dart' as get_imported_elements_test;
 import 'get_library_dependencies_test.dart' as get_library_dependencies_test;
 import 'get_navigation_test.dart' as get_navigation_test;
 import 'get_reachable_sources_test.dart' as get_reachable_sources_test;
+import 'highlights2_test.dart' as highlights2_test;
 import 'highlights_test.dart' as highlights_test;
-import 'highlights_test2.dart' as highlights_test2;
 import 'lint_test.dart' as lint_test;
 import 'navigation_test.dart' as navigation_test;
 import 'occurrences_test.dart' as occurrences_test;
@@ -45,8 +45,8 @@
     get_imported_elements_test.main();
     get_navigation_test.main();
     get_reachable_sources_test.main();
+    highlights2_test.main();
     highlights_test.main();
-    highlights_test2.main();
     lint_test.main();
     navigation_test.main();
     occurrences_test.main();
diff --git a/pkg/analysis_server/test/integration/edit/get_fixes_test.dart b/pkg/analysis_server/test/integration/edit/get_fixes_test.dart
index c9e80c4..cfe923e 100644
--- a/pkg/analysis_server/test/integration/edit/get_fixes_test.dart
+++ b/pkg/analysis_server/test/integration/edit/get_fixes_test.dart
@@ -20,7 +20,7 @@
   test_has_fixes() async {
     String pathname = sourcePath('test.dart');
     String text = r'''
-Future f;
+FutureOr f;
 ''';
     writeFile(pathname, text);
     standardAnalysisSetup();
@@ -29,7 +29,7 @@
     expect(currentAnalysisErrors[pathname], isNotEmpty);
 
     EditGetFixesResult result =
-        await sendEditGetFixes(pathname, text.indexOf('Future f'));
+        await sendEditGetFixes(pathname, text.indexOf('FutureOr f'));
 
     expect(result.fixes, hasLength(1));
     AnalysisErrorFixes fix = result.fixes.first;
@@ -49,13 +49,13 @@
     String text = r'''
 import 'dart:async';
 
-Future f;
+FutureOr f;
 ''';
     writeFile(pathname, text);
     standardAnalysisSetup();
 
     EditGetFixesResult result =
-        await sendEditGetFixes(pathname, text.indexOf('Future f'));
+        await sendEditGetFixes(pathname, text.indexOf('FutureOr f'));
     expect(result.fixes, isEmpty);
   }
 }
diff --git a/pkg/analysis_server/test/search/type_hierarchy_test.dart b/pkg/analysis_server/test/search/type_hierarchy_test.dart
index f993d47..ee2f6b5 100644
--- a/pkg/analysis_server/test/search/type_hierarchy_test.dart
+++ b/pkg/analysis_server/test/search/type_hierarchy_test.dart
@@ -887,6 +887,63 @@
     expect(member2.location.offset, findOffset('test(x) {} // in Derived2'));
   }
 
+  Future<void> test_member_ofSuperclassConstraint_getter() async {
+    addTestFile('''
+class A {
+  get test => 0; // in A
+}
+
+mixin M on A {
+  get test => 0; // in M
+}
+''');
+    var items = await _getTypeHierarchy('test => 0; // in A');
+
+    var inA = items.firstWhere((e) => e.classElement.name == 'A');
+    var inM = items.firstWhere((e) => e.classElement.name == 'M');
+
+    _assertMember(inA, 'test => 0; // in A');
+    _assertMember(inM, 'test => 0; // in M');
+  }
+
+  Future<void> test_member_ofSuperclassConstraint_method() async {
+    addTestFile('''
+class A {
+  void test() {} // in A
+}
+
+mixin M on A {
+  void test() {} // in M
+}
+''');
+    var items = await _getTypeHierarchy('test() {} // in A');
+
+    var inA = items.firstWhere((e) => e.classElement.name == 'A');
+    var inM = items.firstWhere((e) => e.classElement.name == 'M');
+
+    _assertMember(inA, 'test() {} // in A');
+    _assertMember(inM, 'test() {} // in M');
+  }
+
+  Future<void> test_member_ofSuperclassConstraint_setter() async {
+    addTestFile('''
+class A {
+  set test(x) {} // in A
+}
+
+mixin M on A {
+  set test(x) {} // in M
+}
+''');
+    var items = await _getTypeHierarchy('test(x) {} // in A');
+
+    var inA = items.firstWhere((e) => e.classElement.name == 'A');
+    var inM = items.firstWhere((e) => e.classElement.name == 'M');
+
+    _assertMember(inA, 'test(x) {} // in A');
+    _assertMember(inM, 'test(x) {} // in M');
+  }
+
   Future<void> test_member_operator() async {
     addTestFile('''
 class A {
@@ -1024,6 +1081,10 @@
     expect(items, isNull);
   }
 
+  void _assertMember(TypeHierarchyItem item, String search) {
+    expect(item.memberElement.location.offset, findOffset(search));
+  }
+
   Request _createGetTypeHierarchyRequest(String search, {bool superOnly}) {
     return new SearchGetTypeHierarchyParams(testFile, findOffset(search),
             superOnly: superOnly)
diff --git a/pkg/analysis_server/test/services/correction/assist_test.dart b/pkg/analysis_server/test/services/correction/assist_test.dart
index 5b2765e..25aa478 100644
--- a/pkg/analysis_server/test/services/correction/assist_test.dart
+++ b/pkg/analysis_server/test/services/correction/assist_test.dart
@@ -746,6 +746,388 @@
     await assertNoAssistAt('f();', DartAssistKind.ASSIGN_TO_LOCAL_VARIABLE);
   }
 
+  test_convertClassToMixin_extends_noSuper() async {
+    await resolveTestUnit('''
+class A {}
+class B extends A {}
+''');
+    await assertHasAssistAt('B', DartAssistKind.CONVERT_CLASS_TO_MIXIN, '''
+class A {}
+mixin B implements A {}
+''');
+  }
+
+  test_convertClassToMixin_extends_super() async {
+    await resolveTestUnit('''
+class A {
+  a() {}
+}
+class B extends A {
+  b() {
+    super.a();
+  }
+}
+''');
+    await assertHasAssistAt('B', DartAssistKind.CONVERT_CLASS_TO_MIXIN, '''
+class A {
+  a() {}
+}
+mixin B on A {
+  b() {
+    super.a();
+  }
+}
+''');
+  }
+
+  test_convertClassToMixin_extends_superSuper() async {
+    await resolveTestUnit('''
+class A {
+  a() {}
+}
+class B extends A {}
+class C extends B {
+  c() {
+    super.a();
+  }
+}
+''');
+    await assertHasAssistAt('C', DartAssistKind.CONVERT_CLASS_TO_MIXIN, '''
+class A {
+  a() {}
+}
+class B extends A {}
+mixin C on B {
+  c() {
+    super.a();
+  }
+}
+''');
+  }
+
+  test_convertClassToMixin_extendsImplements_noSuper() async {
+    await resolveTestUnit('''
+class A {}
+class B {}
+class C extends A implements B {}
+''');
+    await assertHasAssistAt('C', DartAssistKind.CONVERT_CLASS_TO_MIXIN, '''
+class A {}
+class B {}
+mixin C implements A, B {}
+''');
+  }
+
+  test_convertClassToMixin_extendsImplements_super_extends() async {
+    await resolveTestUnit('''
+class A {
+  a() {}
+}
+class B {}
+class C extends A implements B {
+  c() {
+    super.a();
+  }
+}
+''');
+    await assertHasAssistAt('C', DartAssistKind.CONVERT_CLASS_TO_MIXIN, '''
+class A {
+  a() {}
+}
+class B {}
+mixin C on A implements B {
+  c() {
+    super.a();
+  }
+}
+''');
+  }
+
+  test_convertClassToMixin_extendsWith_noSuper() async {
+    await resolveTestUnit('''
+class A {}
+class B {}
+class C extends A with B {}
+''');
+    await assertHasAssistAt('C', DartAssistKind.CONVERT_CLASS_TO_MIXIN, '''
+class A {}
+class B {}
+mixin C implements A, B {}
+''');
+  }
+
+  test_convertClassToMixin_extendsWith_super_both() async {
+    await resolveTestUnit('''
+class A {
+  a() {}
+}
+class B {
+  b() {}
+}
+class C extends A with B {
+  c() {
+    super.a();
+    super.b();
+  }
+}
+''');
+    await assertHasAssistAt('C', DartAssistKind.CONVERT_CLASS_TO_MIXIN, '''
+class A {
+  a() {}
+}
+class B {
+  b() {}
+}
+mixin C on A, B {
+  c() {
+    super.a();
+    super.b();
+  }
+}
+''');
+  }
+
+  test_convertClassToMixin_extendsWith_super_extends() async {
+    await resolveTestUnit('''
+class A {
+  a() {}
+}
+class B {
+  b() {}
+}
+class C extends A with B {
+  c() {
+    super.a();
+  }
+}
+''');
+    await assertHasAssistAt('C', DartAssistKind.CONVERT_CLASS_TO_MIXIN, '''
+class A {
+  a() {}
+}
+class B {
+  b() {}
+}
+mixin C on A implements B {
+  c() {
+    super.a();
+  }
+}
+''');
+  }
+
+  test_convertClassToMixin_extendsWith_super_with() async {
+    await resolveTestUnit('''
+class A {
+  a() {}
+}
+class B {
+  b() {}
+}
+class C extends A with B {
+  c() {
+    super.b();
+  }
+}
+''');
+    await assertHasAssistAt('C', DartAssistKind.CONVERT_CLASS_TO_MIXIN, '''
+class A {
+  a() {}
+}
+class B {
+  b() {}
+}
+mixin C on B implements A {
+  c() {
+    super.b();
+  }
+}
+''');
+  }
+
+  test_convertClassToMixin_extendsWithImplements_noSuper() async {
+    await resolveTestUnit('''
+class A {}
+class B {}
+class C {}
+class D extends A with B implements C {}
+''');
+    await assertHasAssistAt('D', DartAssistKind.CONVERT_CLASS_TO_MIXIN, '''
+class A {}
+class B {}
+class C {}
+mixin D implements A, B, C {}
+''');
+  }
+
+  test_convertClassToMixin_extendsWithImplements_super_both() async {
+    await resolveTestUnit('''
+class A {
+  a() {}
+}
+class B {
+  b() {}
+}
+class C {}
+class D extends A with B implements C {
+  d() {
+    super.a();
+    super.b();
+  }
+}
+''');
+    await assertHasAssistAt('D', DartAssistKind.CONVERT_CLASS_TO_MIXIN, '''
+class A {
+  a() {}
+}
+class B {
+  b() {}
+}
+class C {}
+mixin D on A, B implements C {
+  d() {
+    super.a();
+    super.b();
+  }
+}
+''');
+  }
+
+  test_convertClassToMixin_extendsWithImplements_super_extends() async {
+    await resolveTestUnit('''
+class A {
+  a() {}
+}
+class B {
+  b() {}
+}
+class C {}
+class D extends A with B implements C {
+  d() {
+    super.a();
+  }
+}
+''');
+    await assertHasAssistAt('D', DartAssistKind.CONVERT_CLASS_TO_MIXIN, '''
+class A {
+  a() {}
+}
+class B {
+  b() {}
+}
+class C {}
+mixin D on A implements B, C {
+  d() {
+    super.a();
+  }
+}
+''');
+  }
+
+  test_convertClassToMixin_extendsWithImplements_super_with() async {
+    await resolveTestUnit('''
+class A {
+  a() {}
+}
+class B {
+  b() {}
+}
+class C {}
+class D extends A with B implements C {
+  d() {
+    super.b();
+  }
+}
+''');
+    await assertHasAssistAt('D', DartAssistKind.CONVERT_CLASS_TO_MIXIN, '''
+class A {
+  a() {}
+}
+class B {
+  b() {}
+}
+class C {}
+mixin D on B implements A, C {
+  d() {
+    super.b();
+  }
+}
+''');
+  }
+
+  test_convertClassToMixin_implements() async {
+    await resolveTestUnit('''
+class A {}
+class B implements A {}
+''');
+    await assertHasAssistAt('B', DartAssistKind.CONVERT_CLASS_TO_MIXIN, '''
+class A {}
+mixin B implements A {}
+''');
+  }
+
+  test_convertClassToMixin_noClauses_invalidSelection() async {
+    await resolveTestUnit('''
+class A {}
+''');
+    await assertNoAssistAt(
+      '{}',
+      DartAssistKind.CONVERT_CLASS_TO_MIXIN,
+    );
+  }
+
+  test_convertClassToMixin_noClauses_selectKeyword() async {
+    await resolveTestUnit('''
+class A {}
+''');
+    await assertHasAssistAt('class', DartAssistKind.CONVERT_CLASS_TO_MIXIN, '''
+mixin A {}
+''');
+  }
+
+  test_convertClassToMixin_noClauses_selectName() async {
+    await resolveTestUnit('''
+class A {}
+''');
+    await assertHasAssistAt('A', DartAssistKind.CONVERT_CLASS_TO_MIXIN, '''
+mixin A {}
+''');
+  }
+
+  test_convertClassToMixin_with_noSuper() async {
+    await resolveTestUnit('''
+class A {}
+class B with A {}
+''');
+    await assertHasAssistAt('B', DartAssistKind.CONVERT_CLASS_TO_MIXIN, '''
+class A {}
+mixin B implements A {}
+''');
+  }
+
+  test_convertClassToMixin_with_super() async {
+    await resolveTestUnit('''
+class A {
+  a() {}
+}
+class B with A {
+  b() {
+    super.a();
+  }
+}
+''');
+    await assertHasAssistAt('B', DartAssistKind.CONVERT_CLASS_TO_MIXIN, '''
+class A {
+  a() {}
+}
+mixin B on A {
+  b() {
+    super.a();
+  }
+}
+''');
+  }
+
   test_convertDocumentationIntoBlock_BAD_alreadyBlock() async {
     await resolveTestUnit('''
 /**
diff --git a/pkg/analysis_server/test/services/correction/fix_test.dart b/pkg/analysis_server/test/services/correction/fix_test.dart
index 63b5a1c..6e8e2f2 100644
--- a/pkg/analysis_server/test/services/correction/fix_test.dart
+++ b/pkg/analysis_server/test/services/correction/fix_test.dart
@@ -4129,6 +4129,146 @@
 ''');
   }
 
+  test_createMixin() async {
+    await resolveTestUnit('''
+main() {
+  Test v = null;
+}
+''');
+    await assertHasFix(DartFixKind.CREATE_MIXIN, '''
+main() {
+  Test v = null;
+}
+
+mixin Test {
+}
+''');
+    _assertLinkedGroup(change.linkedEditGroups[0], ['Test v =', 'Test {']);
+  }
+
+  test_createMixin_BAD_hasUnresolvedPrefix() async {
+    await resolveTestUnit('''
+main() {
+  prefix.Test v = null;
+}
+''');
+    await assertNoFix(DartFixKind.CREATE_MIXIN);
+  }
+
+  test_createMixin_BAD_instanceCreation_withNew() async {
+    await resolveTestUnit('''
+main() {
+  new Test();
+}
+''');
+    await assertNoFix(DartFixKind.CREATE_MIXIN);
+  }
+
+  test_createMixin_BAD_instanceCreation_withoutNew() async {
+    await resolveTestUnit('''
+main() {
+  Test();
+}
+''');
+    await assertNoFix(DartFixKind.CREATE_MIXIN);
+  }
+
+  test_createMixin_inLibraryOfPrefix() async {
+    String libCode = r'''
+library my.lib;
+
+class A {}
+''';
+    addSource('/project/lib.dart', libCode);
+    await resolveTestUnit('''
+import 'lib.dart' as lib;
+
+main() {
+  lib.A a = null;
+  lib.Test t = null;
+}
+''');
+    AnalysisError error = await _findErrorToFix();
+    fix = await _assertHasFix(DartFixKind.CREATE_MIXIN, error);
+    change = fix.change;
+    // apply to "lib.dart"
+    List<SourceFileEdit> fileEdits = change.edits;
+    expect(fileEdits, hasLength(1));
+    SourceFileEdit fileEdit = change.edits[0];
+    expect(fileEdit.file, convertPath('/project/lib.dart'));
+    expect(SourceEdit.applySequence(libCode, fileEdit.edits), r'''
+library my.lib;
+
+class A {}
+
+mixin Test {
+}
+''');
+    expect(change.linkedEditGroups, hasLength(1));
+  }
+
+  test_createMixin_innerLocalFunction() async {
+    await resolveTestUnit('''
+f() {
+  g() {
+    Test v = null;
+  }
+}
+''');
+    await assertHasFix(DartFixKind.CREATE_MIXIN, '''
+f() {
+  g() {
+    Test v = null;
+  }
+}
+
+mixin Test {
+}
+''');
+    _assertLinkedGroup(change.linkedEditGroups[0], ['Test v =', 'Test {']);
+  }
+
+  test_createMixin_itemOfList() async {
+    await resolveTestUnit('''
+main() {
+  var a = [Test];
+}
+''');
+    await assertHasFix(DartFixKind.CREATE_MIXIN, '''
+main() {
+  var a = [Test];
+}
+
+mixin Test {
+}
+''');
+    _assertLinkedGroup(change.linkedEditGroups[0], ['Test];', 'Test {']);
+  }
+
+  test_createMixin_itemOfList_inAnnotation() async {
+    errorFilter = (AnalysisError error) {
+      return error.errorCode == StaticWarningCode.UNDEFINED_IDENTIFIER;
+    };
+    await resolveTestUnit('''
+class MyAnnotation {
+  const MyAnnotation(a, b);
+}
+@MyAnnotation(int, const [Test])
+main() {}
+''');
+    await assertHasFix(DartFixKind.CREATE_MIXIN, '''
+class MyAnnotation {
+  const MyAnnotation(a, b);
+}
+@MyAnnotation(int, const [Test])
+main() {}
+
+mixin Test {
+}
+''');
+    _assertLinkedGroup(change.linkedEditGroups[0], ['Test])', 'Test {']);
+  }
+
   test_createNoSuchMethod_BAD_classTypeAlias() async {
     await resolveTestUnit('''
 abstract class A {
@@ -5188,6 +5328,51 @@
 ''');
   }
 
+  test_impreciseIntAsDouble() async {
+    await resolveTestUnit('''
+double x = 1000000000000000000000000;
+''');
+    await assertHasFix(DartFixKind.CHANGE_TO_NEAREST_PRECISE_VALUE, '''
+double x = 999999999999999983222784;
+''');
+  }
+
+  test_impreciseIntAsDouble_asCapitalHex() async {
+    await resolveTestUnit('''
+double x = 0X1000000000000000000000001;
+''');
+    await assertHasFix(DartFixKind.CHANGE_TO_NEAREST_PRECISE_VALUE, '''
+double x = 0x1000000000000000000000000;
+''');
+  }
+
+  test_impreciseIntAsDouble_asHex() async {
+    await resolveTestUnit('''
+double x = 0x1000000000000000000000001;
+''');
+    await assertHasFix(DartFixKind.CHANGE_TO_NEAREST_PRECISE_VALUE, '''
+double x = 0x1000000000000000000000000;
+''');
+  }
+
+  test_impreciseIntAsDouble_maxValue() async {
+    await resolveTestUnit('''
+double x = 10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000;
+''');
+    await assertHasFix(DartFixKind.CHANGE_TO_NEAREST_PRECISE_VALUE, '''
+double x = 179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368;
+''');
+  }
+
+  test_impreciseIntAsDouble_maxValue_asHex() async {
+    await resolveTestUnit('''
+double x = 0x100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000;
+''');
+    await assertHasFix(DartFixKind.CHANGE_TO_NEAREST_PRECISE_VALUE, '''
+double x = 0xFFFFFFFFFFFFF800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000;
+''');
+  }
+
   test_isNotNull() async {
     await resolveTestUnit('''
 main(p) {
diff --git a/pkg/analysis_server/test/services/search/hierarchy_test.dart b/pkg/analysis_server/test/services/search/hierarchy_test.dart
index b824347..cec129e4 100644
--- a/pkg/analysis_server/test/services/search/hierarchy_test.dart
+++ b/pkg/analysis_server/test/services/search/hierarchy_test.dart
@@ -445,6 +445,45 @@
     }
   }
 
+  test_getSuperClasses_superclassConstraints() async {
+    await _indexTestUnit('''
+class A {}
+class B extends A {}
+class C {}
+
+mixin M1 on A {}
+mixin M2 on B {}
+mixin M3 on M1 {}
+mixin M4 on M2 {}
+mixin M5 on A, C {}
+''');
+    ClassElement a = findElement('A');
+    ClassElement b = findElement('B');
+    ClassElement c = findElement('C');
+    ClassElement m1 = findElement('M1');
+    ClassElement m2 = findElement('M2');
+    ClassElement m3 = findElement('M3');
+    ClassElement m4 = findElement('M4');
+    ClassElement m5 = findElement('M5');
+    ClassElement object = a.supertype.element;
+
+    _assertSuperClasses(object, []);
+    _assertSuperClasses(a, [object]);
+    _assertSuperClasses(b, [object, a]);
+    _assertSuperClasses(c, [object]);
+
+    _assertSuperClasses(m1, [object, a]);
+    _assertSuperClasses(m2, [object, a, b]);
+    _assertSuperClasses(m3, [object, a, m1]);
+    _assertSuperClasses(m4, [object, a, b, m2]);
+    _assertSuperClasses(m5, [object, a, c]);
+  }
+
+  void _assertSuperClasses(ClassElement element, List<ClassElement> expected) {
+    var supers = getSuperClasses(element);
+    expect(supers, unorderedEquals(expected));
+  }
+
   Future<void> _indexTestUnit(String code) async {
     await resolveTestUnit(code);
   }
diff --git a/pkg/analysis_server/test/src/plugin/plugin_watcher_test.dart b/pkg/analysis_server/test/src/plugin/plugin_watcher_test.dart
index 6029159..fde7e3f 100644
--- a/pkg/analysis_server/test/src/plugin/plugin_watcher_test.dart
+++ b/pkg/analysis_server/test/src/plugin/plugin_watcher_test.dart
@@ -142,6 +142,7 @@
         resourceProvider,
         sourceFactory,
         new AnalysisOptionsImpl(),
+        new Uint32List(0),
         new Uint32List(0));
     currentSession = new AnalysisSessionImpl(this);
   }
diff --git a/pkg/analyzer/CHANGELOG.md b/pkg/analyzer/CHANGELOG.md
index 7c7f33c..c2b2c63 100644
--- a/pkg/analyzer/CHANGELOG.md
+++ b/pkg/analyzer/CHANGELOG.md
@@ -1,3 +1,7 @@
+## 0.33.0-alpha.0
+* Switch to using the parser from front_end.
+* Start implementing the new mixin syntax.
+
 ## 0.32.4
 * Updated SDK constraint to <3.0.0.
 * Updated to be compatible with Dart 2 void usage semantics.
diff --git a/pkg/analyzer/lib/dart/ast/ast.dart b/pkg/analyzer/lib/dart/ast/ast.dart
index 777bdc3..397eba4 100644
--- a/pkg/analyzer/lib/dart/ast/ast.dart
+++ b/pkg/analyzer/lib/dart/ast/ast.dart
@@ -1184,7 +1184,7 @@
  *
  * Clients may not extend, implement or mix-in this class.
  */
-abstract class ClassDeclaration extends NamedCompilationUnitMember {
+abstract class ClassDeclaration extends ClassOrMixinDeclaration {
   /**
    * Return the 'abstract' keyword, or `null` if the keyword was absent.
    */
@@ -1205,9 +1205,6 @@
    */
   void set classKeyword(Token token);
 
-  @override
-  ClassElement get declaredElement;
-
   @deprecated
   @override
   ClassElement get element;
@@ -1224,12 +1221,6 @@
   void set extendsClause(ExtendsClause extendsClause);
 
   /**
-   * Return the implements clause for the class, or `null` if the class does not
-   * implement any interfaces.
-   */
-  ImplementsClause get implementsClause;
-
-  /**
    * Set the implements clause for the class to the given [implementsClause].
    */
   void set implementsClause(ImplementsClause implementsClause);
@@ -1240,21 +1231,11 @@
   bool get isAbstract;
 
   /**
-   * Return the left curly bracket.
-   */
-  Token get leftBracket;
-
-  /**
    * Set the left curly bracket to the given [token].
    */
   void set leftBracket(Token token);
 
   /**
-   * Return the members defined by the class.
-   */
-  NodeList<ClassMember> get members;
-
-  /**
    * Return the native clause for this class, or `null` if the class does not
    * have a native clause.
    */
@@ -1266,22 +1247,11 @@
   void set nativeClause(NativeClause nativeClause);
 
   /**
-   * Return the right curly bracket.
-   */
-  Token get rightBracket;
-
-  /**
    * Set the right curly bracket to the given [token].
    */
   void set rightBracket(Token token);
 
   /**
-   * Return the type parameters for the class, or `null` if the class does not
-   * have any type parameters.
-   */
-  TypeParameterList get typeParameters;
-
-  /**
    * Set the type parameters for the class to the given list of [typeParameters].
    */
   void set typeParameters(TypeParameterList typeParameters);
@@ -1303,18 +1273,6 @@
    * default constructor will be searched for.
    */
   ConstructorDeclaration getConstructor(String name);
-
-  /**
-   * Return the field declared in the class with the given [name], or `null` if
-   * there is no such field.
-   */
-  VariableDeclaration getField(String name);
-
-  /**
-   * Return the method declared in the class with the given [name], or `null` if
-   * there is no such method.
-   */
-  MethodDeclaration getMethod(String name);
 }
 
 /**
@@ -1325,6 +1283,53 @@
 abstract class ClassMember extends Declaration {}
 
 /**
+ * The declaration of a class or mixin.
+ */
+abstract class ClassOrMixinDeclaration extends NamedCompilationUnitMember {
+  @override
+  ClassElement get declaredElement;
+
+  /**
+   * Returns the implements clause for the class/mixin, or `null` if the
+   * class/mixin does not implement any interfaces.
+   */
+  ImplementsClause get implementsClause;
+
+  /**
+   * Returns the left curly bracket.
+   */
+  Token get leftBracket;
+
+  /**
+   * Returns the members defined by the class/mixin.
+   */
+  NodeList<ClassMember> get members;
+
+  /**
+   * Returns the right curly bracket.
+   */
+  Token get rightBracket;
+
+  /**
+   * Returns the type parameters for the class/mixin, or `null` if the
+   * class/mixin does not have any type parameters.
+   */
+  TypeParameterList get typeParameters;
+
+  /**
+   * Returns the field declared in the class/mixin with the given [name], or
+   * `null` if there is no such field.
+   */
+  VariableDeclaration getField(String name);
+
+  /**
+   * Returns the method declared in the class/mixin with the given [name], or
+   * `null` if there is no such method.
+   */
+  MethodDeclaration getMethod(String name);
+}
+
+/**
  * A class type alias.
  *
  *    classTypeAlias ::=
@@ -5184,26 +5189,7 @@
  *
  * Clients may not extend, implement or mix-in this class.
  */
-abstract class MixinDeclaration extends NamedCompilationUnitMember {
-  @override
-  ClassElement get declaredElement;
-
-  /**
-   * Return the implements clause for the mixin, or `null` if the mixin does not
-   * implement any interfaces.
-   */
-  ImplementsClause get implementsClause;
-
-  /**
-   * Return the left curly bracket.
-   */
-  Token get leftBracket;
-
-  /**
-   * Return the members defined by the mixin.
-   */
-  NodeList<ClassMember> get members;
-
+abstract class MixinDeclaration extends ClassOrMixinDeclaration {
   /**
    * Return the token representing the 'mixin' keyword.
    */
@@ -5214,29 +5200,6 @@
    * any superclass constraints.
    */
   OnClause get onClause;
-
-  /**
-   * Return the right curly bracket.
-   */
-  Token get rightBracket;
-
-  /**
-   * Return the type parameters for the mixin, or `null` if the mixin does not
-   * have any type parameters.
-   */
-  TypeParameterList get typeParameters;
-
-  /**
-   * Return the field declared in the mixin with the given [name], or `null` if
-   * there is no such field.
-   */
-  VariableDeclaration getField(String name);
-
-  /**
-   * Return the method declared in the mixin with the given [name], or `null` if
-   * there is no such method.
-   */
-  MethodDeclaration getMethod(String name);
 }
 
 /**
diff --git a/pkg/analyzer/lib/dart/element/type.dart b/pkg/analyzer/lib/dart/element/type.dart
index 5aa5c3f..dc89edf 100644
--- a/pkg/analyzer/lib/dart/element/type.dart
+++ b/pkg/analyzer/lib/dart/element/type.dart
@@ -401,6 +401,13 @@
   InterfaceType get superclass;
 
   /**
+   * Return a list containing all of the super-class constraints that this
+   * mixin declaration declares. The list will be empty if this class does not
+   * represent a mixin declaration.
+   */
+  List<InterfaceType> get superclassConstraints;
+
+  /**
    * Return the element representing the getter with the given [name] that is
    * declared in this class, or `null` if this class does not declare a getter
    * with the given name.
diff --git a/pkg/analyzer/lib/error/error.dart b/pkg/analyzer/lib/error/error.dart
index bda2290..5759b93 100644
--- a/pkg/analyzer/lib/error/error.dart
+++ b/pkg/analyzer/lib/error/error.dart
@@ -61,13 +61,12 @@
   CheckedModeCompileTimeErrorCode.MAP_KEY_TYPE_NOT_ASSIGNABLE,
   CheckedModeCompileTimeErrorCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE,
   CheckedModeCompileTimeErrorCode.VARIABLE_TYPE_MISMATCH,
+  CompileTimeErrorCode.ABSTRACT_SUPER_MEMBER_REFERENCE,
   CompileTimeErrorCode.ACCESS_PRIVATE_ENUM_FIELD,
   CompileTimeErrorCode.AMBIGUOUS_EXPORT,
-  CompileTimeErrorCode.AMBIGUOUS_SUPERTYPES,
   CompileTimeErrorCode.ANNOTATION_WITH_NON_CLASS,
   CompileTimeErrorCode.ANNOTATION_WITH_TYPE_ARGUMENTS,
   CompileTimeErrorCode.ARGUMENT_DEFINITION_TEST_NON_PARAMETER,
-  CompileTimeErrorCode.ASSIGNMENT_TO_PARENTHESIZED_EXPRESSION,
   CompileTimeErrorCode.ASYNC_FOR_IN_WRONG_CONTEXT,
   CompileTimeErrorCode.AWAIT_IN_WRONG_CONTEXT,
   CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_PREFIX_NAME,
@@ -77,16 +76,14 @@
   CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_PARAMETER_NAME,
   CompileTimeErrorCode.BUILT_IN_IDENTIFIER_IN_DECLARATION,
   CompileTimeErrorCode.CASE_EXPRESSION_TYPE_IMPLEMENTS_EQUALS,
-  CompileTimeErrorCode.CONFLICTING_CONSTRUCTOR_NAME_AND_FIELD,
-  CompileTimeErrorCode.CONFLICTING_CONSTRUCTOR_NAME_AND_METHOD,
-  CompileTimeErrorCode.CONFLICTING_GETTER_AND_METHOD,
-  CompileTimeErrorCode.CONFLICTING_METHOD_AND_GETTER,
+  CompileTimeErrorCode.CONFLICTING_CONSTRUCTOR_AND_STATIC_FIELD,
+  CompileTimeErrorCode.CONFLICTING_CONSTRUCTOR_AND_STATIC_METHOD,
+  CompileTimeErrorCode.CONFLICTING_FIELD_AND_METHOD,
   CompileTimeErrorCode.CONFLICTING_GENERIC_INTERFACES,
+  CompileTimeErrorCode.CONFLICTING_METHOD_AND_FIELD,
+  CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE,
   CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_CLASS,
   CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_MEMBER,
-  CompileTimeErrorCode.CONFLICTS_WITH_CONSTRUCTOR,
-  CompileTimeErrorCode.CONFLICTS_WITH_INHERITED_MEMBER,
-  CompileTimeErrorCode.CONFLICTS_WITH_MEMBER,
   CompileTimeErrorCode.CONST_CONSTRUCTOR_IN_SUBCLASS_OF_MIXIN_APPLICATION,
   CompileTimeErrorCode.CONST_CONSTRUCTOR_THROWS_EXCEPTION,
   CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_FIELD_INITIALIZED_BY_NON_CONST,
@@ -114,27 +111,21 @@
   CompileTimeErrorCode.CONST_WITH_TYPE_PARAMETERS,
   CompileTimeErrorCode.CONST_WITH_UNDEFINED_CONSTRUCTOR,
   CompileTimeErrorCode.CONST_WITH_UNDEFINED_CONSTRUCTOR_DEFAULT,
-  CompileTimeErrorCode.CONSTRUCTOR_NOT_FOUND,
-  CompileTimeErrorCode.DECLARED_MEMBER_CONFLICTS_WITH_INHERITED,
   CompileTimeErrorCode.DEFAULT_VALUE_IN_FUNCTION_TYPED_PARAMETER,
   CompileTimeErrorCode.DEFAULT_VALUE_IN_FUNCTION_TYPE_ALIAS,
   CompileTimeErrorCode.DEFAULT_VALUE_IN_REDIRECTING_FACTORY_CONSTRUCTOR,
   CompileTimeErrorCode.DUPLICATE_CONSTRUCTOR_DEFAULT,
   CompileTimeErrorCode.DUPLICATE_CONSTRUCTOR_NAME,
   CompileTimeErrorCode.DUPLICATE_DEFINITION,
-  CompileTimeErrorCode.DUPLICATE_DEFINITION_INHERITANCE,
   CompileTimeErrorCode.DUPLICATE_NAMED_ARGUMENT,
   CompileTimeErrorCode.DUPLICATE_PART,
-  CompileTimeErrorCode.ENUM_CONSTANT_WITH_ENUM_NAME,
   CompileTimeErrorCode.EXPORT_INTERNAL_LIBRARY,
   CompileTimeErrorCode.EXPORT_OF_NON_LIBRARY,
   CompileTimeErrorCode.EXTENDS_DEFERRED_CLASS,
   CompileTimeErrorCode.EXTENDS_DISALLOWED_CLASS,
   CompileTimeErrorCode.EXTENDS_NON_CLASS,
-  CompileTimeErrorCode.EXTERNAL_CONSTRUCTOR_WITH_FIELD_INITIALIZERS,
   CompileTimeErrorCode.EXTRA_POSITIONAL_ARGUMENTS,
   CompileTimeErrorCode.EXTRA_POSITIONAL_ARGUMENTS_COULD_BE_NAMED,
-  CompileTimeErrorCode.FACTORY_REDIRECTS_TO_ABSTRACT_CLASS,
   CompileTimeErrorCode.FIELD_INITIALIZED_BY_MULTIPLE_INITIALIZERS,
   CompileTimeErrorCode.FIELD_INITIALIZED_IN_PARAMETER_AND_INITIALIZER,
   CompileTimeErrorCode.FIELD_INITIALIZER_FACTORY_CONSTRUCTOR,
@@ -145,53 +136,48 @@
   CompileTimeErrorCode.GENERIC_FUNCTION_TYPED_PARAM_UNSUPPORTED,
   CompileTimeErrorCode.GENERIC_FUNCTION_TYPE_CANNOT_BE_BOUND,
   CompileTimeErrorCode.GENERIC_FUNCTION_CANNOT_BE_TYPE_ARGUMENT,
-  CompileTimeErrorCode.GETTER_AND_METHOD_WITH_SAME_NAME,
-  CompileTimeErrorCode.ILLEGAL_MIXIN,
   CompileTimeErrorCode.IMPLEMENTS_DEFERRED_CLASS,
   CompileTimeErrorCode.IMPLEMENTS_DISALLOWED_CLASS,
   CompileTimeErrorCode.IMPLEMENTS_NON_CLASS,
   CompileTimeErrorCode.IMPLEMENTS_REPEATED,
   CompileTimeErrorCode.IMPLEMENTS_SUPER_CLASS,
-  CompileTimeErrorCode.IMPLICIT_CALL_OF_NON_METHOD,
   CompileTimeErrorCode.IMPLICIT_THIS_REFERENCE_IN_INITIALIZER,
   CompileTimeErrorCode.IMPORT_INTERNAL_LIBRARY,
   CompileTimeErrorCode.IMPORT_OF_NON_LIBRARY,
   CompileTimeErrorCode.INCONSISTENT_CASE_EXPRESSION_TYPES,
   CompileTimeErrorCode.INITIALIZER_FOR_NON_EXISTENT_FIELD,
   CompileTimeErrorCode.INITIALIZER_FOR_STATIC_FIELD,
-  CompileTimeErrorCode.INITIALIZER_OUTSIDE_CONSTRUCTOR,
   CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_NON_EXISTENT_FIELD,
   CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_STATIC_FIELD,
   CompileTimeErrorCode.INSTANCE_MEMBER_ACCESS_FROM_FACTORY,
   CompileTimeErrorCode.INSTANCE_MEMBER_ACCESS_FROM_STATIC,
   CompileTimeErrorCode.INSTANTIATE_ENUM,
   CompileTimeErrorCode.INTEGER_LITERAL_OUT_OF_RANGE,
+  CompileTimeErrorCode.INTEGER_LITERAL_IMPRECISE_AS_DOUBLE,
   CompileTimeErrorCode.INVALID_ANNOTATION,
   CompileTimeErrorCode.INVALID_ANNOTATION_FROM_DEFERRED_LIBRARY,
   CompileTimeErrorCode.INVALID_ANNOTATION_GETTER,
-  CompileTimeErrorCode.INVALID_CATCH_ARGUMENTS,
   CompileTimeErrorCode.INVALID_CONSTANT,
   CompileTimeErrorCode.INVALID_CONSTRUCTOR_NAME,
   CompileTimeErrorCode.INVALID_FACTORY_NAME_NOT_A_CLASS,
   CompileTimeErrorCode.INVALID_IDENTIFIER_IN_ASYNC,
-  CompileTimeErrorCode.INVALID_INITIALIZER,
   CompileTimeErrorCode.INVALID_MODIFIER_ON_CONSTRUCTOR,
   CompileTimeErrorCode.INVALID_MODIFIER_ON_SETTER,
+  CompileTimeErrorCode.INVALID_INLINE_FUNCTION_TYPE,
   CompileTimeErrorCode.INVALID_REFERENCE_TO_THIS,
   CompileTimeErrorCode.INVALID_TYPE_ARGUMENT_IN_CONST_LIST,
   CompileTimeErrorCode.INVALID_TYPE_ARGUMENT_IN_CONST_MAP,
   CompileTimeErrorCode.INVALID_URI,
   CompileTimeErrorCode.INVALID_USE_OF_COVARIANT,
-  CompileTimeErrorCode.INVALID_USE_OF_NULL_AWARE_ACCESS,
-  CompileTimeErrorCode.INVALID_USE_OF_VOID,
   CompileTimeErrorCode.LABEL_IN_OUTER_SCOPE,
   CompileTimeErrorCode.LABEL_UNDEFINED,
-  CompileTimeErrorCode.LOAD_LIBRARY_TAKES_NO_ARGUMENTS,
   CompileTimeErrorCode.MEMBER_WITH_CLASS_NAME,
-  CompileTimeErrorCode.METHOD_AND_GETTER_WITH_SAME_NAME,
   CompileTimeErrorCode.MISSING_CONST_IN_LIST_LITERAL,
   CompileTimeErrorCode.MISSING_CONST_IN_MAP_LITERAL,
   CompileTimeErrorCode.MISSING_DART_LIBRARY,
+  CompileTimeErrorCode.MIXIN_APPLICATION_CONCRETE_SUPER_INVOKED_MEMBER_TYPE,
+  CompileTimeErrorCode.MIXIN_APPLICATION_NOT_IMPLEMENTED_INTERFACE,
+  CompileTimeErrorCode.MIXIN_APPLICATION_NO_CONCRETE_SUPER_INVOKED_MEMBER,
   CompileTimeErrorCode.MIXIN_CLASS_DECLARES_CONSTRUCTOR,
   CompileTimeErrorCode.MIXIN_DECLARES_CONSTRUCTOR,
   CompileTimeErrorCode.MIXIN_DEFERRED_CLASS,
@@ -200,12 +186,13 @@
   CompileTimeErrorCode.MIXIN_INFERENCE_NO_MATCHING_CLASS,
   CompileTimeErrorCode.MIXIN_INFERENCE_NO_POSSIBLE_SUBSTITUTION,
   CompileTimeErrorCode.MIXIN_INHERITS_FROM_NOT_OBJECT,
+  CompileTimeErrorCode.MIXIN_INSTANTIATE,
   CompileTimeErrorCode.MIXIN_OF_DISALLOWED_CLASS,
   CompileTimeErrorCode.MIXIN_OF_NON_CLASS,
   CompileTimeErrorCode.MIXIN_REFERENCES_SUPER,
   CompileTimeErrorCode.MIXIN_SUPER_CLASS_CONSTRAINT_DEFERRED_CLASS,
   CompileTimeErrorCode.MIXIN_SUPER_CLASS_CONSTRAINT_DISALLOWED_CLASS,
-  CompileTimeErrorCode.MIXIN_SUPER_CLASS_CONSTRAINT_NON_CLASS,
+  CompileTimeErrorCode.MIXIN_SUPER_CLASS_CONSTRAINT_NON_INTERFACE,
   CompileTimeErrorCode.MIXIN_WITH_NON_CLASS_SUPERCLASS,
   CompileTimeErrorCode.MULTIPLE_REDIRECTING_CONSTRUCTOR_INVOCATIONS,
   CompileTimeErrorCode.MULTIPLE_SUPER_INITIALIZERS,
@@ -224,16 +211,13 @@
   CompileTimeErrorCode.NON_CONSTANT_VALUE_IN_INITIALIZER_FROM_DEFERRED_LIBRARY,
   CompileTimeErrorCode.NON_CONST_MAP_AS_EXPRESSION_STATEMENT,
   CompileTimeErrorCode.NON_GENERATIVE_CONSTRUCTOR,
-  CompileTimeErrorCode.NON_SYNC_ABSTRACT_METHOD,
-  CompileTimeErrorCode.NON_SYNC_CONSTRUCTOR,
   CompileTimeErrorCode.NON_SYNC_FACTORY,
-  CompileTimeErrorCode.NOT_AN_LVALUE,
-  CompileTimeErrorCode.NOT_CONSTANT_EXPRESSION,
   CompileTimeErrorCode.NOT_ENOUGH_REQUIRED_ARGUMENTS,
   CompileTimeErrorCode.NO_ANNOTATION_CONSTRUCTOR_ARGUMENTS,
   CompileTimeErrorCode.NO_DEFAULT_SUPER_CONSTRUCTOR_EXPLICIT,
   CompileTimeErrorCode.NO_DEFAULT_SUPER_CONSTRUCTOR_IMPLICIT,
   CompileTimeErrorCode.OBJECT_CANNOT_EXTEND_ANOTHER_CLASS,
+  CompileTimeErrorCode.ON_REPEATED,
   CompileTimeErrorCode.OPTIONAL_PARAMETER_IN_OPERATOR,
   CompileTimeErrorCode.PART_OF_NON_PART,
   CompileTimeErrorCode.PREFIX_COLLIDES_WITH_TOP_LEVEL_MEMBER,
@@ -244,9 +228,10 @@
   CompileTimeErrorCode.RECURSIVE_CONSTRUCTOR_REDIRECT,
   CompileTimeErrorCode.RECURSIVE_FACTORY_REDIRECT,
   CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE,
-  CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_EXTENDS,
-  CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_IMPLEMENTS,
-  CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_WITH,
+  CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_EXTENDS,
+  CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_IMPLEMENTS,
+  CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_ON,
+  CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_WITH,
   CompileTimeErrorCode.REDIRECT_GENERATIVE_TO_MISSING_CONSTRUCTOR,
   CompileTimeErrorCode.REDIRECT_GENERATIVE_TO_NON_GENERATIVE_CONSTRUCTOR,
   CompileTimeErrorCode.REDIRECT_TO_MISSING_CONSTRUCTOR,
@@ -258,13 +243,10 @@
   CompileTimeErrorCode.RETURN_IN_GENERATOR,
   CompileTimeErrorCode.SHARED_DEFERRED_PREFIX,
   CompileTimeErrorCode.SUPER_INITIALIZER_IN_OBJECT,
-  CompileTimeErrorCode.SUPER_AS_EXPRESSION,
   CompileTimeErrorCode.SUPER_IN_INVALID_CONTEXT,
   CompileTimeErrorCode.SUPER_IN_REDIRECTING_CONSTRUCTOR,
-  CompileTimeErrorCode.THIS_ACCESS_FROM_INITIALIZER,
   CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF,
   CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS,
-  CompileTimeErrorCode.TYPE_PARAMETER_IN_CONST_EXPRESSION,
   CompileTimeErrorCode.TYPE_PARAMETER_ON_CONSTRUCTOR,
   CompileTimeErrorCode.UNDEFINED_ANNOTATION,
   CompileTimeErrorCode.UNDEFINED_CLASS,
@@ -279,7 +261,6 @@
   CompileTimeErrorCode.WRONG_NUMBER_OF_PARAMETERS_FOR_SETTER,
   CompileTimeErrorCode.YIELD_EACH_IN_NON_GENERATOR,
   CompileTimeErrorCode.YIELD_IN_NON_GENERATOR,
-  HintCode.ABSTRACT_SUPER_MEMBER_REFERENCE,
   HintCode.ARGUMENT_TYPE_NOT_ASSIGNABLE,
   HintCode.CAN_BE_NULL_AFTER_NULL_AWARE,
   HintCode.DEAD_CODE,
@@ -528,7 +509,6 @@
   ParserErrorCode.VAR_RETURN_TYPE,
   ParserErrorCode.VAR_TYPEDEF,
   ParserErrorCode.WITH_BEFORE_EXTENDS,
-  ParserErrorCode.WITH_WITHOUT_EXTENDS,
   ParserErrorCode.WRONG_SEPARATOR_FOR_POSITIONAL_PARAMETER,
   ParserErrorCode.WRONG_TERMINATOR_FOR_PARAMETER_GROUP,
   ResolverErrorCode.BREAK_LABEL_ON_SWITCH_MEMBER,
@@ -581,6 +561,7 @@
   StaticTypeWarningCode.UNDEFINED_SUPER_SETTER,
   StaticTypeWarningCode.UNQUALIFIED_REFERENCE_TO_NON_LOCAL_STATIC_MEMBER,
   StaticTypeWarningCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS,
+  StaticTypeWarningCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS_CONSTRUCTOR,
   StaticTypeWarningCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS_METHOD,
   StaticTypeWarningCode.YIELD_OF_INVALID_TYPE,
   StaticWarningCode.AMBIGUOUS_IMPORT,
@@ -595,10 +576,6 @@
   StaticWarningCode.CASE_BLOCK_NOT_TERMINATED,
   StaticWarningCode.CAST_TO_NON_TYPE,
   StaticWarningCode.CONCRETE_CLASS_WITH_ABSTRACT_MEMBER,
-  StaticWarningCode.CONFLICTING_INSTANCE_METHOD_SETTER,
-  StaticWarningCode.CONFLICTING_INSTANCE_METHOD_SETTER2,
-  StaticWarningCode.CONFLICTING_STATIC_GETTER_AND_INSTANCE_SETTER,
-  StaticWarningCode.CONFLICTING_STATIC_SETTER_AND_INSTANCE_MEMBER,
   StaticWarningCode.CONST_WITH_ABSTRACT_CLASS,
   StaticWarningCode.EQUAL_KEYS_IN_MAP,
   StaticWarningCode.EXPORT_DUPLICATED_LIBRARY_NAMED,
@@ -665,14 +642,9 @@
   StaticWarningCode.TYPE_TEST_WITH_UNDEFINED_NAME,
   StaticWarningCode.UNDEFINED_CLASS,
   StaticWarningCode.UNDEFINED_CLASS_BOOLEAN,
-  StaticWarningCode.UNDEFINED_GETTER,
   StaticWarningCode.UNDEFINED_IDENTIFIER,
   StaticWarningCode.UNDEFINED_IDENTIFIER_AWAIT,
   StaticWarningCode.UNDEFINED_NAMED_PARAMETER,
-  StaticWarningCode.UNDEFINED_SETTER,
-  StaticWarningCode.UNDEFINED_STATIC_METHOD_OR_GETTER,
-  StaticWarningCode.UNDEFINED_SUPER_GETTER,
-  StaticWarningCode.UNDEFINED_SUPER_SETTER,
   StaticWarningCode.USE_OF_VOID_RESULT,
   StrongModeCode.ASSIGNMENT_CAST,
   StrongModeCode.COULD_NOT_INFER,
@@ -713,7 +685,6 @@
   StrongModeCode.NOT_INSTANTIATED_BOUND,
   StrongModeCode.TOP_LEVEL_CYCLE,
   StrongModeCode.TOP_LEVEL_FUNCTION_LITERAL_BLOCK,
-  StrongModeCode.TOP_LEVEL_FUNCTION_LITERAL_PARAMETER,
   StrongModeCode.TOP_LEVEL_IDENTIFIER_NO_TYPE,
   StrongModeCode.TOP_LEVEL_INSTANCE_GETTER,
   StrongModeCode.TOP_LEVEL_INSTANCE_METHOD,
diff --git a/pkg/analyzer/lib/source/error_processor.dart b/pkg/analyzer/lib/source/error_processor.dart
index 9a00004..b1cf472 100644
--- a/pkg/analyzer/lib/source/error_processor.dart
+++ b/pkg/analyzer/lib/source/error_processor.dart
@@ -123,9 +123,6 @@
   /// Check if this processor applies to the given [error].
   bool appliesTo(AnalysisError error) {
     ErrorCode errorCode = error.errorCode;
-    if (errorCode is StaticTypeWarningCode) {
-      return true;
-    }
     if (errorCode is StaticWarningCode) {
       return true;
     }
diff --git a/pkg/analyzer/lib/src/dart/analysis/driver.dart b/pkg/analyzer/lib/src/dart/analysis/driver.dart
index 37bd368..fc72f2b 100644
--- a/pkg/analyzer/lib/src/dart/analysis/driver.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/driver.dart
@@ -32,6 +32,7 @@
         AnalysisContext,
         AnalysisEngine,
         AnalysisOptions,
+        AnalysisOptionsImpl,
         PerformanceStatistics;
 import 'package:analyzer/src/generated/resolver.dart';
 import 'package:analyzer/src/generated/source.dart';
@@ -92,7 +93,7 @@
   /**
    * The version of data format, should be incremented on every format change.
    */
-  static const int DATA_VERSION = 65;
+  static const int DATA_VERSION = 69;
 
   /**
    * The number of exception contexts allowed to write. Once this field is
@@ -139,7 +140,7 @@
   /**
    * The analysis options to analyze with.
    */
-  AnalysisOptions _analysisOptions;
+  AnalysisOptionsImpl _analysisOptions;
 
   /**
    * The optional SDK bundle, used when the client cannot read SDK files.
@@ -163,9 +164,16 @@
   final ContextRoot contextRoot;
 
   /**
-   * The salt to mix into all hashes used as keys for serialized data.
+   * The salt to mix into all hashes used as keys for unlinked data.
    */
-  final Uint32List _salt = new Uint32List(1 + AnalysisOptions.signatureLength);
+  final Uint32List _unlinkedSalt =
+      new Uint32List(1 + AnalysisOptionsImpl.unlinkedSignatureLength);
+
+  /**
+   * The salt to mix into all hashes used as keys for linked data.
+   */
+  final Uint32List _linkedSalt =
+      new Uint32List(1 + AnalysisOptions.signatureLength);
 
   /**
    * The set of priority files, that should be analyzed sooner.
@@ -841,7 +849,7 @@
     _throwIfNotAbsolutePath(path);
     var file = fsState.getFileForPath(path);
     ApiSignature signature = new ApiSignature();
-    signature.addUint32List(_salt);
+    signature.addUint32List(_linkedSalt);
     signature.addString(file.transitiveSignature);
     return signature;
   }
@@ -1338,8 +1346,15 @@
    */
   void _createFileTracker() {
     _fillSalt();
-    _fsState = new FileSystemState(_logger, _byteStore, _contentOverlay,
-        _resourceProvider, sourceFactory, analysisOptions, _salt,
+    _fsState = new FileSystemState(
+        _logger,
+        _byteStore,
+        _contentOverlay,
+        _resourceProvider,
+        sourceFactory,
+        analysisOptions,
+        _unlinkedSalt,
+        _linkedSalt,
         externalSummaries: _externalSummaries,
         parseExceptionHandler: _storeExceptionContextDuringParsing);
     _fileTracker = new FileTracker(_logger, _fsState, _changeHook);
@@ -1380,15 +1395,14 @@
   }
 
   /**
-   * Fill [_salt] with data.
+   * Fill [_unlinkedSalt] and [_linkedSalt] with data.
    */
   void _fillSalt() {
-    _salt[0] = DATA_VERSION;
-    List<int> crossContextOptions = _analysisOptions.signature;
-    assert(crossContextOptions.length == AnalysisOptions.signatureLength);
-    for (int i = 0; i < crossContextOptions.length; i++) {
-      _salt[i + 1] = crossContextOptions[i];
-    }
+    _unlinkedSalt[0] = DATA_VERSION;
+    _unlinkedSalt.setAll(1, _analysisOptions.unlinkedSignature);
+
+    _linkedSalt[0] = DATA_VERSION;
+    _linkedSalt.setAll(1, _analysisOptions.signature);
   }
 
   /**
@@ -1458,7 +1472,7 @@
    */
   String _getResolvedUnitSignature(FileState library, FileState file) {
     ApiSignature signature = new ApiSignature();
-    signature.addUint32List(_salt);
+    signature.addUint32List(_linkedSalt);
     signature.addString(library.transitiveSignature);
     signature.addString(file.contentHash);
     return signature.toHex();
@@ -2458,10 +2472,12 @@
       FileState file = driver._fsState.getFileForPath(path);
       if (!file.isPart) {
         bool isExported = false;
-        TopLevelDeclaration declaration = file.topLevelDeclarations[name];
-        for (FileState part in file.partedFiles) {
+
+        TopLevelDeclaration declaration;
+        for (FileState part in file.libraryFiles) {
           declaration ??= part.topLevelDeclarations[name];
         }
+
         if (declaration == null) {
           declaration = file.exportedTopLevelDeclarations[name];
           isExported = true;
diff --git a/pkg/analyzer/lib/src/dart/analysis/file_state.dart b/pkg/analyzer/lib/src/dart/analysis/file_state.dart
index b048577..6fc964a 100644
--- a/pkg/analyzer/lib/src/dart/analysis/file_state.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/file_state.dart
@@ -11,8 +11,10 @@
 import 'package:analyzer/error/listener.dart';
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/src/dart/analysis/defined_names.dart';
+import 'package:analyzer/src/dart/analysis/one_phase_summaries_selector.dart';
 import 'package:analyzer/src/dart/analysis/referenced_names.dart';
 import 'package:analyzer/src/dart/analysis/top_level_declaration.dart';
+import 'package:analyzer/src/dart/analysis/unlinked_api_signature.dart';
 import 'package:analyzer/src/dart/scanner/reader.dart';
 import 'package:analyzer/src/dart/scanner/scanner.dart';
 import 'package:analyzer/src/generated/engine.dart';
@@ -125,7 +127,6 @@
   Set<String> _definedTopLevelNames;
   Set<String> _referencedNames;
   Set<String> _subtypedNames;
-  String _unlinkedKey;
   AnalysisDriverUnlinkedUnit _driverUnlinkedUnit;
   UnlinkedUnit _unlinked;
   List<int> _apiSignature;
@@ -133,6 +134,7 @@
   List<FileState> _importedFiles;
   List<FileState> _exportedFiles;
   List<FileState> _partedFiles;
+  List<FileState> _libraryFiles;
   List<NameFilter> _exportFilters;
 
   Set<FileState> _directReferencedFiles = new Set<FileState>();
@@ -246,6 +248,12 @@
   }
 
   /**
+   * The list of files files that this library consists of, i.e. this library
+   * file itself and its [partedFiles].
+   */
+  List<FileState> get libraryFiles => _libraryFiles;
+
+  /**
    * Return information about line in the file.
    */
   LineInfo get lineInfo => _lineInfo;
@@ -348,7 +356,7 @@
   String get transitiveSignature {
     if (_transitiveSignature == null) {
       ApiSignature signature = new ApiSignature();
-      signature.addUint32List(_fsState._salt);
+      signature.addUint32List(_fsState._linkedSalt);
       signature.addInt(transitiveFiles.length);
       transitiveFiles
           .map((file) => file.apiSignature)
@@ -379,7 +387,8 @@
    *
    * If an exception happens during parsing, an empty unit is returned.
    */
-  CompilationUnit parse(AnalysisErrorListener errorListener) {
+  CompilationUnit parse([AnalysisErrorListener errorListener]) {
+    errorListener ??= AnalysisErrorListener.NULL_LISTENER;
     try {
       return PerformanceStatistics.parse.makeCurrentWhile(() {
         return _parse(errorListener);
@@ -410,26 +419,38 @@
       _contentHash = rawFileState.contentHash;
     }
 
-    // Prepare the unlinked bundle key.
+    // Prepare keys of unlinked data.
+    String apiSignatureKey;
+    String unlinkedKey;
     {
-      ApiSignature signature = new ApiSignature();
-      signature.addUint32List(_fsState._salt);
+      var signature = new ApiSignature();
+      signature.addUint32List(_fsState._unlinkedSalt);
       signature.addString(_contentHash);
-      _unlinkedKey = '${signature.toHex()}.unlinked';
+
+      var signatureHex = signature.toHex();
+      apiSignatureKey = '$signatureHex.api_signature';
+      unlinkedKey = '$signatureHex.unlinked';
     }
 
-    // Prepare bytes of the unlinked bundle - existing or new.
-    List<int> bytes;
-    {
-      bytes = _fsState._byteStore.get(_unlinkedKey);
-      if (bytes == null || bytes.isEmpty) {
-        CompilationUnit unit = parse(AnalysisErrorListener.NULL_LISTENER);
-        _fsState._logger.run('Create unlinked for $path', () {
-          UnlinkedUnitBuilder unlinkedUnit = serializeAstUnlinked(unit);
-          DefinedNames definedNames = computeDefinedNames(unit);
-          List<String> referencedNames = computeReferencedNames(unit).toList();
-          List<String> subtypedNames = computeSubtypedNames(unit).toList();
-          bytes = new AnalysisDriverUnlinkedUnitBuilder(
+    // Try to get bytes of unlinked data.
+    var apiSignatureBytes = _fsState._byteStore.get(apiSignatureKey);
+    var unlinkedUnitBytes = _fsState._byteStore.get(unlinkedKey);
+
+    // Compute unlinked data that we are missing.
+    if (apiSignatureBytes == null || unlinkedUnitBytes == null) {
+      CompilationUnit unit = parse(AnalysisErrorListener.NULL_LISTENER);
+      _fsState._logger.run('Create unlinked for $path', () {
+        if (apiSignatureBytes == null) {
+          apiSignatureBytes = computeUnlinkedApiSignature(unit);
+          _fsState._byteStore.put(apiSignatureKey, apiSignatureBytes);
+        }
+        if (unlinkedUnitBytes == null) {
+          var unlinkedUnit = serializeAstUnlinked(unit,
+              serializeInferrableFields: !enableOnePhaseSummaries);
+          var definedNames = computeDefinedNames(unit);
+          var referencedNames = computeReferencedNames(unit).toList();
+          var subtypedNames = computeSubtypedNames(unit).toList();
+          unlinkedUnitBytes = new AnalysisDriverUnlinkedUnitBuilder(
                   unit: unlinkedUnit,
                   definedTopLevelNames: definedNames.topLevelNames.toList(),
                   definedClassMemberNames:
@@ -437,13 +458,14 @@
                   referencedNames: referencedNames,
                   subtypedNames: subtypedNames)
               .toBuffer();
-          _fsState._byteStore.put(_unlinkedKey, bytes);
-        });
-      }
+          _fsState._byteStore.put(unlinkedKey, unlinkedUnitBytes);
+        }
+      });
     }
 
     // Read the unlinked bundle.
-    _driverUnlinkedUnit = new AnalysisDriverUnlinkedUnit.fromBuffer(bytes);
+    _driverUnlinkedUnit =
+        new AnalysisDriverUnlinkedUnit.fromBuffer(unlinkedUnitBytes);
     _unlinked = _driverUnlinkedUnit.unit;
     _lineInfo = new LineInfo(_unlinked.lineStarts);
 
@@ -455,10 +477,9 @@
     _topLevelDeclarations = null;
 
     // Prepare API signature.
-    List<int> newApiSignature = new Uint8List.fromList(_unlinked.apiSignature);
     bool apiSignatureChanged = _apiSignature != null &&
-        !_equalByteLists(_apiSignature, newApiSignature);
-    _apiSignature = newApiSignature;
+        !_equalByteLists(_apiSignature, apiSignatureBytes);
+    _apiSignature = apiSignatureBytes;
 
     // The API signature changed.
     //   Flush transitive signatures of affected files.
@@ -505,6 +526,7 @@
           .putIfAbsent(file, () => <FileState>[])
           .add(this);
     }
+    _libraryFiles = [this]..addAll(_partedFiles);
 
     // Compute referenced files.
     Set<FileState> oldDirectReferencedFiles = _directReferencedFiles;
@@ -583,9 +605,8 @@
     _exportDeclarationsId = 0;
 
     // Append the library declarations.
-    declarations.addAll(topLevelDeclarations);
-    for (FileState part in partedFiles) {
-      declarations.addAll(part.topLevelDeclarations);
+    for (FileState file in libraryFiles) {
+      declarations.addAll(file.topLevelDeclarations);
     }
 
     // Record the declarations only if it is the full result.
@@ -674,8 +695,6 @@
   final FileState file;
 
   FileStateTestView(this.file);
-
-  String get unlinkedKey => file._unlinkedKey;
 }
 
 /**
@@ -688,7 +707,8 @@
   final FileContentOverlay _contentOverlay;
   final SourceFactory _sourceFactory;
   final AnalysisOptions _analysisOptions;
-  final Uint32List _salt;
+  final Uint32List _unlinkedSalt;
+  final Uint32List _linkedSalt;
 
   /**
    * The optional store with externally provided unlinked and corresponding
@@ -770,7 +790,8 @@
     this._resourceProvider,
     this._sourceFactory,
     this._analysisOptions,
-    this._salt, {
+    this._unlinkedSalt,
+    this._linkedSalt, {
     this.externalSummaries,
     this.parseExceptionHandler,
   }) {
@@ -921,18 +942,6 @@
     _partToLibraries.clear();
   }
 
-  void _addFileWithPath(String path, FileState file) {
-    var files = _pathToFiles[path];
-    if (files == null) {
-      knownFilePaths.add(path);
-      knownFiles.add(file);
-      files = <FileState>[];
-      _pathToFiles[path] = files;
-      fileStamp++;
-    }
-    files.add(file);
-  }
-
   /**
    * A specialized version of package:path context.toUri(). This assumes the
    * path is absolute as does a performant conversion to a file: uri.
@@ -944,6 +953,18 @@
       return new Uri(scheme: 'file', path: path);
     }
   }
+
+  void _addFileWithPath(String path, FileState file) {
+    var files = _pathToFiles[path];
+    if (files == null) {
+      knownFilePaths.add(path);
+      knownFiles.add(file);
+      files = <FileState>[];
+      _pathToFiles[path] = files;
+      fileStamp++;
+    }
+    files.add(file);
+  }
 }
 
 @visibleForTesting
diff --git a/pkg/analyzer/lib/src/dart/analysis/index.dart b/pkg/analyzer/lib/src/dart/analysis/index.dart
index 1afbb1d..69dd439 100644
--- a/pkg/analyzer/lib/src/dart/analysis/index.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/index.dart
@@ -627,6 +627,13 @@
   }
 
   @override
+  visitMixinDeclaration(MixinDeclaration node) {
+    _addSubtypeForMixinDeclaration(node);
+    recordIsAncestorOf(node.declaredElement);
+    super.visitMixinDeclaration(node);
+  }
+
+  @override
   visitOnClause(OnClause node) {
     for (TypeName typeName in node.superclassConstraints) {
       recordSuperType(typeName, IndexRelationKind.IS_IMPLEMENTED_BY);
@@ -747,8 +754,12 @@
   /**
    * Record the given class as a subclass of its direct superclasses.
    */
-  void _addSubtype(String name, TypeName superclass, WithClause withClause,
-      ImplementsClause implementsClause, List<ClassMember> memberNodes) {
+  void _addSubtype(String name,
+      {TypeName superclass,
+      WithClause withClause,
+      OnClause onClause,
+      ImplementsClause implementsClause,
+      List<ClassMember> memberNodes}) {
     List<String> supertypes = [];
     List<String> members = [];
 
@@ -770,6 +781,7 @@
 
     addSupertype(superclass);
     withClause?.mixinTypes?.forEach(addSupertype);
+    onClause?.superclassConstraints?.forEach(addSupertype);
     implementsClause?.interfaces?.forEach(addSupertype);
 
     void addMemberName(SimpleIdentifier identifier) {
@@ -802,16 +814,32 @@
    * Record the given class as a subclass of its direct superclasses.
    */
   void _addSubtypeForClassDeclaration(ClassDeclaration node) {
-    _addSubtype(node.name.name, node.extendsClause?.superclass, node.withClause,
-        node.implementsClause, node.members);
+    _addSubtype(node.name.name,
+        superclass: node.extendsClause?.superclass,
+        withClause: node.withClause,
+        implementsClause: node.implementsClause,
+        memberNodes: node.members);
   }
 
   /**
    * Record the given class as a subclass of its direct superclasses.
    */
   void _addSubtypeForClassTypeAlis(ClassTypeAlias node) {
-    _addSubtype(node.name.name, node.superclass, node.withClause,
-        node.implementsClause, const []);
+    _addSubtype(node.name.name,
+        superclass: node.superclass,
+        withClause: node.withClause,
+        implementsClause: node.implementsClause,
+        memberNodes: const []);
+  }
+
+  /**
+   * Record the given mixin as a subclass of its direct superclasses.
+   */
+  void _addSubtypeForMixinDeclaration(MixinDeclaration node) {
+    _addSubtype(node.name.name,
+        onClause: node.onClause,
+        implementsClause: node.implementsClause,
+        memberNodes: node.members);
   }
 
   /**
@@ -871,6 +899,9 @@
     for (InterfaceType mixinType in ancestor.mixins) {
       _recordIsAncestorOf(descendant, mixinType.element, true, visitedElements);
     }
+    for (InterfaceType type in ancestor.superclassConstraints) {
+      _recordIsAncestorOf(descendant, type.element, true, visitedElements);
+    }
     for (InterfaceType implementedType in ancestor.interfaces) {
       _recordIsAncestorOf(
           descendant, implementedType.element, true, visitedElements);
diff --git a/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart b/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart
index c2c7f2c..3de1ee3 100644
--- a/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart
@@ -83,9 +83,8 @@
     Map<FileState, CompilationUnit> units = {};
 
     // Parse all files.
-    units[_library] = _parse(_library);
-    for (FileState part in _library.partedFiles) {
-      units[part] = _parse(part);
+    for (FileState file in _library.libraryFiles) {
+      units[file] = _parse(file);
     }
 
     // Resolve URIs in directives to corresponding sources.
@@ -567,7 +566,7 @@
     new DeclarationResolver().resolve(unit, unitElement);
 
     unit.accept(new AstRewriteVisitor(_context.typeSystem, _libraryElement,
-        source, _typeProvider, AnalysisErrorListener.NULL_LISTENER));
+        source, _typeProvider, errorListener));
 
     // TODO(scheglov) remove EnumMemberBuilder class
 
diff --git a/pkg/analyzer/lib/src/dart/analysis/library_context.dart b/pkg/analyzer/lib/src/dart/analysis/library_context.dart
index 7988281..559ed4d 100644
--- a/pkg/analyzer/lib/src/dart/analysis/library_context.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/library_context.dart
@@ -3,11 +3,13 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:analyzer/dart/analysis/declared_variables.dart';
+import 'package:analyzer/dart/ast/ast.dart' show CompilationUnit;
 import 'package:analyzer/dart/element/element.dart'
     show CompilationUnitElement, LibraryElement;
 import 'package:analyzer/src/context/context.dart';
 import 'package:analyzer/src/dart/analysis/driver.dart';
 import 'package:analyzer/src/dart/analysis/file_state.dart';
+import 'package:analyzer/src/dart/analysis/one_phase_summaries_selector.dart';
 import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/dart/element/handle.dart';
 import 'package:analyzer/src/generated/engine.dart'
@@ -16,7 +18,9 @@
 import 'package:analyzer/src/summary/format.dart';
 import 'package:analyzer/src/summary/idl.dart';
 import 'package:analyzer/src/summary/link.dart';
+import 'package:analyzer/src/summary/one_phase.dart';
 import 'package:analyzer/src/summary/package_bundle_reader.dart';
+import 'package:analyzer/src/summary/summarize_elements.dart';
 import 'package:front_end/src/api_prototype/byte_store.dart';
 import 'package:front_end/src/base/performance_logger.dart';
 
@@ -78,11 +82,8 @@
 
           libraries[library.uriStr] = library;
 
-          // Append the defining unit.
-          store.addUnlinkedUnit(library.uriStr, library.unlinked);
-
-          // Append parts.
-          for (FileState part in library.partedFiles) {
+          // Append library units.
+          for (FileState part in library.libraryFiles) {
             store.addUnlinkedUnit(part.uriStr, part.unlinked);
           }
 
@@ -96,7 +97,8 @@
         appendLibraryFiles(targetLibrary);
       });
 
-      Set<String> libraryUrisToLink = new Set<String>();
+      var libraryUrisToLink = new Set<String>();
+      var libraryFilesToLink = new Set<FileState>();
       logger.run('Load linked bundles', () {
         for (FileState library in libraries.values) {
           if (library.exists || library == targetLibrary) {
@@ -107,6 +109,7 @@
               store.addLinkedLibrary(library.uriStr, linked);
             } else {
               libraryUrisToLink.add(library.uriStr);
+              libraryFilesToLink.add(library);
             }
           }
         }
@@ -115,16 +118,47 @@
       });
 
       Map<String, LinkedLibraryBuilder> linkedLibraries = {};
-      logger.run('Link bundles', () {
-        linkedLibraries = link(libraryUrisToLink, (String uri) {
-          LinkedLibrary linkedLibrary = store.linkedMap[uri];
-          return linkedLibrary;
-        }, (String uri) {
-          UnlinkedUnit unlinkedUnit = store.unlinkedMap[uri];
-          return unlinkedUnit;
-        }, (_) => null);
-        logger.writeln('Linked ${linkedLibraries.length} bundles.');
-      });
+      if (enableOnePhaseSummaries) {
+        var uriToUnit = <String, CompilationUnit>{};
+        logger.run('Parse files', () {
+          for (var library in libraryFilesToLink) {
+            for (var file in library.libraryFiles) {
+              uriToUnit[file.uriStr] = file.parse();
+            }
+          }
+          logger.writeln('Parsed ${uriToUnit.length} files.');
+        });
+
+        logger.run('Link libraries', () {
+          var assembler = new PackageBundleAssembler();
+          summarize(uriToUnit, store, assembler, (_) => null, true);
+
+          var bundle = assembler.assemble();
+          for (int i = 0; i < bundle.linkedLibraryUris.length; i++) {
+            var uri = bundle.linkedLibraryUris[i];
+
+            // TODO(scheglov) At the moment we might get parts here.
+            if (!libraries.containsKey(uri)) {
+              continue;
+            }
+
+            linkedLibraries[uri] = bundle.linkedLibraries[i];
+          }
+
+          logger.writeln('Linked ${linkedLibraries.length} libraries.');
+        });
+      } else {
+        logger.run('Link libraries', () {
+          linkedLibraries = link(libraryUrisToLink, (String uri) {
+            LinkedLibrary linkedLibrary = store.linkedMap[uri];
+            return linkedLibrary;
+          }, (String uri) {
+            UnlinkedUnit unlinkedUnit = store.unlinkedMap[uri];
+            return unlinkedUnit;
+          }, (_) => null);
+          logger.writeln('Linked ${linkedLibraries.length} libraries.');
+        });
+      }
 
       for (String uri in linkedLibraries.keys) {
         LinkedLibraryBuilder linkedBuilder = linkedLibraries[uri];
diff --git a/pkg/analyzer/lib/src/dart/analysis/one_phase_summaries_selector.dart b/pkg/analyzer/lib/src/dart/analysis/one_phase_summaries_selector.dart
new file mode 100644
index 0000000..c172ea1
--- /dev/null
+++ b/pkg/analyzer/lib/src/dart/analysis/one_phase_summaries_selector.dart
@@ -0,0 +1,8 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for 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 flag indicating whether analysis driver should work using one-phase,
+/// unresolved AST based summaries, or using old unlinked / link process.
+const bool enableOnePhaseSummaries =
+    const bool.fromEnvironment('enableOnePhaseSummaries', defaultValue: false);
diff --git a/pkg/analyzer/lib/src/dart/analysis/search.dart b/pkg/analyzer/lib/src/dart/analysis/search.dart
index b998712..658298a 100644
--- a/pkg/analyzer/lib/src/dart/analysis/search.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/search.dart
@@ -509,8 +509,7 @@
       String libraryPath = element.library.source.fullName;
       if (searchedFiles.add(libraryPath, this)) {
         FileState library = _driver.fsState.getFileForPath(libraryPath);
-        List<FileState> candidates = [library]..addAll(library.partedFiles);
-        for (FileState file in candidates) {
+        for (FileState file in library.libraryFiles) {
           if (file.path == path || file.referencedNames.contains(name)) {
             files.add(file.path);
           }
diff --git a/pkg/analyzer/lib/src/dart/analysis/unlinked_api_signature.dart b/pkg/analyzer/lib/src/dart/analysis/unlinked_api_signature.dart
new file mode 100644
index 0000000..e9b3c93
--- /dev/null
+++ b/pkg/analyzer/lib/src/dart/analysis/unlinked_api_signature.dart
@@ -0,0 +1,119 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for 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/token.dart';
+import 'package:analyzer/src/dart/ast/token.dart';
+import 'package:analyzer/src/summary/api_signature.dart';
+
+/// Return the bytes of the unlinked API signature of the given [unit].
+///
+/// If API signatures of two units are different, they may have different APIs.
+List<int> computeUnlinkedApiSignature(CompilationUnit unit) {
+  var computer = new _UnitApiSignatureComputer();
+  computer.compute(unit);
+  return computer.signature.toByteList();
+}
+
+class _UnitApiSignatureComputer {
+  final signature = new ApiSignature();
+
+  void addClassOrMixin(ClassOrMixinDeclaration node) {
+    addTokens(node.beginToken, node.leftBracket);
+
+    bool hasConstConstructor = node.members
+        .any((m) => m is ConstructorDeclaration && m.constKeyword != null);
+
+    signature.addInt(node.members.length);
+    for (var member in node.members) {
+      if (member is ConstructorDeclaration) {
+        var lastInitializer = member.constKeyword != null &&
+                member.initializers != null &&
+                member.initializers.isNotEmpty
+            ? member.initializers.last
+            : null;
+        addTokens(
+          member.beginToken,
+          (lastInitializer ?? member.parameters ?? member.name).endToken,
+        );
+      } else if (member is FieldDeclaration) {
+        addVariables(member, member.fields, hasConstConstructor);
+      } else if (member is MethodDeclaration) {
+        addTokens(
+          member.beginToken,
+          (member.parameters ?? member.name).endToken,
+        );
+      } else {
+        addNode(member);
+      }
+    }
+
+    addToken(node.rightBracket);
+  }
+
+  void addNode(AstNode node) {
+    addTokens(node.beginToken, node.endToken);
+  }
+
+  void addToken(Token token) {
+    signature.addString(token.lexeme);
+  }
+
+  /// Appends tokens from [begin] (including), to [end] (also including).
+  void addTokens(Token begin, Token end) {
+    if (begin is CommentToken) {
+      begin = (begin as CommentToken).parent;
+    }
+    Token token = begin;
+    while (token != null) {
+      addToken(token);
+      if (token == end) {
+        break;
+      }
+      token = token.next;
+    }
+  }
+
+  void addVariables(
+    AstNode node,
+    VariableDeclarationList variableList,
+    bool includeFinalInitializers,
+  ) {
+    if (variableList.type == null ||
+        variableList.isConst ||
+        variableList.isFinal && includeFinalInitializers) {
+      addTokens(node.beginToken, node.endToken);
+    } else {
+      addTokens(node.beginToken, variableList.type.endToken);
+
+      signature.addInt(variableList.variables.length);
+      for (var variable in variableList.variables) {
+        addTokens(variable.beginToken, variable.name.endToken);
+        addToken(variable.endToken.next); // `,` or `;`
+      }
+    }
+  }
+
+  void compute(CompilationUnit unit) {
+    signature.addInt(unit.directives.length);
+    unit.directives.forEach(addNode);
+
+    signature.addInt(unit.declarations.length);
+    for (var declaration in unit.declarations) {
+      if (declaration is ClassOrMixinDeclaration) {
+        addClassOrMixin(declaration);
+      } else if (declaration is FunctionDeclaration) {
+        var parameters = declaration.functionExpression.parameters;
+        addTokens(
+          declaration.beginToken,
+          (parameters ?? declaration.name).endToken,
+        );
+      } else if (declaration is TopLevelVariableDeclaration) {
+        addVariables(declaration, declaration.variables, false);
+      } else {
+        addNode(declaration);
+      }
+    }
+  }
+}
diff --git a/pkg/analyzer/lib/src/dart/ast/ast.dart b/pkg/analyzer/lib/src/dart/ast/ast.dart
index 573adfe..c725c8b 100644
--- a/pkg/analyzer/lib/src/dart/ast/ast.dart
+++ b/pkg/analyzer/lib/src/dart/ast/ast.dart
@@ -3,6 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'dart:collection';
+import 'dart:math' as math;
 
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/ast/syntactic_entity.dart';
@@ -1809,7 +1810,7 @@
 }
 
 abstract class ClassOrMixinDeclarationImpl
-    extends NamedCompilationUnitMemberImpl {
+    extends NamedCompilationUnitMemberImpl implements ClassOrMixinDeclaration {
   /**
    * The type parameters for the class or mixin,
    * or `null` if the declaration does not have any type parameters.
@@ -6621,6 +6622,20 @@
   @override
   Token get endToken => literal;
 
+  /**
+   * Returns whether this literal's [parent] is a [PrefixExpression] of unary
+   * negation.
+   *
+   * Note: this does *not* indicate that the value itself is negated, just that
+   * the literal is the child of a negation operation. The literal value itself
+   * will always be positive.
+   */
+  bool get immediatelyNegated {
+    AstNode parent = this.parent; // Capture for type propagation.
+    return parent is PrefixExpression &&
+        parent.operator.type == TokenType.MINUS;
+  }
+
   @override
   E accept<E>(AstVisitor<E> visitor) => visitor.visitIntegerLiteral(this);
 
@@ -6629,12 +6644,43 @@
     // There are no children to visit.
   }
 
+  static bool isValidAsDouble(String lexeme) {
+    // Less than 16 characters must be a valid double since it will be less than
+    // 9007199254740992, 0x10000000000000, both 16 characters and 53 bits.
+    if (lexeme.length < 16) {
+      return true;
+    }
+
+    BigInt fullPrecision = BigInt.tryParse(lexeme);
+    if (fullPrecision == null) {
+      return false;
+    }
+
+    // Usually handled by the length check, however, we must check this before
+    // constructing a mask later, or we'd get a negative-shift runtime error.
+    int bitLengthAsInt = fullPrecision.bitLength;
+    if (bitLengthAsInt <= 53) {
+      return true;
+    }
+
+    // This would overflow the exponent (larger than maximum double).
+    if (fullPrecision > BigInt.from(double.maxFinite)) {
+      return false;
+    }
+
+    // Say [lexeme] uses 100 bits as an integer. The bottom 47 must be 0s -- so
+    // construct a mask of 47 ones, via of 2^n - 1 where n is 47.
+    BigInt bottomMask = (BigInt.one << (bitLengthAsInt - 53)) - BigInt.one;
+
+    return fullPrecision & bottomMask == BigInt.zero;
+  }
+
   /**
    * Return `true` if the given [lexeme] is a valid lexeme for an integer
    * literal. The flag [isNegative] should be `true` if the lexeme is preceded
    * by a unary negation operator.
    */
-  static bool isValidLiteral(String lexeme, bool isNegative) {
+  static bool isValidAsInteger(String lexeme, bool isNegative) {
     // TODO(jmesserly): this depends on the platform int implementation, and
     // may not be accurate if run on dart4web.
     //
@@ -6645,6 +6691,14 @@
     if (isNegative) lexeme = '-$lexeme';
     return int.tryParse(lexeme) != null;
   }
+
+  /**
+   * Suggest the nearest valid double to a user. If the integer they wrote
+   * requires more than a 53 bit mantissa, or more than 10 exponent bits, do
+   * them the favor of suggesting the nearest integer that would work for them.
+   */
+  static double nearestValidDouble(String lexeme) =>
+      math.min(double.maxFinite, BigInt.parse(lexeme).toDouble());
 }
 
 /**
diff --git a/pkg/analyzer/lib/src/dart/ast/mixin_super_invoked_names.dart b/pkg/analyzer/lib/src/dart/ast/mixin_super_invoked_names.dart
new file mode 100644
index 0000000..b96dfe5
--- /dev/null
+++ b/pkg/analyzer/lib/src/dart/ast/mixin_super_invoked_names.dart
@@ -0,0 +1,66 @@
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/ast/token.dart';
+import 'package:analyzer/dart/ast/visitor.dart';
+
+/// Visitor that collects super-invoked names in a mixin declaration.
+class MixinSuperInvokedNamesCollector extends RecursiveAstVisitor<void> {
+  final Set<String> _names;
+
+  MixinSuperInvokedNamesCollector(this._names);
+
+  @override
+  void visitBinaryExpression(BinaryExpression node) {
+    if (node.leftOperand is SuperExpression) {
+      _names.add(node.operator.lexeme);
+    }
+    super.visitBinaryExpression(node);
+  }
+
+  @override
+  void visitIndexExpression(IndexExpression node) {
+    if (node.target is SuperExpression) {
+      if (node.inGetterContext()) {
+        _names.add('[]');
+      }
+      if (node.inSetterContext()) {
+        _names.add('[]=');
+      }
+    }
+    super.visitIndexExpression(node);
+  }
+
+  @override
+  void visitMethodInvocation(MethodInvocation node) {
+    if (node.target is SuperExpression) {
+      _names.add(node.methodName.name);
+    }
+    super.visitMethodInvocation(node);
+  }
+
+  @override
+  void visitPrefixExpression(PrefixExpression node) {
+    if (node.operand is SuperExpression) {
+      TokenType operatorType = node.operator.type;
+      if (operatorType == TokenType.MINUS) {
+        _names.add('unary-');
+      } else if (operatorType == TokenType.TILDE) {
+        _names.add('~');
+      }
+    }
+    super.visitPrefixExpression(node);
+  }
+
+  @override
+  void visitPropertyAccess(PropertyAccess node) {
+    if (node.target is SuperExpression) {
+      var name = node.propertyName.name;
+      if (node.propertyName.inGetterContext()) {
+        _names.add(name);
+      }
+      if (node.propertyName.inSetterContext()) {
+        _names.add('$name=');
+      }
+    }
+    super.visitPropertyAccess(node);
+  }
+}
diff --git a/pkg/analyzer/lib/src/dart/constant/evaluation.dart b/pkg/analyzer/lib/src/dart/constant/evaluation.dart
index d4eb48a..64ad7bf 100644
--- a/pkg/analyzer/lib/src/dart/constant/evaluation.dart
+++ b/pkg/analyzer/lib/src/dart/constant/evaluation.dart
@@ -879,6 +879,11 @@
     if (type.isUndefined) {
       return false;
     }
+    // TODO(mfairhurst): Remove this once #33441 is solved and we can use
+    // inference properly. This is a hack.
+    if (obj.type == typeProvider.intType && type == typeProvider.doubleType) {
+      return true;
+    }
     return obj.type.isSubtypeOf(type);
   }
 
diff --git a/pkg/analyzer/lib/src/dart/element/builder.dart b/pkg/analyzer/lib/src/dart/element/builder.dart
index 567dd7c..76bec62 100644
--- a/pkg/analyzer/lib/src/dart/element/builder.dart
+++ b/pkg/analyzer/lib/src/dart/element/builder.dart
@@ -14,6 +14,7 @@
 import 'package:analyzer/error/error.dart';
 import 'package:analyzer/exception/exception.dart';
 import 'package:analyzer/src/dart/ast/ast.dart';
+import 'package:analyzer/src/dart/ast/mixin_super_invoked_names.dart';
 import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/dart/element/type.dart';
 import 'package:analyzer/src/error/codes.dart';
@@ -86,23 +87,12 @@
 
     SimpleIdentifier className = node.name;
     ClassElementImpl element = new ClassElementImpl.forNode(className);
-    _setCodeRange(element, node);
-    element.metadata = _createElementAnnotations(node.metadata);
-    element.typeParameters = holder.typeParameters;
-    setElementDocumentationComment(element, node);
-    element.abstract = node.isAbstract;
-    element.accessors = holder.accessors;
-    List<ConstructorElement> constructors = holder.constructors;
-    if (constructors.isEmpty) {
-      constructors = _createDefaultConstructors(element);
-    }
-    element.constructors = constructors;
-    element.fields = holder.fields;
-    element.methods = holder.methods;
-    _currentHolder.addType(element);
     className.staticElement = element;
-    _fieldMap = null;
-    holder.validate();
+    element.abstract = node.isAbstract;
+    _fillClassElement(node, element, holder);
+
+    _currentHolder.addType(element);
+
     return null;
   }
 
@@ -591,17 +581,11 @@
 
     SimpleIdentifier nameNode = node.name;
     MixinElementImpl element = new MixinElementImpl.forNode(nameNode);
-    _setCodeRange(element, node);
-    element.metadata = _createElementAnnotations(node.metadata);
-    element.typeParameters = holder.typeParameters;
-    setElementDocumentationComment(element, node);
-    element.accessors = holder.accessors;
-    element.constructors = holder.constructors;
-    element.fields = holder.fields;
-    element.methods = holder.methods;
-    _currentHolder.addMixin(element);
     nameNode.staticElement = element;
-    holder.validate();
+    _fillClassElement(node, element, holder);
+
+    _currentHolder.addMixin(element);
+
     return null;
   }
 
@@ -716,6 +700,7 @@
       }
     } finally {
       _currentHolder = previousHolder;
+      _fieldMap = null;
     }
     return holder;
   }
@@ -770,6 +755,27 @@
     return typeArguments;
   }
 
+  void _fillClassElement(
+      AnnotatedNode node, ClassElementImpl element, ElementHolder holder) {
+    _setCodeRange(element, node);
+    setElementDocumentationComment(element, node);
+    element.metadata = _createElementAnnotations(node.metadata);
+
+    element.accessors = holder.accessors;
+
+    List<ConstructorElement> constructors = holder.constructors;
+    if (constructors.isEmpty) {
+      constructors = _createDefaultConstructors(element);
+    }
+    element.constructors = constructors;
+
+    element.fields = holder.fields;
+    element.methods = holder.methods;
+    element.typeParameters = holder.typeParameters;
+
+    holder.validate();
+  }
+
   @override
   void _setFieldParameterField(
       FormalParameter node, FieldFormalParameterElementImpl element) {
@@ -1063,6 +1069,10 @@
  * model representing the AST structure.
  */
 class ElementBuilder extends ApiElementBuilder {
+  /// List of names of methods, getters, setters, and operators that are
+  /// super-invoked in the current mixin declaration.
+  Set<String> _mixinSuperInvokedNames;
+
   /**
    * Initialize a newly created element builder to build the elements for a
    * compilation unit. The [initialHolder] is the element holder to which the
@@ -1093,6 +1103,18 @@
   }
 
   @override
+  Object visitMixinDeclaration(MixinDeclaration node) {
+    _mixinSuperInvokedNames = new Set<String>();
+    try {
+      return super.visitMixinDeclaration(node);
+    } finally {
+      MixinElementImpl element = node.declaredElement;
+      element.superInvokedNames = _mixinSuperInvokedNames.toList();
+      _mixinSuperInvokedNames = null;
+    }
+  }
+
+  @override
   Object visitVariableDeclaration(VariableDeclaration node) {
     super.visitVariableDeclaration(node);
     VariableElementImpl element = node.declaredElement as VariableElementImpl;
@@ -1100,8 +1122,12 @@
     return null;
   }
 
-  void _buildLocal(AstNode node) {
-    node.accept(new LocalElementBuilder(_currentHolder, _unitElement));
+  void _buildLocal(FunctionBody body) {
+    body.accept(new LocalElementBuilder(_currentHolder, _unitElement));
+    // This is not efficient - we visit AST second time.
+    if (_mixinSuperInvokedNames != null) {
+      body.accept(new MixinSuperInvokedNamesCollector(_mixinSuperInvokedNames));
+    }
   }
 }
 
diff --git a/pkg/analyzer/lib/src/dart/element/element.dart b/pkg/analyzer/lib/src/dart/element/element.dart
index e3c4b49..627ce03 100644
--- a/pkg/analyzer/lib/src/dart/element/element.dart
+++ b/pkg/analyzer/lib/src/dart/element/element.dart
@@ -219,6 +219,16 @@
               getter.isAccessibleIn(library) &&
               getter.enclosingElement != this));
 
+  ExecutableElement lookUpInheritedConcreteMember(
+      String name, LibraryElement library) {
+    if (name.endsWith('=')) {
+      return lookUpInheritedConcreteSetter(name, library);
+    } else {
+      return lookUpInheritedConcreteMethod(name, library) ??
+          lookUpInheritedConcreteGetter(name, library);
+    }
+  }
+
   @override
   MethodElement lookUpInheritedConcreteMethod(
           String methodName, LibraryElement library) =>
@@ -616,8 +626,8 @@
       return false;
     }
     if (supertype == null) {
-      // Should never happen, since Object is the only class that has no
-      // supertype, and it should have been caught by the test above.
+      // Should never happen, since Object and mixins are the only classes that
+      // have no supertype, and they should have been caught by the test above.
       assert(false);
       return false;
     }
@@ -637,8 +647,8 @@
         }
         classesSeen.add(nearestNonMixinClass);
         if (nearestNonMixinClass.supertype == null) {
-          // Should never happen, since Object is the only class that has no
-          // supertype, and it is not a mixin application.
+          // Should never happen, since Object and mixins are the only classes that
+          // have no supertype, and they are not mixin applications.
           assert(false);
           return false;
         }
@@ -756,7 +766,7 @@
         ResynthesizerContext context = enclosingUnit.resynthesizerContext;
         _interfaces = _unlinkedClass.interfaces
             .map((EntityRef t) => context.resolveTypeRef(this, t))
-            .where(_isClassInterfaceType)
+            .where(_isInterfaceTypeInterface)
             .cast<InterfaceType>()
             .toList(growable: false);
       }
@@ -863,7 +873,7 @@
         ResynthesizerContext context = enclosingUnit.resynthesizerContext;
         _mixins = _unlinkedClass.mixins
             .map((EntityRef t) => context.resolveTypeRef(this, t))
-            .where(_isClassInterfaceType)
+            .where(_isInterfaceTypeInterface)
             .cast<InterfaceType>()
             .toList(growable: false);
       }
@@ -898,6 +908,13 @@
     return offset;
   }
 
+  /**
+   * Names of methods, getters, setters, and operators that this mixin
+   * declaration super-invokes.  For setters this includes the trailing "=".
+   * The list will be empty if this class is not a mixin declaration.
+   */
+  List<String> get superInvokedNames => const <String>[];
+
   @override
   InterfaceType get supertype {
     if (_supertype == null) {
@@ -905,7 +922,7 @@
         if (_unlinkedClass.supertype != null) {
           DartType type = enclosingUnit.resynthesizerContext
               .resolveTypeRef(this, _unlinkedClass.supertype);
-          if (_isClassInterfaceType(type)) {
+          if (_isInterfaceTypeClass(type)) {
             _supertype = type;
           } else {
             _supertype = context.typeProvider.objectType;
@@ -1089,9 +1106,9 @@
     // forwarded to this class.
     Iterable<ConstructorElement> constructorsToForward;
     if (supertype == null) {
-      // Shouldn't ever happen, since the only class with no supertype is
-      // Object, and it isn't a mixin application.  But for safety's sake just
-      // assume an empty list.
+      // Shouldn't ever happen, since the only classes with no supertype are
+      // Object and mixins, and they aren't a mixin application. But for
+      // safety's sake just assume an empty list.
       assert(false);
       constructorsToForward = <ConstructorElement>[];
     } else if (!supertype.element.isMixinApplication) {
@@ -1172,9 +1189,22 @@
   }
 
   /**
-   * Return `true` if the given [type] is a class [InterfaceType].
+   * Return `true` if the given [type] is an [InterfaceType] that can be used
+   * as a class.
    */
-  bool _isClassInterfaceType(DartType type) {
+  bool _isInterfaceTypeClass(DartType type) {
+    if (type is InterfaceType) {
+      var element = type.element;
+      return !element.isEnum && !element.isMixin;
+    }
+    return false;
+  }
+
+  /**
+   * Return `true` if the given [type] is an [InterfaceType] that can be used
+   * as an interface or a mixin.
+   */
+  bool _isInterfaceTypeInterface(DartType type) {
     return type is InterfaceType && !type.element.isEnum;
   }
 
@@ -1285,6 +1315,9 @@
         if (supertype != null) {
           typesToVisit.add(supertype);
         }
+        for (InterfaceType type in currentType.superclassConstraints) {
+          typesToVisit.add(type);
+        }
         for (InterfaceType type in currentType.interfaces) {
           typesToVisit.add(type);
         }
@@ -3242,11 +3275,7 @@
 
   @override
   E getAncestor<E extends Element>(Predicate<Element> predicate) {
-    Element ancestor = _enclosingElement;
-    while (ancestor != null && !predicate(ancestor)) {
-      ancestor = ancestor.enclosingElement;
-    }
-    return ancestor as E;
+    return getAncestorStatic<E>(_enclosingElement, predicate);
   }
 
   /**
@@ -3391,6 +3420,15 @@
     }
     throw new StateError('Unable to find $item in $items');
   }
+
+  static E getAncestorStatic<E extends Element>(
+      Element startingPoint, Predicate<Element> predicate) {
+    Element ancestor = startingPoint;
+    while (ancestor != null && !predicate(ancestor)) {
+      ancestor = ancestor.enclosingElement;
+    }
+    return ancestor as E;
+  }
 }
 
 /**
@@ -6465,14 +6503,6 @@
   }
 
   @override
-  List<TypeParameterType> get allEnclosingTypeParameterTypes {
-    if (isStatic) {
-      return const <TypeParameterType>[];
-    }
-    return super.allEnclosingTypeParameterTypes;
-  }
-
-  @override
   String get displayName {
     String displayName = super.displayName;
     if ("unary-" == displayName) {
@@ -6590,6 +6620,13 @@
   List<InterfaceType> _superclassConstraints;
 
   /**
+   * Names of methods, getters, setters, and operators that this mixin
+   * declaration super-invokes.  For setters this includes the trailing "=".
+   * The list will be empty if this class is not a mixin declaration.
+   */
+  List<String> _superInvokedNames;
+
+  /**
    * Initialize a newly created class element to have the given [name] at the
    * given [offset] in the file that contains the declaration of this element.
    */
@@ -6619,7 +6656,7 @@
           ResynthesizerContext context = enclosingUnit.resynthesizerContext;
           constraints = _unlinkedClass.superclassConstraints
               .map((EntityRef t) => context.resolveTypeRef(this, t))
-              .where(_isClassInterfaceType)
+              .where(_isInterfaceTypeInterface)
               .cast<InterfaceType>()
               .toList(growable: false);
         }
@@ -6641,6 +6678,62 @@
       _superclassConstraints = superclassConstraints;
     }
   }
+
+  @override
+  List<String> get superInvokedNames {
+    if (_superInvokedNames == null) {
+      if (_unlinkedClass != null) {
+        _superInvokedNames = _unlinkedClass.superInvokedNames;
+      }
+    }
+    return _superInvokedNames ?? const <String>[];
+  }
+
+  void set superInvokedNames(List<String> superInvokedNames) {
+    _assertNotResynthesized(_unlinkedClass);
+    if (_unlinkedClass == null) {
+      _superInvokedNames = superInvokedNames;
+    }
+  }
+
+  @override
+  InterfaceType get supertype => null;
+
+  @override
+  void set supertype(InterfaceType supertype) {
+    throw new StateError('Attempt to set a supertype for a mixin declaratio.');
+  }
+
+  @override
+  void appendTo(StringBuffer buffer) {
+    buffer.write('mixin ');
+    String name = displayName;
+    if (name == null) {
+      // TODO(brianwilkerson) Can this happen (for either classes or mixins)?
+      buffer.write("{unnamed mixin}");
+    } else {
+      buffer.write(name);
+    }
+    int variableCount = typeParameters.length;
+    if (variableCount > 0) {
+      buffer.write("<");
+      for (int i = 0; i < variableCount; i++) {
+        if (i > 0) {
+          buffer.write(", ");
+        }
+        (typeParameters[i] as TypeParameterElementImpl).appendTo(buffer);
+      }
+      buffer.write(">");
+    }
+    if (superclassConstraints.isNotEmpty) {
+      buffer.write(' on ');
+      buffer.write(superclassConstraints.map((t) => t.displayName).join(', '));
+    }
+    if (interfaces.isNotEmpty) {
+      buffer.write(' implements ');
+      buffer.write(interfaces.map((t) => t.displayName).join(', '));
+    }
+  }
 }
 
 /**
@@ -7929,14 +8022,6 @@
   }
 
   @override
-  List<TypeParameterType> get allEnclosingTypeParameterTypes {
-    if (isStatic) {
-      return const <TypeParameterType>[];
-    }
-    return super.allEnclosingTypeParameterTypes;
-  }
-
-  @override
   PropertyAccessorElement get correspondingGetter {
     if (isGetter || variable == null) {
       return null;
@@ -8419,16 +8504,6 @@
   final UnlinkedTypeParam _unlinkedTypeParam;
 
   /**
-   * The number of type parameters whose scope overlaps this one, and which are
-   * declared earlier in the file.
-   *
-   * If the value is negative, then it represents negated De Bruijn index.
-   *
-   * TODO(scheglov) make private?
-   */
-  final int nestingLevel;
-
-  /**
    * The type defined by this type parameter.
    */
   TypeParameterType _type;
@@ -8445,7 +8520,6 @@
    */
   TypeParameterElementImpl(String name, int offset)
       : _unlinkedTypeParam = null,
-        nestingLevel = null,
         super(name, offset);
 
   /**
@@ -8453,21 +8527,20 @@
    */
   TypeParameterElementImpl.forNode(Identifier name)
       : _unlinkedTypeParam = null,
-        nestingLevel = null,
         super.forNode(name);
 
   /**
    * Initialize using the given serialized information.
    */
-  TypeParameterElementImpl.forSerialized(this._unlinkedTypeParam,
-      TypeParameterizedElementMixin enclosingElement, this.nestingLevel)
+  TypeParameterElementImpl.forSerialized(
+      this._unlinkedTypeParam, TypeParameterizedElementMixin enclosingElement)
       : super.forSerialized(enclosingElement);
 
   /**
    * Initialize a newly created synthetic type parameter element to have the
    * given [name], and with [synthetic] set to true.
    */
-  TypeParameterElementImpl.synthetic(String name, {this.nestingLevel})
+  TypeParameterElementImpl.synthetic(String name)
       : _unlinkedTypeParam = null,
         super(name, -1) {
     isSynthetic = true;
@@ -8571,12 +8644,6 @@
 abstract class TypeParameterizedElementMixin
     implements TypeParameterizedElement, ElementImpl {
   /**
-   * The cached number of type parameters that are in scope in this context, or
-   * `null` if the number has not yet been computed.
-   */
-  int _nestingLevel;
-
-  /**
    * A cached list containing the type parameters declared by this element
    * directly, or `null` if the elements have not been created yet. This does
    * not include type parameters that are declared by any enclosing elements.
@@ -8590,37 +8657,6 @@
   List<TypeParameterType> _typeParameterTypes;
 
   /**
-   * A cached list containing all of the type parameter types of this element,
-   * including those declared by this element directly and those declared by any
-   * enclosing elements, or `null` if the list has not been computed yet.
-   */
-  List<TypeParameterType> _allTypeParameterTypes;
-
-  /**
-   * Return all type parameter types of the element that encloses element.
-   * Not `null`, but might be empty for top-level and static class members.
-   */
-  List<TypeParameterType> get allEnclosingTypeParameterTypes {
-    return enclosingTypeParameterContext?.allTypeParameterTypes ??
-        const <TypeParameterType>[];
-  }
-
-  /**
-   * Return all type parameter types of this element.
-   */
-  List<TypeParameterType> get allTypeParameterTypes {
-    if (_allTypeParameterTypes == null) {
-      _allTypeParameterTypes = <TypeParameterType>[];
-      // The most logical order would be (enclosing, this).
-      // But we have to have it like this to be consistent with (inconsistent
-      // by itself) element builder for generic functions.
-      _allTypeParameterTypes.addAll(typeParameterTypes);
-      _allTypeParameterTypes.addAll(allEnclosingTypeParameterTypes);
-    }
-    return _allTypeParameterTypes;
-  }
-
-  /**
    * Get the type parameter context enclosing this one, if any.
    */
   TypeParameterizedElementMixin get enclosingTypeParameterContext;
@@ -8633,27 +8669,18 @@
   @override
   TypeParameterizedElementMixin get typeParameterContext => this;
 
-  /**
-   * Find out how many type parameters are in scope in this context.
-   */
-  int get typeParameterNestingLevel =>
-      _nestingLevel ??= (unlinkedTypeParams?.length ?? 0) +
-          (enclosingTypeParameterContext?.typeParameterNestingLevel ?? 0);
-
   @override
   List<TypeParameterElement> get typeParameters {
     if (_typeParameterElements == null) {
       List<UnlinkedTypeParam> unlinkedParams = unlinkedTypeParams;
       if (unlinkedParams != null) {
-        int enclosingNestingLevel =
-            enclosingTypeParameterContext?.typeParameterNestingLevel ?? 0;
         int numTypeParameters = unlinkedParams.length;
         _typeParameterElements =
             new List<TypeParameterElement>(numTypeParameters);
         for (int i = 0; i < numTypeParameters; i++) {
           _typeParameterElements[i] =
               new TypeParameterElementImpl.forSerialized(
-                  unlinkedParams[i], this, enclosingNestingLevel + i);
+                  unlinkedParams[i], this);
         }
       }
     }
@@ -8679,6 +8706,26 @@
   List<UnlinkedTypeParam> get unlinkedTypeParams;
 
   /**
+   * Return the given [typeParameter]'s de Bruijn index in this context, or
+   * `null` if it's not in scope.
+   *
+   * If an [offset] is provided, then it is added to the computed index.
+   */
+  int computeDeBruijnIndex(TypeParameterElement typeParameter,
+      {int offset = 0}) {
+    if (typeParameter.enclosingElement == this) {
+      var index = typeParameters.indexOf(typeParameter);
+      assert(index >= 0);
+      return typeParameters.length - index + offset;
+    } else if (enclosingTypeParameterContext != null) {
+      return enclosingTypeParameterContext.computeDeBruijnIndex(typeParameter,
+          offset: offset + typeParameters.length);
+    } else {
+      return null;
+    }
+  }
+
+  /**
    * Convert the given [index] into a type parameter type.
    */
   TypeParameterType getTypeParameterType(int index) {
@@ -8694,20 +8741,6 @@
       throw new RangeError('Invalid type parameter index');
     }
   }
-
-  /**
-   * Find out if the given [typeParameter] is in scope in this context.
-   */
-  bool isTypeParameterInScope(TypeParameterElement typeParameter) {
-    if (typeParameter.enclosingElement == this) {
-      return true;
-    } else if (enclosingTypeParameterContext != null) {
-      return enclosingTypeParameterContext
-          .isTypeParameterInScope(typeParameter);
-    } else {
-      return false;
-    }
-  }
 }
 
 /**
diff --git a/pkg/analyzer/lib/src/dart/element/type.dart b/pkg/analyzer/lib/src/dart/element/type.dart
index e13eeac..b8a110c 100644
--- a/pkg/analyzer/lib/src/dart/element/type.dart
+++ b/pkg/analyzer/lib/src/dart/element/type.dart
@@ -403,13 +403,8 @@
     for (int i = 0; i < formalCount; i++) {
       var typeParamElement = originalFormals[i];
 
-      // We don't know in which context the fresh function type will be used.
-      // So, we can only compute De Bruijn index for type parameters.
-      int negativeDeBruijnIndex = -(formalCount - i);
-
-      var freshElement = new TypeParameterElementImpl.synthetic(
-          typeParamElement.name,
-          nestingLevel: negativeDeBruijnIndex);
+      var freshElement =
+          new TypeParameterElementImpl.synthetic(typeParamElement.name);
       var freshTypeVar = new TypeParameterTypeImpl(freshElement);
       freshElement.type = freshTypeVar;
 
@@ -1344,7 +1339,7 @@
   }
 
   @override
-  bool get isObject => element.supertype == null;
+  bool get isObject => element.supertype == null && !element.isMixin;
 
   @override
   List<MethodElement> get methods {
@@ -1362,19 +1357,8 @@
 
   @override
   List<InterfaceType> get mixins {
-    ClassElement classElement = element;
-    List<InterfaceType> mixins = classElement.mixins;
-    List<TypeParameterElement> typeParameters = classElement.typeParameters;
-    List<DartType> parameterTypes = classElement.type.typeArguments;
-    if (typeParameters.length == 0) {
-      return mixins;
-    }
-    int count = mixins.length;
-    List<InterfaceType> typedMixins = new List<InterfaceType>(count);
-    for (int i = 0; i < count; i++) {
-      typedMixins[i] = mixins[i].substitute2(typeArguments, parameterTypes);
-    }
-    return typedMixins;
+    List<InterfaceType> mixins = element.mixins;
+    return _instantiateSuperTypes(mixins);
   }
 
   @override
@@ -1393,6 +1377,12 @@
   }
 
   @override
+  List<InterfaceType> get superclassConstraints {
+    List<InterfaceType> constraints = element.superclassConstraints;
+    return _instantiateSuperTypes(constraints);
+  }
+
+  @override
   List<DartType> get typeArguments {
     if (_typeArguments == null) {
       try {
@@ -1505,10 +1495,9 @@
     ClassElement jElement = j.element;
     InterfaceType supertype = jElement.supertype;
     //
-    // If J has no direct supertype then it is Object, and Object has no direct
-    // supertypes.
+    // If J is Object, then it has no direct supertypes.
     //
-    if (supertype == null) {
+    if (j.isObject) {
       return false;
     }
     //
@@ -1521,6 +1510,15 @@
       return true;
     }
     //
+    // I is listed in the on clause of J.
+    //
+    for (InterfaceType interfaceType in jElement.superclassConstraints) {
+      interfaceType = interfaceType.substitute2(jArgs, jVars);
+      if (interfaceType == i) {
+        return true;
+      }
+    }
+    //
     // I is listed in the implements clause of J.
     //
     for (InterfaceType interfaceType in jElement.interfaces) {
@@ -1702,6 +1700,12 @@
         return element;
       }
     }
+    for (InterfaceType constraint in superclassConstraints) {
+      PropertyAccessorElement element = constraint.getGetter(getterName);
+      if (element != null && element.isAccessibleIn(library)) {
+        return element;
+      }
+    }
     HashSet<ClassElement> visitedClasses = new HashSet<ClassElement>();
     InterfaceType supertype = superclass;
     ClassElement supertypeElement = supertype?.element;
@@ -1756,6 +1760,69 @@
         (InterfaceType t) => t.getGetter(name) ?? t.getMethod(name));
   }
 
+  ExecutableElement lookUpInheritedMember(String name, LibraryElement library,
+      {bool concrete: false, bool setter: false}) {
+    HashSet<ClassElement> visitedClasses = new HashSet<ClassElement>();
+
+    ExecutableElement lookUpImpl(InterfaceTypeImpl type,
+        {bool acceptAbstract: false, bool includeType: true}) {
+      if (type == null || !visitedClasses.add(type.element)) {
+        return null;
+      }
+
+      if (includeType) {
+        ExecutableElement result;
+        if (setter) {
+          result = type.getSetter(name);
+        } else {
+          result = type.getMethod(name);
+          result ??= type.getGetter(name);
+        }
+        if (result != null && result.isAccessibleIn(library)) {
+          if (!concrete || acceptAbstract || !result.isAbstract) {
+            return result;
+          }
+          ClassElementImpl elementImpl = type.element;
+          if (elementImpl.hasNoSuchMethod) {
+            return result;
+          }
+        }
+      }
+
+      for (InterfaceType mixin in type.mixins.reversed) {
+        var result = lookUpImpl(mixin, acceptAbstract: acceptAbstract);
+        if (result != null) {
+          return result;
+        }
+      }
+
+      // We were not able to find the concrete dispatch target.
+      // It is OK to look into interfaces, we need just some resolution now.
+      if (!concrete) {
+        for (InterfaceType mixin in type.interfaces) {
+          var result = lookUpImpl(mixin, acceptAbstract: acceptAbstract);
+          if (result != null) {
+            return result;
+          }
+        }
+      }
+
+      return lookUpImpl(type.superclass, acceptAbstract: acceptAbstract);
+    }
+
+    if (element.isMixin) {
+      for (InterfaceType constraint in superclassConstraints) {
+        var result = lookUpImpl(constraint, acceptAbstract: true);
+        if (result != null) {
+          return result;
+        }
+      }
+      return null;
+    } else {
+      return lookUpImpl(this, includeType: false);
+    }
+  }
+
   @override
   MethodElement lookUpInheritedMethod(String name,
       {LibraryElement library, bool thisType: true}) {
@@ -1806,6 +1873,12 @@
         return element;
       }
     }
+    for (InterfaceType constraint in superclassConstraints) {
+      MethodElement element = constraint.getMethod(methodName);
+      if (element != null && element.isAccessibleIn(library)) {
+        return element;
+      }
+    }
     HashSet<ClassElement> visitedClasses = new HashSet<ClassElement>();
     InterfaceType supertype = superclass;
     ClassElement supertypeElement = supertype?.element;
@@ -1846,6 +1919,12 @@
         return element;
       }
     }
+    for (InterfaceType constraint in superclassConstraints) {
+      PropertyAccessorElement element = constraint.getSetter(setterName);
+      if (element != null && element.isAccessibleIn(library)) {
+        return element;
+      }
+    }
     HashSet<ClassElement> visitedClasses = new HashSet<ClassElement>();
     InterfaceType supertype = superclass;
     ClassElement supertypeElement = supertype?.element;
@@ -1930,6 +2009,20 @@
     }
   }
 
+  List<InterfaceType> _instantiateSuperTypes(List<InterfaceType> defined) {
+    List<TypeParameterElement> typeParameters = element.typeParameters;
+    if (typeParameters.isEmpty) {
+      return defined;
+    }
+    List<DartType> instantiated = element.type.typeArguments;
+    int count = defined.length;
+    List<InterfaceType> typedConstraints = new List<InterfaceType>(count);
+    for (int i = 0; i < count; i++) {
+      typedConstraints[i] = defined[i].substitute2(typeArguments, instantiated);
+    }
+    return typedConstraints;
+  }
+
   /**
    * Starting from this type, search its class hierarchy for types of the form
    * Future<R>, and return a list of the resulting R's.
@@ -2118,33 +2211,44 @@
       InterfaceType type, int depth, HashSet<ClassElement> visitedTypes) {
     ClassElement classElement = type.element;
     // Object case
-    if (classElement.supertype == null || visitedTypes.contains(classElement)) {
+    if (type.isObject || visitedTypes.contains(classElement)) {
       return depth;
     }
     int longestPath = 1;
     try {
       visitedTypes.add(classElement);
-      List<InterfaceType> superinterfaces = classElement.interfaces;
       int pathLength;
-      if (superinterfaces.length > 0) {
-        // loop through each of the superinterfaces recursively calling this
-        // method and keeping track of the longest path to return
-        for (InterfaceType superinterface in superinterfaces) {
-          pathLength = _computeLongestInheritancePathToObject(
-              superinterface, depth + 1, visitedTypes);
-          if (pathLength > longestPath) {
-            longestPath = pathLength;
-          }
+
+      // loop through each of the superinterfaces recursively calling this
+      // method and keeping track of the longest path to return
+      for (InterfaceType interface in classElement.superclassConstraints) {
+        pathLength = _computeLongestInheritancePathToObject(
+            interface, depth + 1, visitedTypes);
+        if (pathLength > longestPath) {
+          longestPath = pathLength;
         }
       }
+
+      // loop through each of the superinterfaces recursively calling this
+      // method and keeping track of the longest path to return
+      for (InterfaceType interface in classElement.interfaces) {
+        pathLength = _computeLongestInheritancePathToObject(
+            interface, depth + 1, visitedTypes);
+        if (pathLength > longestPath) {
+          longestPath = pathLength;
+        }
+      }
+
       // finally, perform this same check on the super type
       // TODO(brianwilkerson) Does this also need to add in the number of mixin
       // classes?
       InterfaceType supertype = classElement.supertype;
-      pathLength = _computeLongestInheritancePathToObject(
-          supertype, depth + 1, visitedTypes);
-      if (pathLength > longestPath) {
-        longestPath = pathLength;
+      if (supertype != null) {
+        pathLength = _computeLongestInheritancePathToObject(
+            supertype, depth + 1, visitedTypes);
+        if (pathLength > longestPath) {
+          longestPath = pathLength;
+        }
       }
     } finally {
       visitedTypes.remove(classElement);
diff --git a/pkg/analyzer/lib/src/dart/error/hint_codes.dart b/pkg/analyzer/lib/src/dart/error/hint_codes.dart
index 73b516c..7de60e2 100644
--- a/pkg/analyzer/lib/src/dart/error/hint_codes.dart
+++ b/pkg/analyzer/lib/src/dart/error/hint_codes.dart
@@ -13,18 +13,6 @@
  */
 class HintCode extends ErrorCode {
   /**
-   * When an abstract supertype member is referenced with `super` as its target,
-   * it cannot be overridden, so it is always a runtime error.
-   *
-   * Parameters:
-   * 0: the display name for the kind of the referenced element
-   * 1: the name of the referenced element
-   */
-  static const HintCode ABSTRACT_SUPER_MEMBER_REFERENCE = const HintCode(
-      'ABSTRACT_SUPER_MEMBER_REFERENCE',
-      "The {0} '{1}' is always abstract in the supertype.");
-
-  /**
    * This hint is generated anywhere where the
    * [StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE] would have been generated,
    * if we used propagated information for the warnings.
diff --git a/pkg/analyzer/lib/src/dart/error/syntactic_errors.dart b/pkg/analyzer/lib/src/dart/error/syntactic_errors.dart
index c1361b0..b75e8d1 100644
--- a/pkg/analyzer/lib/src/dart/error/syntactic_errors.dart
+++ b/pkg/analyzer/lib/src/dart/error/syntactic_errors.dart
@@ -11,6 +11,8 @@
 
 export 'package:front_end/src/scanner/errors.dart' show ScannerErrorCode;
 
+part 'syntactic_errors.g.dart';
+
 /**
  * The error codes used for errors detected by the parser. The convention for
  * this class is for the name of the error code to indicate the problem that
@@ -132,10 +134,8 @@
           "Constructors can't have a return type.",
           correction: "Try removing the return type.");
 
-  static const ParserErrorCode CONTINUE_OUTSIDE_OF_LOOP = const ParserErrorCode(
-      'CONTINUE_OUTSIDE_OF_LOOP',
-      "A continue statement can't be used outside of a loop or switch statement.",
-      correction: "Try removing the continue statement.");
+  static const ParserErrorCode CONTINUE_OUTSIDE_OF_LOOP =
+      _CONTINUE_OUTSIDE_OF_LOOP;
 
   static const ParserErrorCode CONTINUE_WITHOUT_LABEL_IN_CASE = const ParserErrorCode(
       'CONTINUE_WITHOUT_LABEL_IN_CASE',
@@ -148,10 +148,7 @@
       "The modifier 'covariant' should be before the modifier 'final'.",
       correction: "Try re-ordering the modifiers.");
 
-  static const ParserErrorCode COVARIANT_AFTER_VAR = const ParserErrorCode(
-      'COVARIANT_AFTER_VAR',
-      "The modifier 'covariant' should be before the modifier 'final'.",
-      correction: "Try re-ordering the modifiers.");
+  static const ParserErrorCode COVARIANT_AFTER_VAR = _COVARIANT_AFTER_VAR;
 
   static const ParserErrorCode COVARIANT_AND_STATIC = const ParserErrorCode(
       'COVARIANT_AND_STATIC',
@@ -225,9 +222,7 @@
       correction: "Try moving the enum to the top-level.");
 
   static const ParserErrorCode EQUALITY_CANNOT_BE_EQUALITY_OPERAND =
-      const ParserErrorCode('EQUALITY_CANNOT_BE_EQUALITY_OPERAND',
-          "An equality expression can't be an operand of another equality expression.",
-          correction: "Try re-writing the expression.");
+      _EQUALITY_CANNOT_BE_EQUALITY_OPERAND;
 
   static const ParserErrorCode EXPECTED_CASE_OR_DEFAULT = const ParserErrorCode(
       'EXPECTED_CASE_OR_DEFAULT', "Expected 'case' or 'default'.",
@@ -282,9 +277,7 @@
       "The modifier 'external' should be before the modifier 'static'.",
       correction: "Try re-ordering the modifiers.");
 
-  static const ParserErrorCode EXTERNAL_CLASS = const ParserErrorCode(
-      'EXTERNAL_CLASS', "Classes can't be declared to be 'external'.",
-      correction: "Try removing the keyword 'external'.");
+  static const ParserErrorCode EXTERNAL_CLASS = _EXTERNAL_CLASS;
 
   static const ParserErrorCode EXTERNAL_CONSTRUCTOR_WITH_BODY =
       const ParserErrorCode('EXTERNAL_CONSTRUCTOR_WITH_BODY',
@@ -292,9 +285,7 @@
           correction: "Try removing the body of the constructor, or "
               "removing the keyword 'external'.");
 
-  static const ParserErrorCode EXTERNAL_ENUM = const ParserErrorCode(
-      'EXTERNAL_ENUM', "Enums can't be declared to be 'external'.",
-      correction: "Try removing the keyword 'external'.");
+  static const ParserErrorCode EXTERNAL_ENUM = _EXTERNAL_ENUM;
 
   static const ParserErrorCode EXTERNAL_FIELD = const ParserErrorCode(
       'EXTERNAL_FIELD', "Fields can't be declared to be 'external'.",
@@ -424,10 +415,7 @@
       correction: "Try moving the with clause before the implements clause.");
 
   static const ParserErrorCode IMPORT_DIRECTIVE_AFTER_PART_DIRECTIVE =
-      const ParserErrorCode('IMPORT_DIRECTIVE_AFTER_PART_DIRECTIVE',
-          "Import directives must preceed part directives.",
-          correction:
-              "Try moving the import directives before the part directives.");
+      _IMPORT_DIRECTIVE_AFTER_PART_DIRECTIVE;
 
   static const ParserErrorCode INITIALIZED_VARIABLE_IN_FOR_EACH =
       const ParserErrorCode('INITIALIZED_VARIABLE_IN_FOR_EACH',
@@ -435,10 +423,7 @@
           correction:
               "Try removing the initializer, or using a different kind of loop.");
 
-  static const ParserErrorCode INVALID_AWAIT_IN_FOR = const ParserErrorCode(
-      'INVALID_AWAIT_IN_FOR',
-      "The keyword 'await' isn't allowed for a normal 'for' statement.",
-      correction: "Try removing the keyword, or use a for-each statement.");
+  static const ParserErrorCode INVALID_AWAIT_IN_FOR = _INVALID_AWAIT_IN_FOR;
 
   /**
    * Parameters:
@@ -466,7 +451,8 @@
 
   static const ParserErrorCode INVALID_HEX_ESCAPE = const ParserErrorCode(
       'INVALID_HEX_ESCAPE',
-      "An escape sequence starting with '\\x' must be followed by 2 hexidecimal digits.");
+      "An escape sequence starting with '\\x' "
+      "must be followed by 2 hexadecimal digits.");
 
   static const ParserErrorCode INVALID_LITERAL_IN_CONFIGURATION =
       const ParserErrorCode('INVALID_LITERAL_IN_CONFIGURATION',
@@ -501,7 +487,7 @@
   static const ParserErrorCode INVALID_UNICODE_ESCAPE = const ParserErrorCode(
       'INVALID_UNICODE_ESCAPE',
       "An escape sequence starting with '\\u' must be followed by 4 "
-      "hexidecimal digits or from 1 to 6 digits between '{' and '}'.");
+      "hexadecimal digits or from 1 to 6 digits between '{' and '}'.");
 
   static const ParserErrorCode LIBRARY_DIRECTIVE_NOT_FIRST =
       const ParserErrorCode('LIBRARY_DIRECTIVE_NOT_FIRST',
@@ -617,17 +603,14 @@
           correction: "Try adding a library name after the 'of'.");
 
   static const ParserErrorCode MISSING_PREFIX_IN_DEFERRED_IMPORT =
-      const ParserErrorCode('MISSING_PREFIX_IN_DEFERRED_IMPORT',
-          "Deferred imports should have a prefix.",
-          correction: "Try adding a prefix to the import.");
+      _MISSING_PREFIX_IN_DEFERRED_IMPORT;
 
   static const ParserErrorCode MISSING_STAR_AFTER_SYNC = const ParserErrorCode(
       'MISSING_STAR_AFTER_SYNC',
       "The modifier 'sync' must be followed by a star ('*').",
       correction: "Try removing the modifier, or add a star.");
 
-  static const ParserErrorCode MISSING_STATEMENT =
-      const ParserErrorCode('MISSING_STATEMENT', "Expected a statement.");
+  static const ParserErrorCode MISSING_STATEMENT = _MISSING_STATEMENT;
 
   /**
    * Parameters:
@@ -653,11 +636,8 @@
       "Can't have both positional and named parameters in a single parameter list.",
       correction: "Try choosing a single style of optional parameters.");
 
-  static const ParserErrorCode MULTIPLE_EXTENDS_CLAUSES = const ParserErrorCode(
-      'MULTIPLE_EXTENDS_CLAUSES',
-      "Each class definition can have at most one extends clause.",
-      correction:
-          "Try choosing one superclass and define your class to implement (or mix in) the others.");
+  static const ParserErrorCode MULTIPLE_EXTENDS_CLAUSES =
+      _MULTIPLE_EXTENDS_CLAUSES;
 
   static const ParserErrorCode MULTIPLE_IMPLEMENTS_CLAUSES = const ParserErrorCode(
       'MULTIPLE_IMPLEMENTS_CLAUSES',
@@ -666,24 +646,17 @@
           "Try combining all of the implements clauses into a single clause.");
 
   static const ParserErrorCode MULTIPLE_LIBRARY_DIRECTIVES =
-      const ParserErrorCode('MULTIPLE_LIBRARY_DIRECTIVES',
-          "Only one library directive may be declared in a file.",
-          correction: "Try removing all but one of the library directives.");
+      _MULTIPLE_LIBRARY_DIRECTIVES;
 
   static const ParserErrorCode MULTIPLE_NAMED_PARAMETER_GROUPS =
       const ParserErrorCode('MULTIPLE_NAMED_PARAMETER_GROUPS',
           "Can't have multiple groups of named parameters in a single parameter list.",
           correction: "Try combining all of the groups into a single group.");
 
-  static const ParserErrorCode MULTIPLE_ON_CLAUSES = const ParserErrorCode(
-      'MULTIPLE_ON_CLAUSES',
-      "Each mixin definition can have at most one on clause.",
-      correction: "Try combining all of the on clauses into a single clause.");
+  static const ParserErrorCode MULTIPLE_ON_CLAUSES = _MULTIPLE_ON_CLAUSES;
 
   static const ParserErrorCode MULTIPLE_PART_OF_DIRECTIVES =
-      const ParserErrorCode('MULTIPLE_PART_OF_DIRECTIVES',
-          "Only one part-of directive may be declared in a file.",
-          correction: "Try removing all but one of the part-of directives.");
+      _MULTIPLE_PART_OF_DIRECTIVES;
 
   static const ParserErrorCode MULTIPLE_POSITIONAL_PARAMETER_GROUPS =
       const ParserErrorCode('MULTIPLE_POSITIONAL_PARAMETER_GROUPS',
@@ -702,11 +675,7 @@
           correction:
               "Try moving all but one of the declarations inside the loop body.");
 
-  static const ParserErrorCode MULTIPLE_WITH_CLAUSES = const ParserErrorCode(
-      'MULTIPLE_WITH_CLAUSES',
-      "Each class definition can have at most one with clause.",
-      correction:
-          "Try combining all of the with clauses into a single clause.");
+  static const ParserErrorCode MULTIPLE_WITH_CLAUSES = _MULTIPLE_WITH_CLAUSES;
 
   static const ParserErrorCode NAMED_FUNCTION_EXPRESSION = const ParserErrorCode(
       'NAMED_FUNCTION_EXPRESSION', "Function expressions can't be named.",
@@ -737,10 +706,7 @@
           correction: "Try removing the word 'native'.");
 
   static const ParserErrorCode NATIVE_CLAUSE_SHOULD_BE_ANNOTATION =
-      const ParserErrorCode('NATIVE_CLAUSE_SHOULD_BE_ANNOTATION',
-          "Native clause in this form is deprecated.",
-          correction: "Try removing this native clause and adding @native()"
-              " or @native('native-name') before the declaration.");
+      _NATIVE_CLAUSE_SHOULD_BE_ANNOTATION;
 
   static const ParserErrorCode NON_CONSTRUCTOR_FACTORY = const ParserErrorCode(
       'NON_CONSTRUCTOR_FACTORY',
@@ -809,22 +775,14 @@
           correction:
               "Try surrounding the positional parameters in square brackets.");
 
-  static const ParserErrorCode PREFIX_AFTER_COMBINATOR = const ParserErrorCode(
-      'PREFIX_AFTER_COMBINATOR',
-      "The prefix ('as' clause) should come before any show/hide combinators.",
-      correction: "Try moving the prefix before the combinators.");
+  static const ParserErrorCode PREFIX_AFTER_COMBINATOR =
+      _PREFIX_AFTER_COMBINATOR;
 
   static const ParserErrorCode REDIRECTING_CONSTRUCTOR_WITH_BODY =
-      const ParserErrorCode('REDIRECTING_CONSTRUCTOR_WITH_BODY',
-          "Redirecting constructors can't have a body.",
-          correction: "Try removing the body, or "
-              "not making this a redirecting constructor.");
+      _REDIRECTING_CONSTRUCTOR_WITH_BODY;
 
   static const ParserErrorCode REDIRECTION_IN_NON_FACTORY_CONSTRUCTOR =
-      const ParserErrorCode('REDIRECTION_IN_NON_FACTORY_CONSTRUCTOR',
-          "Only factory constructor can specify '=' redirection.",
-          correction: "Try making this a factory constructor, or "
-              "not making this a redirecting constructor.");
+      _REDIRECTION_IN_NON_FACTORY_CONSTRUCTOR;
 
   static const ParserErrorCode SETTER_IN_FUNCTION = const ParserErrorCode(
       'SETTER_IN_FUNCTION',
@@ -836,33 +794,20 @@
       "The file has too many nested expressions or statements.",
       correction: "Try simplifying the code.");
 
-  static const ParserErrorCode STATIC_AFTER_CONST = const ParserErrorCode(
-      'STATIC_AFTER_CONST',
-      "The modifier 'static' should be before the modifier 'const'.",
-      correction: "Try re-ordering the modifiers.");
+  static const ParserErrorCode STATIC_AFTER_CONST = _STATIC_AFTER_CONST;
 
-  static const ParserErrorCode STATIC_AFTER_FINAL = const ParserErrorCode(
-      'STATIC_AFTER_FINAL',
-      "The modifier 'static' should be before the modifier 'final'.",
-      correction: "Try re-ordering the modifiers.");
+  static const ParserErrorCode STATIC_AFTER_FINAL = _STATIC_AFTER_FINAL;
 
-  static const ParserErrorCode STATIC_AFTER_VAR = const ParserErrorCode(
-      'STATIC_AFTER_VAR',
-      "The modifier 'static' should be before the modifier 'var'.",
-      correction: "Try re-ordering the modifiers.");
+  static const ParserErrorCode STATIC_AFTER_VAR = _STATIC_AFTER_VAR;
 
-  static const ParserErrorCode STATIC_CONSTRUCTOR = const ParserErrorCode(
-      'STATIC_CONSTRUCTOR', "Constructors can't be static.",
-      correction: "Try removing the keyword 'static'.");
+  static const ParserErrorCode STATIC_CONSTRUCTOR = _STATIC_CONSTRUCTOR;
 
   static const ParserErrorCode STATIC_GETTER_WITHOUT_BODY = const ParserErrorCode(
       'STATIC_GETTER_WITHOUT_BODY', "A 'static' getter must have a body.",
       correction:
           "Try adding a body to the getter, or removing the keyword 'static'.");
 
-  static const ParserErrorCode STATIC_OPERATOR = const ParserErrorCode(
-      'STATIC_OPERATOR', "Operators can't be static.",
-      correction: "Try removing the keyword 'static'.");
+  static const ParserErrorCode STATIC_OPERATOR = _STATIC_OPERATOR;
 
   static const ParserErrorCode STATIC_SETTER_WITHOUT_BODY = const ParserErrorCode(
       'STATIC_SETTER_WITHOUT_BODY', "A 'static' setter must have a body.",
@@ -875,30 +820,17 @@
           correction: "Try removing the keyword 'static'.");
 
   static const ParserErrorCode SWITCH_HAS_CASE_AFTER_DEFAULT_CASE =
-      const ParserErrorCode('SWITCH_HAS_CASE_AFTER_DEFAULT_CASE',
-          "The default case should be the last case in a switch statement.",
-          correction:
-              "Try moving the default case after the other case clauses.");
+      _SWITCH_HAS_CASE_AFTER_DEFAULT_CASE;
 
   static const ParserErrorCode SWITCH_HAS_MULTIPLE_DEFAULT_CASES =
-      const ParserErrorCode('SWITCH_HAS_MULTIPLE_DEFAULT_CASES',
-          "The 'default' case can only be declared once.",
-          correction: "Try removing all but one default case.");
+      _SWITCH_HAS_MULTIPLE_DEFAULT_CASES;
 
-  static const ParserErrorCode TOP_LEVEL_OPERATOR = const ParserErrorCode(
-      'TOP_LEVEL_OPERATOR', "Operators must be declared within a class.",
-      correction: "Try removing the operator, "
-          "moving it to a class, or "
-          "converting it to be a function.");
+  static const ParserErrorCode TOP_LEVEL_OPERATOR = _TOP_LEVEL_OPERATOR;
 
   static const ParserErrorCode TYPE_ARGUMENTS_ON_TYPE_VARIABLE =
-      const ParserErrorCode('TYPE_ARGUMENTS_ON_TYPE_VARIABLE',
-          "Can't use type arguments with type variable '{0}'.",
-          correction: "Try removing the type arguments.");
+      _TYPE_ARGUMENTS_ON_TYPE_VARIABLE;
 
-  static const ParserErrorCode TYPEDEF_IN_CLASS = const ParserErrorCode(
-      'TYPEDEF_IN_CLASS', "Typedefs can't be declared inside classes.",
-      correction: "Try moving the typedef to the top-level.");
+  static const ParserErrorCode TYPEDEF_IN_CLASS = _TYPEDEF_IN_CLASS;
 
   /**
    * Parameters:
@@ -917,15 +849,7 @@
       'UNEXPECTED_TOKEN', "Unexpected text '{0}'.",
       correction: "Try removing the text.");
 
-  static const ParserErrorCode WITH_BEFORE_EXTENDS = const ParserErrorCode(
-      'WITH_BEFORE_EXTENDS',
-      "The extends clause must be before the with clause.",
-      correction: "Try moving the extends clause before the with clause.");
-
-  static const ParserErrorCode WITH_WITHOUT_EXTENDS = const ParserErrorCode(
-      'WITH_WITHOUT_EXTENDS',
-      "The with clause can't be used without an extends clause.",
-      correction: "Try adding an extends clause such as 'extends Object'.");
+  static const ParserErrorCode WITH_BEFORE_EXTENDS = _WITH_BEFORE_EXTENDS;
 
   static const ParserErrorCode WRONG_SEPARATOR_FOR_POSITIONAL_PARAMETER =
       const ParserErrorCode('WRONG_SEPARATOR_FOR_POSITIONAL_PARAMETER',
@@ -959,10 +883,7 @@
       'VAR_ENUM', "Enums can't be declared to be 'var'.",
       correction: "Try removing the keyword 'var'.");
 
-  static const ParserErrorCode VAR_RETURN_TYPE = const ParserErrorCode(
-      'VAR_RETURN_TYPE', "The return type can't be 'var'.",
-      correction: "Try removing the keyword 'var', or "
-          "replacing it with the name of the return type.");
+  static const ParserErrorCode VAR_RETURN_TYPE = _VAR_RETURN_TYPE;
 
   static const ParserErrorCode VAR_TYPEDEF = const ParserErrorCode(
       'VAR_TYPEDEF', "Typedefs can't be declared to be 'var'.",
diff --git a/pkg/analyzer/lib/src/dart/error/syntactic_errors.g.dart b/pkg/analyzer/lib/src/dart/error/syntactic_errors.g.dart
new file mode 100644
index 0000000..4c26c3a
--- /dev/null
+++ b/pkg/analyzer/lib/src/dart/error/syntactic_errors.g.dart
@@ -0,0 +1,189 @@
+//
+// THIS FILE IS GENERATED. DO NOT EDIT.
+//
+// Instead modify 'pkg/front_end/messages.yaml' and run
+// 'dart pkg/analyzer/tool/messages/generate.dart' to update.
+
+part of 'syntactic_errors.dart';
+
+final fastaAnalyzerErrorCodes = <ErrorCode>[
+  null,
+  _EQUALITY_CANNOT_BE_EQUALITY_OPERAND,
+  _CONTINUE_OUTSIDE_OF_LOOP,
+  _EXTERNAL_CLASS,
+  _STATIC_CONSTRUCTOR,
+  _EXTERNAL_ENUM,
+  _PREFIX_AFTER_COMBINATOR,
+  _TYPEDEF_IN_CLASS,
+  _COVARIANT_AFTER_VAR,
+  _INVALID_AWAIT_IN_FOR,
+  _IMPORT_DIRECTIVE_AFTER_PART_DIRECTIVE,
+  _WITH_BEFORE_EXTENDS,
+  _VAR_RETURN_TYPE,
+  _TYPE_ARGUMENTS_ON_TYPE_VARIABLE,
+  _TOP_LEVEL_OPERATOR,
+  _SWITCH_HAS_MULTIPLE_DEFAULT_CASES,
+  _SWITCH_HAS_CASE_AFTER_DEFAULT_CASE,
+  _STATIC_OPERATOR,
+  _STATIC_AFTER_VAR,
+  _STATIC_AFTER_FINAL,
+  _STATIC_AFTER_CONST,
+  _REDIRECTION_IN_NON_FACTORY_CONSTRUCTOR,
+  _REDIRECTING_CONSTRUCTOR_WITH_BODY,
+  _NATIVE_CLAUSE_SHOULD_BE_ANNOTATION,
+  _MULTIPLE_WITH_CLAUSES,
+  _MULTIPLE_PART_OF_DIRECTIVES,
+  _MULTIPLE_ON_CLAUSES,
+  _MULTIPLE_LIBRARY_DIRECTIVES,
+  _MULTIPLE_EXTENDS_CLAUSES,
+  _MISSING_STATEMENT,
+  _MISSING_PREFIX_IN_DEFERRED_IMPORT,
+];
+
+const ParserErrorCode _CONTINUE_OUTSIDE_OF_LOOP = const ParserErrorCode(
+    'CONTINUE_OUTSIDE_OF_LOOP',
+    "A continue statement can't be used outside of a loop or switch statement.",
+    correction: "Try removing the continue statement.");
+
+const ParserErrorCode _COVARIANT_AFTER_VAR = const ParserErrorCode(
+    'COVARIANT_AFTER_VAR',
+    "The modifier 'covariant' should be before the modifier 'var'.",
+    correction: "Try re-ordering the modifiers.");
+
+const ParserErrorCode _EQUALITY_CANNOT_BE_EQUALITY_OPERAND = const ParserErrorCode(
+    'EQUALITY_CANNOT_BE_EQUALITY_OPERAND',
+    "An equality expression can't be an operand of another equality expression.",
+    correction: "Try re-writing the expression.");
+
+const ParserErrorCode _EXTERNAL_CLASS = const ParserErrorCode(
+    'EXTERNAL_CLASS', "Classes can't be declared to be 'external'.",
+    correction: "Try removing the keyword 'external'.");
+
+const ParserErrorCode _EXTERNAL_ENUM = const ParserErrorCode(
+    'EXTERNAL_ENUM', "Enums can't be declared to be 'external'.",
+    correction: "Try removing the keyword 'external'.");
+
+const ParserErrorCode _IMPORT_DIRECTIVE_AFTER_PART_DIRECTIVE =
+    const ParserErrorCode('IMPORT_DIRECTIVE_AFTER_PART_DIRECTIVE',
+        "Import directives must preceed part directives.",
+        correction:
+            "Try moving the import directives before the part directives.");
+
+const ParserErrorCode _INVALID_AWAIT_IN_FOR = const ParserErrorCode(
+    'INVALID_AWAIT_IN_FOR',
+    "The keyword 'await' isn't allowed for a normal 'for' statement.",
+    correction: "Try removing the keyword, or use a for-each statement.");
+
+const ParserErrorCode _MISSING_PREFIX_IN_DEFERRED_IMPORT =
+    const ParserErrorCode('MISSING_PREFIX_IN_DEFERRED_IMPORT',
+        "Deferred imports should have a prefix.",
+        correction: "Try adding a prefix to the import.");
+
+const ParserErrorCode _MISSING_STATEMENT =
+    const ParserErrorCode('MISSING_STATEMENT', "Expected a statement.");
+
+const ParserErrorCode _MULTIPLE_EXTENDS_CLAUSES = const ParserErrorCode(
+    'MULTIPLE_EXTENDS_CLAUSES',
+    "Each class definition can have at most one extends clause.",
+    correction:
+        "Try choosing one superclass and define your class to implement (or mix in) the others.");
+
+const ParserErrorCode _MULTIPLE_LIBRARY_DIRECTIVES = const ParserErrorCode(
+    'MULTIPLE_LIBRARY_DIRECTIVES',
+    "Only one library directive may be declared in a file.",
+    correction: "Try removing all but one of the library directives.");
+
+const ParserErrorCode _MULTIPLE_ON_CLAUSES = const ParserErrorCode(
+    'MULTIPLE_ON_CLAUSES',
+    "Each mixin definition can have at most one on clause.",
+    correction: "Try combining all of the on clauses into a single clause.");
+
+const ParserErrorCode _MULTIPLE_PART_OF_DIRECTIVES = const ParserErrorCode(
+    'MULTIPLE_PART_OF_DIRECTIVES',
+    "Only one part-of directive may be declared in a file.",
+    correction: "Try removing all but one of the part-of directives.");
+
+const ParserErrorCode _MULTIPLE_WITH_CLAUSES = const ParserErrorCode(
+    'MULTIPLE_WITH_CLAUSES',
+    "Each class definition can have at most one with clause.",
+    correction: "Try combining all of the with clauses into a single clause.");
+
+const ParserErrorCode _NATIVE_CLAUSE_SHOULD_BE_ANNOTATION = const ParserErrorCode(
+    'NATIVE_CLAUSE_SHOULD_BE_ANNOTATION',
+    "Native clause in this form is deprecated.",
+    correction:
+        "Try removing this native clause and adding @native() or @native('native-name') before the declaration.");
+
+const ParserErrorCode _PREFIX_AFTER_COMBINATOR = const ParserErrorCode(
+    'PREFIX_AFTER_COMBINATOR',
+    "The prefix ('as' clause) should come before any show/hide combinators.",
+    correction: "Try moving the prefix before the combinators.");
+
+const ParserErrorCode _REDIRECTING_CONSTRUCTOR_WITH_BODY = const ParserErrorCode(
+    'REDIRECTING_CONSTRUCTOR_WITH_BODY',
+    "Redirecting constructors can't have a body.",
+    correction:
+        "Try removing the body, or not making this a redirecting constructor.");
+
+const ParserErrorCode _REDIRECTION_IN_NON_FACTORY_CONSTRUCTOR =
+    const ParserErrorCode('REDIRECTION_IN_NON_FACTORY_CONSTRUCTOR',
+        "Only factory constructor can specify '=' redirection.",
+        correction:
+            "Try making this a factory constructor, or remove the redirection.");
+
+const ParserErrorCode _STATIC_AFTER_CONST = const ParserErrorCode(
+    'STATIC_AFTER_CONST',
+    "The modifier 'static' should be before the modifier 'const'.",
+    correction: "Try re-ordering the modifiers.");
+
+const ParserErrorCode _STATIC_AFTER_FINAL = const ParserErrorCode(
+    'STATIC_AFTER_FINAL',
+    "The modifier 'static' should be before the modifier 'final'.",
+    correction: "Try re-ordering the modifiers.");
+
+const ParserErrorCode _STATIC_AFTER_VAR = const ParserErrorCode(
+    'STATIC_AFTER_VAR',
+    "The modifier 'static' should be before the modifier 'var'.",
+    correction: "Try re-ordering the modifiers.");
+
+const ParserErrorCode _STATIC_CONSTRUCTOR = const ParserErrorCode(
+    'STATIC_CONSTRUCTOR', "Constructors can't be static.",
+    correction: "Try removing the keyword 'static'.");
+
+const ParserErrorCode _STATIC_OPERATOR = const ParserErrorCode(
+    'STATIC_OPERATOR', "Operators can't be static.",
+    correction: "Try removing the keyword 'static'.");
+
+const ParserErrorCode _SWITCH_HAS_CASE_AFTER_DEFAULT_CASE =
+    const ParserErrorCode('SWITCH_HAS_CASE_AFTER_DEFAULT_CASE',
+        "The default case should be the last case in a switch statement.",
+        correction:
+            "Try moving the default case after the other case clauses.");
+
+const ParserErrorCode _SWITCH_HAS_MULTIPLE_DEFAULT_CASES =
+    const ParserErrorCode('SWITCH_HAS_MULTIPLE_DEFAULT_CASES',
+        "The 'default' case can only be declared once.",
+        correction: "Try removing all but one default case.");
+
+const ParserErrorCode _TOP_LEVEL_OPERATOR = const ParserErrorCode(
+    'TOP_LEVEL_OPERATOR', "Operators must be declared within a class.",
+    correction:
+        "Try removing the operator, moving it to a class, or converting it to be a function.");
+
+const ParserErrorCode _TYPEDEF_IN_CLASS = const ParserErrorCode(
+    'TYPEDEF_IN_CLASS', "Typedefs can't be declared inside classes.",
+    correction: "Try moving the typedef to the top-level.");
+
+const ParserErrorCode _TYPE_ARGUMENTS_ON_TYPE_VARIABLE = const ParserErrorCode(
+    'TYPE_ARGUMENTS_ON_TYPE_VARIABLE',
+    "Can't use type arguments with type variable '#name'.",
+    correction: "Try removing the type arguments.");
+
+const ParserErrorCode _VAR_RETURN_TYPE = const ParserErrorCode(
+    'VAR_RETURN_TYPE', "The return type can't be 'var'.",
+    correction:
+        "Try removing the keyword 'var', or replacing it with the name of the return type.");
+
+const ParserErrorCode _WITH_BEFORE_EXTENDS = const ParserErrorCode(
+    'WITH_BEFORE_EXTENDS', "The extends clause must be before the with clause.",
+    correction: "Try moving the extends clause before the with clause.");
diff --git a/pkg/analyzer/lib/src/dart/resolver/inheritance_manager.dart b/pkg/analyzer/lib/src/dart/resolver/inheritance_manager.dart
index 6cbae08..db3945b 100644
--- a/pkg/analyzer/lib/src/dart/resolver/inheritance_manager.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/inheritance_manager.dart
@@ -283,7 +283,7 @@
     }
     InterfaceType supertype = classElt.supertype;
     if (supertype == null) {
-      // classElt is Object
+      // classElt is Object or a mixin
       _classLookup[classElt] = resultMap;
       return resultMap;
     }
@@ -380,9 +380,8 @@
     // functionality in InheritanceManagerTest
     chain.add(currentType);
     ClassElement classElt = currentType.element;
-    InterfaceType supertype = classElt.supertype;
     // Base case- reached Object
-    if (supertype == null) {
+    if (currentType.isObject) {
       // Looked up the chain all the way to Object, return null.
       // This should never happen.
       return;
@@ -411,14 +410,23 @@
       }
     }
     // Superclass
-    ClassElement superclassElt = supertype.element;
-    if (lookupMember(superclassElt, memberName) != null) {
+    InterfaceType supertype = classElt.supertype;
+    if (supertype != null &&
+        lookupMember(supertype.element, memberName) != null) {
       _computeInheritancePath(chain, supertype, memberName);
       return;
     }
+    // Superclass constraints
+    for (InterfaceType interfaceType in classElt.superclassConstraints) {
+      ClassElement interfaceElement = interfaceType.element;
+      if (interfaceElement != null &&
+          lookupMember(interfaceElement, memberName) != null) {
+        _computeInheritancePath(chain, interfaceType, memberName);
+        return;
+      }
+    }
     // Interfaces
-    List<InterfaceType> interfaces = classElt.interfaces;
-    for (InterfaceType interfaceType in interfaces) {
+    for (InterfaceType interfaceType in classElt.interfaces) {
       ClassElement interfaceElement = interfaceType.element;
       if (interfaceElement != null &&
           lookupMember(interfaceElement, memberName) != null) {
@@ -585,110 +593,54 @@
    */
   List<Map<String, ExecutableElement>> _gatherInterfaceLookupMaps(
       ClassElement classElt, HashSet<ClassElement> visitedInterfaces) {
-    InterfaceType supertype = classElt.supertype;
-    ClassElement superclassElement = supertype?.element;
-    List<InterfaceType> mixins = classElt.mixins;
-    List<InterfaceType> interfaces = classElt.interfaces;
-    // Recursively collect the list of mappings from all of the interface types
     List<Map<String, ExecutableElement>> lookupMaps =
         new List<Map<String, ExecutableElement>>();
-    //
-    // Superclass element
-    //
-    if (superclassElement != null) {
-      if (!visitedInterfaces.contains(superclassElement)) {
-        try {
-          visitedInterfaces.add(superclassElement);
-          //
-          // Recursively compute the map for the super type.
-          //
-          Map<String, ExecutableElement> map =
-              _computeInterfaceLookupMap(superclassElement, visitedInterfaces);
-          map = new Map<String, ExecutableElement>.from(map);
-          //
-          // Substitute the super type down the hierarchy.
-          //
-          _substituteTypeParametersDownHierarchy(supertype, map);
-          //
-          // Add any members from the super type into the map as well.
-          //
-          _recordMapWithClassMembers(map, supertype, true);
-          lookupMaps.add(map);
-        } finally {
-          visitedInterfaces.remove(superclassElement);
-        }
-      } else {
-        return null;
+    bool hasProblem = false;
+
+    void recordInterface(InterfaceType type) {
+      ClassElement element = type.element;
+      if (!visitedInterfaces.add(element)) {
+        hasProblem = true;
+        return;
+      }
+      try {
+        //
+        // Recursively compute the map for the interfaces.
+        //
+        Map<String, ExecutableElement> map =
+            _computeInterfaceLookupMap(element, visitedInterfaces);
+        map = new Map<String, ExecutableElement>.from(map);
+        //
+        // Substitute the supertypes down the hierarchy.
+        //
+        _substituteTypeParametersDownHierarchy(type, map);
+        //
+        // And any members from the interface into the map as well.
+        //
+        _recordMapWithClassMembers(map, type, true);
+        lookupMaps.add(map);
+      } finally {
+        visitedInterfaces.remove(element);
       }
     }
-    //
-    // Mixin elements
-    //
-    for (int i = mixins.length - 1; i >= 0; i--) {
-      InterfaceType mixinType = mixins[i];
-      ClassElement mixinElement = mixinType.element;
-      if (mixinElement != null) {
-        if (!visitedInterfaces.contains(mixinElement)) {
-          try {
-            visitedInterfaces.add(mixinElement);
-            //
-            // Recursively compute the map for the mixin.
-            //
-            Map<String, ExecutableElement> map =
-                _computeInterfaceLookupMap(mixinElement, visitedInterfaces);
-            map = new Map<String, ExecutableElement>.from(map);
-            //
-            // Substitute the mixin type down the hierarchy.
-            //
-            _substituteTypeParametersDownHierarchy(mixinType, map);
-            //
-            // Add any members from the mixin type into the map as well.
-            //
-            _recordMapWithClassMembers(map, mixinType, true);
-            lookupMaps.add(map);
-          } finally {
-            visitedInterfaces.remove(mixinElement);
-          }
-        } else {
-          return null;
-        }
+
+    void recordInterfaces(List<InterfaceType> types) {
+      for (int i = types.length - 1; i >= 0; i--) {
+        InterfaceType type = types[i];
+        recordInterface(type);
       }
     }
-    //
-    // Interface elements
-    //
-    int interfaceLength = interfaces.length;
-    for (int i = 0; i < interfaceLength; i++) {
-      InterfaceType interfaceType = interfaces[i];
-      ClassElement interfaceElement = interfaceType.element;
-      if (interfaceElement != null) {
-        if (!visitedInterfaces.contains(interfaceElement)) {
-          try {
-            visitedInterfaces.add(interfaceElement);
-            //
-            // Recursively compute the map for the interfaces.
-            //
-            Map<String, ExecutableElement> map =
-                _computeInterfaceLookupMap(interfaceElement, visitedInterfaces);
-            map = new Map<String, ExecutableElement>.from(map);
-            //
-            // Substitute the supertypes down the hierarchy
-            //
-            _substituteTypeParametersDownHierarchy(interfaceType, map);
-            //
-            // And add any members from the interface into the map as well.
-            //
-            _recordMapWithClassMembers(map, interfaceType, true);
-            lookupMaps.add(map);
-          } finally {
-            visitedInterfaces.remove(interfaceElement);
-          }
-        } else {
-          return null;
-        }
-      }
+
+    InterfaceType superType = classElt.supertype;
+    if (superType != null) {
+      recordInterface(superType);
     }
-    if (lookupMaps.isEmpty) {
+
+    recordInterfaces(classElt.mixins);
+    recordInterfaces(classElt.superclassConstraints);
+    recordInterfaces(classElt.interfaces);
+
+    if (hasProblem || lookupMaps.isEmpty) {
       return null;
     }
     return lookupMaps;
diff --git a/pkg/analyzer/lib/src/dart/resolver/scope.dart b/pkg/analyzer/lib/src/dart/resolver/scope.dart
index 2e688d6..62b2517 100644
--- a/pkg/analyzer/lib/src/dart/resolver/scope.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/scope.dart
@@ -8,9 +8,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/error/codes.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/java_engine.dart';
 import 'package:analyzer/src/generated/source.dart';
@@ -74,28 +72,6 @@
     _defineMembers(classElement);
   }
 
-  @override
-  AnalysisError getErrorForDuplicate(Element existing, Element duplicate) {
-    if (existing is PropertyAccessorElement && duplicate is MethodElement) {
-      if (existing.nameOffset < duplicate.nameOffset) {
-        return new AnalysisError(
-            duplicate.source,
-            duplicate.nameOffset,
-            duplicate.nameLength,
-            CompileTimeErrorCode.METHOD_AND_GETTER_WITH_SAME_NAME,
-            [existing.displayName]);
-      } else {
-        return new AnalysisError(
-            existing.source,
-            existing.nameOffset,
-            existing.nameLength,
-            CompileTimeErrorCode.GETTER_AND_METHOD_WITH_SAME_NAME,
-            [existing.displayName]);
-      }
-    }
-    return super.getErrorForDuplicate(existing, duplicate);
-  }
-
   /**
    * Define the instance members defined by the given [classElement].
    */
@@ -598,28 +574,6 @@
     }
   }
 
-  @override
-  AnalysisError getErrorForDuplicate(Element existing, Element duplicate) {
-    if (existing is PrefixElement) {
-      // TODO(scheglov) consider providing actual 'nameOffset' from the
-      // synthetic accessor
-      int offset = duplicate.nameOffset;
-      if (duplicate is PropertyAccessorElement) {
-        PropertyAccessorElement accessor = duplicate;
-        if (accessor.isSynthetic) {
-          offset = accessor.variable.nameOffset;
-        }
-      }
-      return new AnalysisError(
-          duplicate.source,
-          offset,
-          duplicate.nameLength,
-          CompileTimeErrorCode.PREFIX_COLLIDES_WITH_TOP_LEVEL_MEMBER,
-          [existing.displayName]);
-    }
-    return super.getErrorForDuplicate(existing, duplicate);
-  }
-
   /**
    * Add to this scope all of the public top-level names that are defined in the
    * given [compilationUnit].
@@ -818,6 +772,9 @@
         in compilationUnit.functionTypeAliases) {
       _addIfPublic(definedNames, element);
     }
+    for (ClassElement element in compilationUnit.mixins) {
+      _addIfPublic(definedNames, element);
+    }
     for (ClassElement element in compilationUnit.types) {
       _addIfPublic(definedNames, element);
     }
@@ -1052,22 +1009,6 @@
   }
 
   /**
-   * Return the error code to be used when reporting that a name being defined
-   * locally conflicts with another element of the same name in the local scope.
-   * [existing] is the first element to be declared with the conflicting name,
-   * while [duplicate] another element declared with the conflicting name.
-   */
-  AnalysisError getErrorForDuplicate(Element existing, Element duplicate) {
-    // TODO(brianwilkerson) Customize the error message based on the types of
-    // elements that share the same name.
-    // TODO(jwren) There are 4 error codes for duplicate, but only 1 is being
-    // generated.
-    Source source = duplicate.source;
-    return new AnalysisError(source, duplicate.nameOffset, duplicate.nameLength,
-        CompileTimeErrorCode.DUPLICATE_DEFINITION, [existing.displayName]);
-  }
-
-  /**
    * Return the source that contains the given [identifier], or the source
    * associated with this scope if the source containing the identifier could
    * not be determined.
diff --git a/pkg/analyzer/lib/src/error/codes.dart b/pkg/analyzer/lib/src/error/codes.dart
index 5adc23c7..a572b6a 100644
--- a/pkg/analyzer/lib/src/error/codes.dart
+++ b/pkg/analyzer/lib/src/error/codes.dart
@@ -169,6 +169,19 @@
  */
 class CompileTimeErrorCode extends ErrorCode {
   /**
+   * Member lookups ignore abstract declarations, which means that there will
+   * be a compile-time error if the targeted member `m` is abstract, as well as
+   * when it does not exist at all.
+   *
+   * Parameters:
+   * 0: the display name for the kind of the found abstract member
+   * 1: the name of the member
+   */
+  static const CompileTimeErrorCode ABSTRACT_SUPER_MEMBER_REFERENCE =
+      const CompileTimeErrorCode('ABSTRACT_SUPER_MEMBER_REFERENCE',
+          "The {0} '{1}' is always abstract in the supertype.");
+
+  /**
    * Enum proposal: It is also a compile-time error to explicitly instantiate an
    * enum via 'new' or 'const' or to access its private fields.
    */
@@ -195,9 +208,6 @@
           correction: "Try removing the export of one of the libraries, or "
               "explicitly hiding the name in one of the export directives.");
 
-  static const CompileTimeErrorCode AMBIGUOUS_SUPERTYPES =
-      const CompileTimeErrorCode.fromFasta('AMBIGUOUS_SUPERTYPES');
-
   /**
    * 15 Metadata: The constant expression given in an annotation is type checked
    * and evaluated in the scope surrounding the declaration being annotated.
@@ -222,7 +232,8 @@
               "defining a class with the given name.");
 
   static const CompileTimeErrorCode ANNOTATION_WITH_TYPE_ARGUMENTS =
-      const CompileTimeErrorCode.fromFasta('ANNOTATION_WITH_TYPE_ARGUMENTS');
+      const CompileTimeErrorCode('ANNOTATION_WITH_TYPE_ARGUMENTS',
+          "An annotation (metadata) can't use type arguments.");
 
   /**
    * 12.33 Argument Definition Test: It is a compile time error if <i>v</i> does
@@ -236,10 +247,6 @@
       const CompileTimeErrorCode(
           'ARGUMENT_DEFINITION_TEST_NON_PARAMETER', "'{0}' isn't a parameter.");
 
-  static const CompileTimeErrorCode ASSIGNMENT_TO_PARENTHESIZED_EXPRESSION =
-      const CompileTimeErrorCode.fromFasta(
-          'ASSIGNMENT_TO_PARENTHESIZED_EXPRESSION');
-
   /**
    * 17.6.3 Asynchronous For-in: It is a compile-time error if an asynchronous
    * for-in statement appears inside a synchronous function.
@@ -354,75 +361,64 @@
           "The switch case expression type '{0}' can't override the == operator.");
 
   /**
-   * 7.2 Getters: It is a compile-time error if a class has both a getter and a
-   * method with the same name. This restriction holds regardless of whether the
-   * getter is defined explicitly or implicitly, or whether the getter or the
-   * method are inherited or not.
+   * 10.11 Class Member Conflicts: Let `C` be a class. It is a compile-time
+   * error if `C` declares a constructor named `C.n`, and a static member with
+   * basename `n`.
    *
    * Parameters:
-   * 0: the name of the class defining the conflicting method
-   * 1: the name of the class defining the getter with which the method conflicts
-   * 2: the name of the conflicting method
+   * 0: the name of the constructor
    */
-  static const CompileTimeErrorCode CONFLICTING_GETTER_AND_METHOD =
+  static const CompileTimeErrorCode CONFLICTING_CONSTRUCTOR_AND_STATIC_FIELD =
       const CompileTimeErrorCode(
-          'CONFLICTING_GETTER_AND_METHOD',
-          "Class '{0}' can't have both getter '{1}.{2}' and method with the "
-          "same name.",
-          correction: "Try converting the method to a getter, or "
-              "renaming the method to a name that doesn't conflit.");
+          'CONFLICTING_CONSTRUCTOR_AND_STATIC_FIELD',
+          "'{0}' can't be used to name both a constructor and a static field "
+          "in this class.",
+          correction: "Try renaming either the constructor or the field.");
 
   /**
-   * 7.2 Getters: It is a compile-time error if a class has both a getter and a
-   * method with the same name. This restriction holds regardless of whether the
-   * getter is defined explicitly or implicitly, or whether the getter or the
-   * method are inherited or not.
+   * 10.11 Class Member Conflicts: Let `C` be a class. It is a compile-time
+   * error if `C` declares a constructor named `C.n`, and a static member with
+   * basename `n`.
    *
    * Parameters:
-   * 0: the name of the class defining the conflicting getter
-   * 1: the name of the class defining the method with which the getter conflicts
-   * 2: the name of the conflicting getter
+   * 0: the name of the constructor
    */
-  static const CompileTimeErrorCode CONFLICTING_METHOD_AND_GETTER =
+  static const CompileTimeErrorCode CONFLICTING_CONSTRUCTOR_AND_STATIC_METHOD =
       const CompileTimeErrorCode(
-          'CONFLICTING_METHOD_AND_GETTER',
-          "Class '{0}' can't have both method '{1}.{2}' and getter with the "
-          "same name.",
+          'CONFLICTING_CONSTRUCTOR_AND_STATIC_METHOD',
+          "'{0}' can't be used to name both a constructor and a static method "
+          "in this class.",
+          correction: "Try renaming either the constructor or the method.");
+
+  /**
+   * 10.11 Class Member Conflicts: Let `C` be a class. It is a compile-time
+   * error if `C` declares a getter or a setter with basename `n`, and has a
+   * method named `n`.
+   *
+   * Parameters:
+   * 0: the name of the class defining the conflicting field
+   * 1: the name of the conflicting field
+   * 2: the name of the class defining the method with which the field conflicts
+   */
+  static const CompileTimeErrorCode CONFLICTING_FIELD_AND_METHOD =
+      const CompileTimeErrorCode(
+          'CONFLICTING_FIELD_AND_METHOD',
+          "Class '{0}' can't define field '{1}' and have method '{2}.{1}' "
+          "with the same name.",
           correction: "Try converting the getter to a method, or "
-              "renaming the getter to a name that doesn't conflit.");
+              "renaming the field to a name that doesn't conflit.");
 
   /**
-   * 7.6 Constructors: A constructor name always begins with the name of its
-   * immediately enclosing class, and may optionally be followed by a dot and an
-   * identifier <i>id</i>. It is a compile-time error if <i>id</i> is the name
-   * of a member declared in the immediately enclosing class.
+   * 10.10 Superinterfaces: It is a compile-time error if a class `C` has two
+   * superinterfaces that are different instantiations of the same generic
+   * class. For example, a class may not have both `List<int>` and `List<num>`
+   * as superinterfaces.
    *
    * Parameters:
-   * 0: the name of the constructor
+   * 0: the name of the class implementing the conflicting interface
+   * 1: the first conflicting type
+   * 1: the second conflicting type
    */
-  static const CompileTimeErrorCode CONFLICTING_CONSTRUCTOR_NAME_AND_FIELD =
-      const CompileTimeErrorCode(
-          'CONFLICTING_CONSTRUCTOR_NAME_AND_FIELD',
-          "'{0}' can't be used to name both a constructor and a field in this "
-          "class.",
-          correction: "Try renaming either the constructor or the field.");
-
-  /**
-   * 7.6 Constructors: A constructor name always begins with the name of its
-   * immediately enclosing class, and may optionally be followed by a dot and an
-   * identifier <i>id</i>. It is a compile-time error if <i>id</i> is the name
-   * of a member declared in the immediately enclosing class.
-   *
-   * Parameters:
-   * 0: the name of the constructor
-   */
-  static const CompileTimeErrorCode CONFLICTING_CONSTRUCTOR_NAME_AND_METHOD =
-      const CompileTimeErrorCode(
-          'CONFLICTING_CONSTRUCTOR_NAME_AND_METHOD',
-          "'{0}' can't be used to name both a constructor and a method in this "
-          "class.",
-          correction: "Try renaming either the constructor or the field.");
-
   static const CompileTimeErrorCode CONFLICTING_GENERIC_INTERFACES =
       const CompileTimeErrorCode(
           'CONFLICTING_GENERIC_INTERFACES',
@@ -430,6 +426,42 @@
           "type arguments are different.");
 
   /**
+   * 10.11 Class Member Conflicts: Let `C` be a class. It is a compile-time
+   * error if `C` declares a method named `n`, and has a getter or a setter
+   * with basename `n`.
+   *
+   * Parameters:
+   * 0: the name of the class defining the conflicting method
+   * 1: the name of the conflicting method
+   * 2: the name of the class defining the field with which the method conflicts
+   */
+  static const CompileTimeErrorCode CONFLICTING_METHOD_AND_FIELD =
+      const CompileTimeErrorCode(
+          'CONFLICTING_METHOD_AND_FIELD',
+          "Class '{0}' can't define method '{1}' and have field '{2}.{1}' "
+          "with the same name.",
+          correction: "Try converting the method to a getter, or "
+              "renaming the method to a name that doesn't conflit.");
+
+  /**
+   * 10.11 Class Member Conflicts: Let `C` be a class. It is a compile-time
+   * error if `C` declares a static member with basename `n`, and has an
+   * instance member with basename `n`.
+   *
+   * Parameters:
+   * 0: the name of the class defining the conflicting member
+   * 1: the name of the conflicting static member
+   * 2: the name of the class defining the field with which the method conflicts
+   */
+  static const CompileTimeErrorCode CONFLICTING_STATIC_AND_INSTANCE =
+      const CompileTimeErrorCode(
+          'CONFLICTING_STATIC_AND_INSTANCE',
+          "Class '{0}' can't define static member '{1}' and have instance "
+          "member '{2}.{1}' with the same name.",
+          correction:
+              "Try renaming the member to a name that doesn't conflit.");
+
+  /**
    * 7. Classes: It is a compile time error if a generic class declares a type
    * variable with the same name as the class or any of its members or
    * constructors.
@@ -459,19 +491,11 @@
           "this class.",
           correction: "Try renaming either the type variable or the member.");
 
-  static const CompileTimeErrorCode CONFLICTS_WITH_CONSTRUCTOR =
-      const CompileTimeErrorCode.fromFasta('CONFLICTS_WITH_CONSTRUCTOR');
-
-  static const CompileTimeErrorCode CONFLICTS_WITH_INHERITED_MEMBER =
-      const CompileTimeErrorCode.fromFasta('CONFLICTS_WITH_INHERITED_MEMBER');
-
-  static const CompileTimeErrorCode CONFLICTS_WITH_MEMBER =
-      const CompileTimeErrorCode.fromFasta('CONFLICTS_WITH_MEMBER');
-
   static const CompileTimeErrorCode
       CONST_CONSTRUCTOR_IN_SUBCLASS_OF_MIXIN_APPLICATION =
-      const CompileTimeErrorCode.fromFasta(
-          'CONST_CONSTRUCTOR_IN_SUBCLASS_OF_MIXIN_APPLICATION');
+      const CompileTimeErrorCode(
+          'CONST_CONSTRUCTOR_IN_SUBCLASS_OF_MIXIN_APPLICATION',
+          "Can't extend a mixin application and be 'const'.");
 
   /**
    * 16.12.2 Const: It is a compile-time error if evaluation of a constant
@@ -795,13 +819,6 @@
           "The class '{0}' doesn't have a default constant constructor.",
           correction: "Try calling a different contructor.");
 
-  static const CompileTimeErrorCode CONSTRUCTOR_NOT_FOUND =
-      const CompileTimeErrorCode.fromFasta('CONSTRUCTOR_NOT_FOUND');
-
-  static const CompileTimeErrorCode DECLARED_MEMBER_CONFLICTS_WITH_INHERITED =
-      const CompileTimeErrorCode.fromFasta(
-          'DECLARED_MEMBER_CONFLICTS_WITH_INHERITED');
-
   /**
    * 15.3.1 Typedef: It is a compile-time error if any default values are
    * specified in the signature of a function type alias.
@@ -887,24 +904,6 @@
           "Try removing all but one of the duplicated part directives.");
 
   /**
-   * 7. Classes: It is a compile-time error if a class has an instance member
-   * and a static member with the same name.
-   *
-   * This covers the additional duplicate definition cases where inheritance has
-   * to be considered.
-   *
-   * Parameters:
-   * 0: the name of the class that has conflicting instance/static members
-   * 1: the name of the conflicting member
-   *
-   * See [DUPLICATE_DEFINITION].
-   */
-  static const CompileTimeErrorCode DUPLICATE_DEFINITION_INHERITANCE =
-      const CompileTimeErrorCode('DUPLICATE_DEFINITION_INHERITANCE',
-          "The name '{0}' is already defined in '{1}'.",
-          correction: "Try renaming one of the declarations.");
-
-  /**
    * 12.14.2 Binding Actuals to Formals: It is a compile-time error if
    * <i>q<sub>i</sub> = q<sub>j</sub></i> for any <i>i != j</i> [where
    * <i>q<sub>i</sub></i> is the label for a named argument].
@@ -918,9 +917,6 @@
           correction: "Try removing one of the named arguments, or "
               "correcting one of the names to reference a different named parameter.");
 
-  static const CompileTimeErrorCode ENUM_CONSTANT_WITH_ENUM_NAME =
-      const CompileTimeErrorCode.fromFasta('ENUM_CONSTANT_WITH_ENUM_NAME');
-
   /**
    * SDK implementation libraries can be exported only by other SDK libraries.
    *
@@ -1005,11 +1001,6 @@
           correction: "Try specifying a different superclass, or "
               "removing the extends clause.");
 
-  static const CompileTimeErrorCode
-      EXTERNAL_CONSTRUCTOR_WITH_FIELD_INITIALIZERS =
-      const CompileTimeErrorCode.fromFasta(
-          'EXTERNAL_CONSTRUCTOR_WITH_FIELD_INITIALIZERS');
-
   /**
    * 12.14.2 Binding Actuals to Formals: It is a static warning if <i>m &lt;
    * h</i> or if <i>m &gt; n</i>.
@@ -1045,10 +1036,6 @@
           correction: "Try removing the extra positional arguments, "
               "or specifying the name for named arguments.");
 
-  static const CompileTimeErrorCode FACTORY_REDIRECTS_TO_ABSTRACT_CLASS =
-      const CompileTimeErrorCode.fromFasta(
-          'FACTORY_REDIRECTS_TO_ABSTRACT_CLASS');
-
   /**
    * 7.6.1 Generative Constructors: Let <i>k</i> be a generative constructor. It
    * is a compile time error if more than one initializer corresponding to a
@@ -1139,23 +1126,6 @@
               "`dynamic`.");
 
   /**
-   * 7.2 Getters: It is a compile-time error if a class has both a getter and a
-   * method with the same name.
-   *
-   * Parameters:
-   * 0: the conflicting name of the getter and method
-   */
-  static const CompileTimeErrorCode GETTER_AND_METHOD_WITH_SAME_NAME =
-      const CompileTimeErrorCode(
-          'GETTER_AND_METHOD_WITH_SAME_NAME',
-          "'{0}' can't be used to name a getter, there is already a method "
-          "with the same name.",
-          correction: "Try renaming either the getter or the method.");
-
-  static const CompileTimeErrorCode ILLEGAL_MIXIN =
-      const CompileTimeErrorCode.fromFasta('ILLEGAL_MIXIN');
-
-  /**
    * 7.10 Superinterfaces: It is a compile-time error if the implements clause
    * of a class <i>C</i> specifies a malformed type or deferred type as a
    * superinterface.
@@ -1215,11 +1185,12 @@
               "Try specifying a class, or remove the name from the list.");
 
   /**
-   * 7.10 Superinterfaces: It is a compile-time error if a type <i>T</i> appears
-   * more than once in the implements clause of a class.
+   * 10.10 Superinterfaces: It is a compile-time error if two elements in the
+   * type list of the implements clause of a class `C` specifies the same
+   * type `T`.
    *
    * Parameters:
-   * 0: the name of the class that is implemented more than once
+   * 0: the name of the interface that is implemented more than once
    */
   static const CompileTimeErrorCode IMPLEMENTS_REPEATED =
       const CompileTimeErrorCode(
@@ -1239,9 +1210,6 @@
           "'{0}' can't be used in both 'extends' and 'implements' clauses.",
           correction: "Try removing one of the occurances.");
 
-  static const CompileTimeErrorCode IMPLICIT_CALL_OF_NON_METHOD =
-      const CompileTimeErrorCode.fromFasta('IMPLICIT_CALL_OF_NON_METHOD');
-
   /**
    * 7.6.1 Generative Constructors: Note that <b>this</b> is not in scope on the
    * right hand side of an initializer.
@@ -1329,9 +1297,6 @@
           "in a constructor can't be static.",
           correction: "Try removing the initialization.");
 
-  static const CompileTimeErrorCode INITIALIZER_OUTSIDE_CONSTRUCTOR =
-      const CompileTimeErrorCode.fromFasta('INITIALIZER_OUTSIDE_CONSTRUCTOR');
-
   /**
    * 7.6.1 Generative Constructors: An initializing formal has the form
    * <i>this.id</i>. It is a compile-time error if <i>id</i> is not the name of
@@ -1404,6 +1369,22 @@
               "9,223,372,036,854,775,807 or less than -9,223,372,036,854,775,808.");
 
   /**
+   * An integer literal with static type `double` and numeric value `i`
+   * evaluates to an instance of the `double` class representing the value `i`.
+   * It is a compile-time error if the value `i` cannot be represented
+   * _precisely_ by the an instace of `double`.
+   */
+  static const CompileTimeErrorCode INTEGER_LITERAL_IMPRECISE_AS_DOUBLE =
+      const CompileTimeErrorCode(
+          'INTEGER_LITERAL_IMPRECISE_AS_DOUBLE',
+          "The integer literal is being used as a double, but can't be "
+          'represented as a 64 bit double without overflow and/or loss of '
+          'precision: {0}',
+          correction:
+              'Try using the BigInt class, or switch to the closest valid '
+              'double: {1}');
+
+  /**
    * 15 Metadata: Metadata consists of a series of annotations, each of which
    * begin with the character @, followed by a constant expression that must be
    * either a reference to a compile-time constant variable, or a call to a
@@ -1441,9 +1422,6 @@
           'INVALID_ANNOTATION_GETTER', "Getters cannot be used as annotations.",
           correction: "Try using a top-level variable or a field.");
 
-  static const CompileTimeErrorCode INVALID_CATCH_ARGUMENTS =
-      const CompileTimeErrorCode.fromFasta('INVALID_CATCH_ARGUMENTS');
-
   /**
    * 15.31 Identifier Reference: It is a compile-time error if any of the
    * identifiers async, await or yield is used as an identifier in a function
@@ -1457,9 +1435,6 @@
           correction: "Try using a different name, or "
               "remove the modifier on the function body.");
 
-  static const CompileTimeErrorCode INVALID_INITIALIZER =
-      const CompileTimeErrorCode.fromFasta('INVALID_INITIALIZER');
-
   /**
    * 9. Functions: It is a compile-time error if an async, async* or sync*
    * modifier is attached to the body of a setter or constructor.
@@ -1506,6 +1481,12 @@
           "The name of a factory constructor must be the same as the name of "
           "the immediately enclosing class.");
 
+  static const CompileTimeErrorCode INVALID_INLINE_FUNCTION_TYPE =
+      const CompileTimeErrorCode('INVALID_INLINE_FUNCTION_TYPE',
+          "Inline function types cannot be used for parameters in a generic function type.",
+          correction:
+              "Try using a generic function type (returnType 'Function(' parameters ')').");
+
   /**
    * 12.10 This: It is a compile-time error if this appears in a top-level
    * function or variable initializer, in a factory constructor, or in a static
@@ -1556,12 +1537,6 @@
           "methods or before non-final instance fields.",
           correction: "Try removing the 'covariant' keyword.");
 
-  static const CompileTimeErrorCode INVALID_USE_OF_NULL_AWARE_ACCESS =
-      const CompileTimeErrorCode.fromFasta('INVALID_USE_OF_NULL_AWARE_ACCESS');
-
-  static const CompileTimeErrorCode INVALID_USE_OF_VOID =
-      const CompileTimeErrorCode.fromFasta('INVALID_USE_OF_VOID');
-
   /**
    * 14.2 Exports: It is a compile-time error if the compilation unit found at
    * the specified URI is not a library declaration.
@@ -1614,9 +1589,6 @@
           correction: "Try defining the label, or "
               "correcting the name to match an existing label.");
 
-  static const CompileTimeErrorCode LOAD_LIBRARY_TAKES_NO_ARGUMENTS =
-      const CompileTimeErrorCode.fromFasta('LOAD_LIBRARY_TAKES_NO_ARGUMENTS');
-
   /**
    * 7 Classes: It is a compile time error if a class <i>C</i> declares a member
    * with the same name as <i>C</i>.
@@ -1626,19 +1598,6 @@
           "Class members can't have the same name as the enclosing class.");
 
   /**
-   * 7.2 Getters: It is a compile-time error if a class has both a getter and a
-   * method with the same name.
-   *
-   * Parameters:
-   * 0: the conflicting name of the getter and method
-   */
-  static const CompileTimeErrorCode METHOD_AND_GETTER_WITH_SAME_NAME =
-      const CompileTimeErrorCode(
-          'METHOD_AND_GETTER_WITH_SAME_NAME',
-          "'{0}' can't be used to name a method, there is already a getter "
-          "with the same name.");
-
-  /**
    * 12.1 Constants: A constant expression is ... a constant list literal.
    */
   static const CompileTimeErrorCode MISSING_CONST_IN_LIST_LITERAL =
@@ -1664,6 +1623,55 @@
           correction: "Check your Dart SDK installation for completeness.");
 
   /**
+   * It's a compile-time error to apply a mixin containing super-invocations to
+   * a class that doesn't have a concrete implementation of the super-invoked
+   * members compatible with the super-constraint interface.
+   *
+   * This ensures that if more than one super-constraint interface declares a
+   * member with the same name, at least one of those members is more specific
+   * than the rest, and this is the unique signature that super-invocations
+   * are allowed to invoke.
+   *
+   * Parameters:
+   * 0: the name of the super-invoked member
+   * 1: the display name of the type of the super-invoked member in the mixin
+   * 2: the display name of the type of the concrete member in the class
+   */
+  static const CompileTimeErrorCode
+      MIXIN_APPLICATION_CONCRETE_SUPER_INVOKED_MEMBER_TYPE =
+      const CompileTimeErrorCode(
+          'MIXIN_APPLICATION_CONCRETE_SUPER_INVOKED_MEMBER_TYPE',
+          "The super-invoked member '{0}' has the type '{1}', but the "
+          "concrete member in the class has type '{2}'.");
+
+  /**
+   * It's a compile-time error to apply a mixin to a class that doesn't
+   * implement all the on type requirements of the mixin declaration.
+   *
+   * Parameters:
+   * 0: the display name of the not implemented type
+   */
+  static const CompileTimeErrorCode
+      MIXIN_APPLICATION_NOT_IMPLEMENTED_INTERFACE = const CompileTimeErrorCode(
+          'MIXIN_APPLICATION_NOT_IMPLEMENTED_INTERFACE',
+          "The class doesn't implement the required class '{0}'.");
+
+  /**
+   * It's a compile-time error to apply a mixin containing super-invocations to
+   * a class that doesn't have a concrete implementation of the super-invoked
+   * members compatible with the super-constraint interface.
+   *
+   * Parameters:
+   * 0: the display name of the member without a concrete implementation
+   */
+  static const CompileTimeErrorCode
+      MIXIN_APPLICATION_NO_CONCRETE_SUPER_INVOKED_MEMBER =
+      const CompileTimeErrorCode(
+          'MIXIN_APPLICATION_NO_CONCRETE_SUPER_INVOKED_MEMBER',
+          "The class doesn't have a concrete implementation of the "
+          "super-invoked member '{0}'.");
+
+  /**
    * 9 Mixins: It is a compile-time error if a declared or derived mixin
    * explicitly declares a constructor.
    *
@@ -1747,6 +1755,13 @@
           "other than Object.");
 
   /**
+   * A mixin declaration introduces a mixin and an interface, but not a class.
+   */
+  static const CompileTimeErrorCode MIXIN_INSTANTIATE =
+      const CompileTimeErrorCode(
+          'MIXIN_INSTANTIATE', "Mixins can't be instantiated.");
+
+  /**
    * 12.2 Null: It is a compile-time error for a class to attempt to extend or
    * implement Null.
    *
@@ -1804,9 +1819,9 @@
           'MIXIN_SUPER_CLASS_CONSTRAINT_DISALLOWED_CLASS',
           "'{0}' can't be used as a super-class constraint.");
 
-  static const CompileTimeErrorCode MIXIN_SUPER_CLASS_CONSTRAINT_NON_CLASS =
-      const CompileTimeErrorCode('MIXIN_SUPER_CLASS_CONSTRAINT_NON_CLASS',
-          "Only classes can be used as super-class constraints.");
+  static const CompileTimeErrorCode MIXIN_SUPER_CLASS_CONSTRAINT_NON_INTERFACE =
+      const CompileTimeErrorCode('MIXIN_SUPER_CLASS_CONSTRAINT_NON_INTERFACE',
+          "Only classes and mixins can be used as super-class constraints.");
 
   /**
    * 9.1 Mixin Application: It is a compile-time error if <i>S</i> does not
@@ -1897,9 +1912,6 @@
               "declaring a constructor in {1} that explicitly invokes a "
               "constructor in '{0}'.");
 
-  static const CompileTimeErrorCode NOT_AN_LVALUE =
-      const CompileTimeErrorCode.fromFasta('NOT_AN_LVALUE');
-
   /**
    * 13.2 Expression Statements: It is a compile-time error if a non-constant
    * map literal that has no explicit type arguments appears in a place where a
@@ -2084,14 +2096,9 @@
           "initializers.",
           correction: "Try changing the import to not be deferred.");
 
-  static const CompileTimeErrorCode NON_SYNC_ABSTRACT_METHOD =
-      const CompileTimeErrorCode.fromFasta('NON_SYNC_ABSTRACT_METHOD');
-
-  static const CompileTimeErrorCode NON_SYNC_CONSTRUCTOR =
-      const CompileTimeErrorCode.fromFasta('NON_SYNC_CONSTRUCTOR');
-
   static const CompileTimeErrorCode NON_SYNC_FACTORY =
-      const CompileTimeErrorCode.fromFasta('NON_SYNC_FACTORY');
+      const CompileTimeErrorCode('NON_SYNC_FACTORY',
+          "Factory bodies can't use 'async', 'async*', or 'sync*'.");
 
   /**
    * 12.14.2 Binding Actuals to Formals: It is a static warning if <i>m < h</i>
@@ -2123,9 +2130,6 @@
               "Try calling a different constructor in the superclass, or "
               "making the called constructor not be a factory constructor.");
 
-  static const CompileTimeErrorCode NOT_CONSTANT_EXPRESSION =
-      const CompileTimeErrorCode.fromFasta('NOT_CONSTANT_EXPRESSION');
-
   /**
    * 7.9 Superclasses: It is a compile-time error to specify an extends clause
    * for class Object.
@@ -2135,6 +2139,19 @@
           "The class 'Object' can't extend any other class.");
 
   /**
+   * 10.10 Superinterfaces: It is a compile-time error if two elements in the
+   * type list of the implements clause of a class `C` specifies the same
+   * type `T`.
+   *
+   * Parameters:
+   * 0: the name of the interface that is implemented more than once
+   */
+  static const CompileTimeErrorCode ON_REPEATED = const CompileTimeErrorCode(
+      'ON_REPEATED',
+      "'{0}' can only be used in super-class constraints only once.",
+      correction: "Try removing all but one occurance of the class name.");
+
+  /**
    * 7.1.1 Operators: It is a compile-time error to declare an optional
    * parameter in an operator.
    */
@@ -2261,10 +2278,8 @@
    * Parameters:
    * 0: the name of the class that implements itself recursively
    */
-  static const CompileTimeErrorCode
-      RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_EXTENDS =
-      const CompileTimeErrorCode(
-          'RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_EXTENDS',
+  static const CompileTimeErrorCode RECURSIVE_INTERFACE_INHERITANCE_EXTENDS =
+      const CompileTimeErrorCode('RECURSIVE_INTERFACE_INHERITANCE_EXTENDS',
           "'{0}' can't extend itself.");
 
   /**
@@ -2280,13 +2295,19 @@
    * Parameters:
    * 0: the name of the class that implements itself recursively
    */
-  static const CompileTimeErrorCode
-      RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_IMPLEMENTS =
-      const CompileTimeErrorCode(
-          'RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_IMPLEMENTS',
+  static const CompileTimeErrorCode RECURSIVE_INTERFACE_INHERITANCE_IMPLEMENTS =
+      const CompileTimeErrorCode('RECURSIVE_INTERFACE_INHERITANCE_IMPLEMENTS',
           "'{0}' can't implement itself.");
 
   /**
+   * Parameters:
+   * 0: the name of the mixin that constraints itself recursively
+   */
+  static const CompileTimeErrorCode RECURSIVE_INTERFACE_INHERITANCE_ON =
+      const CompileTimeErrorCode('RECURSIVE_INTERFACE_INHERITANCE_ON',
+          "'{0}' can't use itself as a superclass constraint.");
+
+  /**
    * 7.10 Superinterfaces: It is a compile-time error if the interface of a
    * class <i>C</i> is a superinterface of itself.
    *
@@ -2299,10 +2320,8 @@
    * Parameters:
    * 0: the name of the class that implements itself recursively
    */
-  static const CompileTimeErrorCode
-      RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_WITH =
-      const CompileTimeErrorCode(
-          'RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_WITH',
+  static const CompileTimeErrorCode RECURSIVE_INTERFACE_INHERITANCE_WITH =
+      const CompileTimeErrorCode('RECURSIVE_INTERFACE_INHERITANCE_WITH',
           "'{0}' can't use itself as a mixin.");
 
   /**
@@ -2415,9 +2434,6 @@
           "directives.",
           correction: "Try renaming one of the prefixes.");
 
-  static const CompileTimeErrorCode SUPER_AS_EXPRESSION =
-      const CompileTimeErrorCode.fromFasta('SUPER_AS_EXPRESSION');
-
   /**
    * 12.15.4 Super Invocation: A super method invocation <i>i</i> has the form
    * <i>super.m(a<sub>1</sub>, &hellip;, a<sub>n</sub>, x<sub>n+1</sub>:
@@ -2500,9 +2516,6 @@
           correction: "Try removing the type parameters '<{0}>', or using"
               " 'dynamic' as the type argument here instead of a function.");
 
-  static const CompileTimeErrorCode THIS_ACCESS_FROM_INITIALIZER =
-      const CompileTimeErrorCode.fromFasta('THIS_ACCESS_FROM_INITIALIZER');
-
   /**
    * 15.3.1 Typedef: Any self reference, either directly, or recursively via
    * another typedef, is a compile time error.
@@ -2513,12 +2526,10 @@
           "Typedefs can't reference themselves directly or recursively via "
           "another typedef.");
 
-  static const CompileTimeErrorCode TYPE_PARAMETER_IN_CONST_EXPRESSION =
-      const CompileTimeErrorCode.fromFasta(
-          'TYPE_PARAMETER_IN_CONST_EXPRESSION');
-
   static const CompileTimeErrorCode TYPE_PARAMETER_ON_CONSTRUCTOR =
-      const CompileTimeErrorCode.fromFasta('TYPE_PARAMETER_ON_CONSTRUCTOR');
+      const CompileTimeErrorCode('TYPE_PARAMETER_ON_CONSTRUCTOR',
+          "Constructors can't have type parameters.",
+          correction: "Try removing the type parameters.");
 
   /**
    * 15 Metadata: Metadata consists of a series of annotations, each of which
@@ -2721,14 +2732,6 @@
             correction: correction,
             isUnresolvedIdentifier: isUnresolvedIdentifier);
 
-  /**
-   * Initialize a newly created error code to have the given [name]. No message
-   * or correction are necessary because the error code is only used when
-   * translating an error produced by fasta, and both will be taken from the
-   * error being translated.
-   */
-  const CompileTimeErrorCode.fromFasta(String name) : this(name, '');
-
   @override
   ErrorSeverity get errorSeverity => ErrorType.COMPILE_TIME_ERROR.severity;
 
@@ -3313,6 +3316,21 @@
    * exactly <i>n</i> type parameters.
    *
    * Parameters:
+   * 0: the name of the class being instantiated
+   * 1: the name of the constructor being invoked
+   */
+  static const StaticTypeWarningCode
+      WRONG_NUMBER_OF_TYPE_ARGUMENTS_CONSTRUCTOR = const StaticTypeWarningCode(
+          'WRONG_NUMBER_OF_TYPE_ARGUMENTS_CONSTRUCTOR',
+          "The constructor '{0}.{1}' does not have type parameters.",
+          correction: "Try moving type arguments to after the type name.",
+          errorSeverity: ErrorSeverity.WARNING);
+
+  /**
+   * It will be a static type warning if <i>m</i> is not a generic method with
+   * exactly <i>n</i> type parameters.
+   *
+   * Parameters:
    * 0: the name of the method being referenced (<i>G</i>)
    * 1: the number of type parameters that were declared
    * 2: the number of type arguments provided
@@ -3376,6 +3394,9 @@
           "The type '{0}' used in the 'for' loop must implement {1} with a "
           "type argument that can be assigned to '{2}'.");
 
+  @override
+  final ErrorSeverity errorSeverity;
+
   /**
    * Initialize a newly created error code to have the given [name]. The message
    * associated with the error will be created from the given [message]
@@ -3383,15 +3404,14 @@
    * given [correction] template.
    */
   const StaticTypeWarningCode(String name, String message,
-      {String correction, bool isUnresolvedIdentifier: false})
+      {String correction,
+      this.errorSeverity: ErrorSeverity.ERROR,
+      bool isUnresolvedIdentifier: false})
       : super.temporary(name, message,
             correction: correction,
             isUnresolvedIdentifier: isUnresolvedIdentifier);
 
   @override
-  ErrorSeverity get errorSeverity => ErrorType.STATIC_TYPE_WARNING.severity;
-
-  @override
   ErrorType get type => ErrorType.STATIC_TYPE_WARNING;
 }
 
@@ -3563,47 +3583,6 @@
           correction: "Try making '{1}' abstract, or adding a body to '{0}'.");
 
   /**
-   * 7.1 Instance Methods: It is a static warning if a class <i>C</i> declares
-   * an instance method named <i>n</i> and has a setter named <i>n=</i>.
-   */
-  static const StaticWarningCode CONFLICTING_INSTANCE_METHOD_SETTER =
-      const StaticWarningCode(
-          'CONFLICTING_INSTANCE_METHOD_SETTER',
-          "Class '{0}' declares instance method '{1}', "
-          "but also has a setter with the same name from '{2}'.",
-          correction: "Try renaming either the method or the setter.");
-
-  /**
-   * 7.1 Instance Methods: It is a static warning if a class <i>C</i> declares
-   * an instance method named <i>n</i> and has a setter named <i>n=</i>.
-   */
-  static const StaticWarningCode CONFLICTING_INSTANCE_METHOD_SETTER2 =
-      const StaticWarningCode(
-          'CONFLICTING_INSTANCE_METHOD_SETTER2',
-          "Class '{0}' declares the setter '{1}', "
-          "but also has an instance method in the same class.",
-          correction: "Try renaming either the method or the setter.");
-
-  /**
-   * 7.2 Getters: It is a static warning if a class declares a static getter
-   * named <i>v</i> and also has a non-static setter named <i>v=</i>.
-   */
-  static const StaticWarningCode CONFLICTING_STATIC_GETTER_AND_INSTANCE_SETTER =
-      const StaticWarningCode('CONFLICTING_STATIC_GETTER_AND_INSTANCE_SETTER',
-          "Class '{0}' declares non-static setter with the same name.",
-          correction: "Try renaming either the getter or the setter.");
-
-  /**
-   * 7.3 Setters: It is a static warning if a class declares a static setter
-   * named <i>v=</i> and also has a non-static member named <i>v</i>.
-   */
-  static const StaticWarningCode CONFLICTING_STATIC_SETTER_AND_INSTANCE_MEMBER =
-      const StaticWarningCode('CONFLICTING_STATIC_SETTER_AND_INSTANCE_MEMBER',
-          "Class '{0}' declares non-static member with the same name.",
-          correction:
-              "Try renaming either the inherited member or the setter.");
-
-  /**
    * 16.12.2 Const: Given an instance creation expression of the form <i>const
    * q(a<sub>1</sub>, &hellip; a<sub>n</sub>)</i> it is a static warning if
    * <i>q</i> is the constructor of an abstract class but <i>q</i> is not a
@@ -3841,15 +3820,11 @@
           correction: "Try importing the library that the part is a part of.");
 
   /**
-   * 8.1.1 Inheritance and Overriding: However, if the above rules would cause
-   * multiple members <i>m<sub>1</sub>, &hellip;, m<sub>k</sub></i> with the
-   * same name <i>n</i> that would be inherited (because identically named
-   * members existed in several superinterfaces) then at most one member is
-   * inherited.
-   *
-   * If some but not all of the <i>m<sub>i</sub>, 1 &lt;= i &lt;= k</i> are
-   * getters none of the <i>m<sub>i</sub></i> are inherited, and a static
-   * warning is issued.
+   * 11.1.1 Inheritance and Overriding. Let `I` be the implicit interface of a
+   * class `C` declared in library `L`. `I` inherits all members of
+   * `inherited(I, L)` and `I` overrides `m'` if `m' ∈ overrides(I, L)`. It is
+   * a compile-time error if `m` is a method and `m'` is a getter, or if `m`
+   * is a getter and `m'` is a method.
    */
   static const StaticWarningCode
       INCONSISTENT_METHOD_INHERITANCE_GETTER_AND_METHOD =
@@ -4658,20 +4633,6 @@
           correction: "Try using the type 'bool'.");
 
   /**
-   * 12.17 Getter Invocation: It is a static warning if there is no class
-   * <i>C</i> in the enclosing lexical scope of <i>i</i>, or if <i>C</i> does
-   * not declare, implicitly or explicitly, a getter named <i>m</i>.
-   *
-   * Parameters:
-   * 0: the name of the getter
-   * 1: the name of the enclosing type where the getter is being looked for
-   */
-  static const StaticWarningCode UNDEFINED_GETTER = const StaticWarningCode(
-      'UNDEFINED_GETTER', "The getter '{0}' isn't defined for the class '{1}'.",
-      correction:
-          "Try defining a getter or field named '{0}', or invoke a different getter.");
-
-  /**
    * 12.30 Identifier Reference: It is as static warning if an identifier
    * expression of the form <i>id</i> occurs inside a top level or static
    * function (be it function, method, getter, or setter) or variable
@@ -4714,76 +4675,6 @@
               "defining a new parameter with this name.");
 
   /**
-   * 12.18 Assignment: It is as static warning if an assignment of the form
-   * <i>v = e</i> occurs inside a top level or static function (be it function,
-   * method, getter, or setter) or variable initializer and there is no
-   * declaration <i>d</i> with name <i>v=</i> in the lexical scope enclosing the
-   * assignment.
-   *
-   * 12.18 Assignment: It is a static warning if there is no class <i>C</i> in
-   * the enclosing lexical scope of the assignment, or if <i>C</i> does not
-   * declare, implicitly or explicitly, a setter <i>v=</i>.
-   *
-   * Parameters:
-   * 0: the name of the getter
-   * 1: the name of the enclosing type where the setter is being looked for
-   */
-  static const StaticWarningCode UNDEFINED_SETTER = const StaticWarningCode(
-      'UNDEFINED_SETTER', "The setter '{0}' isn't defined for the class '{1}'.",
-      correction:
-          "Try defining a setter or field named '{0}', or invoke a different setter.");
-
-  /**
-   * 12.16.3 Static Invocation: It is a static warning if <i>C</i> does not
-   * declare a static method or getter <i>m</i>.
-   *
-   * Parameters:
-   * 0: the name of the method
-   * 1: the name of the enclosing type where the method is being looked for
-   */
-  static const StaticWarningCode UNDEFINED_STATIC_METHOD_OR_GETTER =
-      const StaticWarningCode('UNDEFINED_STATIC_METHOD_OR_GETTER',
-          "The static method, getter or setter '{0}' isn't defined for the class '{1}'.",
-          correction: "Try correcting the name to an existing member, or "
-              "defining the member in '{1}'.");
-
-  /**
-   * 12.17 Getter Invocation: It is a static warning if there is no class
-   * <i>C</i> in the enclosing lexical scope of <i>i</i>, or if <i>C</i> does
-   * not declare, implicitly or explicitly, a getter named <i>m</i>.
-   *
-   * Parameters:
-   * 0: the name of the getter
-   * 1: the name of the enclosing type where the getter is being looked for
-   */
-  static const StaticWarningCode UNDEFINED_SUPER_GETTER =
-      const StaticWarningCode('UNDEFINED_SUPER_GETTER',
-          "The getter '{0}' isn't defined in a superclass of '{1}'.",
-          correction: "Try correcting the name to an existing getter, or "
-              "defining the getter in a superclass of '{1}'.");
-
-  /**
-   * 12.18 Assignment: It is as static warning if an assignment of the form
-   * <i>v = e</i> occurs inside a top level or static function (be it function,
-   * method, getter, or setter) or variable initializer and there is no
-   * declaration <i>d</i> with name <i>v=</i> in the lexical scope enclosing the
-   * assignment.
-   *
-   * 12.18 Assignment: It is a static warning if there is no class <i>C</i> in
-   * the enclosing lexical scope of the assignment, or if <i>C</i> does not
-   * declare, implicitly or explicitly, a setter <i>v=</i>.
-   *
-   * Parameters:
-   * 0: the name of the getter
-   * 1: the name of the enclosing type where the setter is being looked for
-   */
-  static const StaticWarningCode UNDEFINED_SUPER_SETTER =
-      const StaticWarningCode('UNDEFINED_SUPER_SETTER',
-          "The setter '{0}' isn't defined in a superclass of '{1}'.",
-          correction: "Try correcting the name to an existing setter, or "
-              "defining the setter in a superclass of '{1}'.");
-
-  /**
    * It is a static warning to assign void to any non-void type in dart.
    * compile-time error). Report that error specially for a better user
    * experience.
@@ -5067,14 +4958,6 @@
           "The type of the function literal can't be inferred because the literal has a block as its body.",
           correction: "Try adding an explicit type to the variable.");
 
-  static const StrongModeCode TOP_LEVEL_FUNCTION_LITERAL_PARAMETER =
-      const StrongModeCode(
-          ErrorType.HINT,
-          'TOP_LEVEL_FUNCTION_LITERAL_PARAMETER',
-          "The type of '{0}' can't be inferred because the parameter '{1}' does not have an explicit type.",
-          correction:
-              "Try adding an explicit type to the parameter '{1}', or add an explicit type for '{0}'.");
-
   static const StrongModeCode TOP_LEVEL_IDENTIFIER_NO_TYPE = const StrongModeCode(
       ErrorType.HINT,
       'TOP_LEVEL_IDENTIFIER_NO_TYPE',
diff --git a/pkg/analyzer/lib/src/fasta/ast_builder.dart b/pkg/analyzer/lib/src/fasta/ast_builder.dart
index 68906df..3b43199 100644
--- a/pkg/analyzer/lib/src/fasta/ast_builder.dart
+++ b/pkg/analyzer/lib/src/fasta/ast_builder.dart
@@ -46,8 +46,7 @@
         messageStaticConstructor,
         messageTypedefNotFunction,
         templateDuplicateLabelInSwitchStatement,
-        templateExpectedIdentifier,
-        templateExpectedType;
+        templateExpectedIdentifier;
 import 'package:front_end/src/fasta/quote.dart';
 import 'package:front_end/src/fasta/scanner/token_constants.dart';
 import 'package:front_end/src/fasta/source/stack_listener.dart'
@@ -331,11 +330,7 @@
     assert(optional(';', semicolon));
     debugEvent("ExpressionStatement");
     Expression expression = pop();
-    if (expression is SuperExpression) {
-      // This error is also reported by the body builder.
-      handleRecoverableError(messageMissingAssignableSelector,
-          expression.beginToken, expression.endToken);
-    }
+    reportErrorIfSuper(expression);
     if (expression is SimpleIdentifier &&
         expression.token?.keyword?.isBuiltInOrPseudo == false) {
       // This error is also reported by the body builder.
@@ -354,6 +349,14 @@
     push(ast.expressionStatement(expression, semicolon));
   }
 
+  void reportErrorIfSuper(Expression expression) {
+    if (expression is SuperExpression) {
+      // This error is also reported by the body builder.
+      handleRecoverableError(messageMissingAssignableSelector,
+          expression.beginToken, expression.endToken);
+    }
+  }
+
   @override
   void handleNativeFunctionBody(Token nativeToken, Token semicolon) {
     assert(optional('native', nativeToken));
@@ -474,6 +477,7 @@
     } else {
       Expression right = pop();
       Expression left = pop();
+      reportErrorIfSuper(right);
       push(ast.binaryExpression(left, operatorToken, right));
     }
   }
@@ -945,17 +949,6 @@
     debugEvent("AsOperator");
 
     TypeAnnotation type = pop();
-    if (type is TypeName) {
-      Identifier name = type.name;
-      if (name is SimpleIdentifier) {
-        if (name.name == 'void') {
-          Token token = name.beginToken;
-          // TODO(danrubel): This needs to be reported during fasta resolution.
-          handleRecoverableError(
-              templateExpectedType.withArguments(token), token, token);
-        }
-      }
-    }
     Expression expression = pop();
     push(ast.asExpression(expression, asOperator, type));
   }
@@ -988,17 +981,6 @@
     debugEvent("IsOperator");
 
     TypeAnnotation type = pop();
-    if (type is TypeName) {
-      Identifier name = type.name;
-      if (name is SimpleIdentifier) {
-        if (name.name == 'void') {
-          Token token = name.beginToken;
-          // TODO(danrubel): This needs to be reported during fasta resolution.
-          handleRecoverableError(
-              templateExpectedType.withArguments(token), token, token);
-        }
-      }
-    }
     Expression expression = pop();
     push(ast.isExpression(expression, isOperator, not, type));
   }
@@ -1011,6 +993,8 @@
     Expression elseExpression = pop();
     Expression thenExpression = pop();
     Expression condition = pop();
+    reportErrorIfSuper(elseExpression);
+    reportErrorIfSuper(thenExpression);
     push(ast.conditionalExpression(
         condition, question, thenExpression, colon, elseExpression));
   }
@@ -1768,22 +1752,24 @@
     assert(optionalOrNull('extends', extendsKeyword));
     debugEvent("ClassExtends");
 
-    ExtendsClause extendsClause;
-    WithClause withClause;
-    var supertype = pop();
-    if (supertype == null) {
-      // No extends clause
-    } else if (supertype is TypeName) {
-      extendsClause = ast.extendsClause(extendsKeyword, supertype);
-    } else if (supertype is _MixinApplication) {
-      extendsClause = ast.extendsClause(extendsKeyword, supertype.supertype);
-      withClause = ast.withClause(supertype.withKeyword, supertype.mixinTypes);
+    TypeName supertype = pop();
+    if (supertype != null) {
+      push(ast.extendsClause(extendsKeyword, supertype));
     } else {
-      unhandled("${supertype.runtimeType}", "supertype",
-          extendsKeyword.charOffset, uri);
+      push(NullValue.ExtendsClause);
     }
-    push(extendsClause ?? NullValue.ExtendsClause);
-    push(withClause ?? NullValue.WithClause);
+  }
+
+  @override
+  void handleClassWithClause(Token withKeyword) {
+    assert(optional('with', withKeyword));
+    List<TypeName> mixinTypes = pop();
+    push(ast.withClause(withKeyword, mixinTypes));
+  }
+
+  @override
+  void handleClassNoWithClause() {
+    push(NullValue.WithClause);
   }
 
   @override
@@ -1947,7 +1933,7 @@
   }
 
   @override
-  void endMixinDeclaration(Token token) {
+  void endMixinDeclaration(Token mixinKeyword, Token endToken) {
     debugEvent("MixinDeclaration");
     mixinDeclaration = null;
   }
@@ -1959,13 +1945,10 @@
   }
 
   @override
-  void endMixinApplication(Token withKeyword) {
+  void handleNamedMixinApplicationWithClause(Token withKeyword) {
     assert(optionalOrNull('with', withKeyword));
-    debugEvent("MixinApplication");
-
     List<TypeName> mixinTypes = pop();
-    TypeName supertype = pop();
-    push(new _MixinApplication(supertype, withKeyword, mixinTypes));
+    push(ast.withClause(withKeyword, mixinTypes));
   }
 
   @override
@@ -1982,10 +1965,8 @@
       List<TypeName> interfaces = pop();
       implementsClause = ast.implementsClause(implementsKeyword, interfaces);
     }
-    _MixinApplication mixinApplication = pop();
-    var superclass = mixinApplication.supertype;
-    var withClause = ast.withClause(
-        mixinApplication.withKeyword, mixinApplication.mixinTypes);
+    WithClause withClause = pop(NullValue.WithClause);
+    TypeName superclass = pop();
     _Modifiers modifiers = pop();
     TypeParameterList typeParameters = pop();
     SimpleIdentifier name = pop();
@@ -2835,22 +2816,6 @@
   }
 }
 
-/// Data structure placed on the stack to represent a mixin application (a
-/// structure of the form "A with B, C").
-///
-/// This is needed because analyzer has no separate AST representation of a
-/// mixin application; it simply stores all of the relevant data in the
-/// [ClassDeclaration] or [ClassTypeAlias] object.
-class _MixinApplication {
-  final TypeName supertype;
-
-  final Token withKeyword;
-
-  final List<TypeName> mixinTypes;
-
-  _MixinApplication(this.supertype, this.withKeyword, this.mixinTypes);
-}
-
 /// Data structure placed on the stack to represent the default parameter
 /// value with the separator token.
 class _ParameterDefaultValue {
diff --git a/pkg/analyzer/lib/src/fasta/error_converter.dart b/pkg/analyzer/lib/src/fasta/error_converter.dart
index aebe4d2..d11fb57 100644
--- a/pkg/analyzer/lib/src/fasta/error_converter.dart
+++ b/pkg/analyzer/lib/src/fasta/error_converter.dart
@@ -114,10 +114,6 @@
         errorReporter?.reportErrorForOffset(
             ParserErrorCode.CONSTRUCTOR_WITH_RETURN_TYPE, offset, length);
         return;
-      case "CONTINUE_OUTSIDE_OF_LOOP":
-        errorReporter?.reportErrorForOffset(
-            ParserErrorCode.CONTINUE_OUTSIDE_OF_LOOP, offset, length);
-        return;
       case "CONTINUE_WITHOUT_LABEL_IN_CASE":
         errorReporter?.reportErrorForOffset(
             ParserErrorCode.CONTINUE_WITHOUT_LABEL_IN_CASE, offset, length);
@@ -126,10 +122,6 @@
         errorReporter?.reportErrorForOffset(
             ParserErrorCode.COVARIANT_AFTER_FINAL, offset, length);
         return;
-      case "COVARIANT_AFTER_VAR":
-        errorReporter?.reportErrorForOffset(
-            ParserErrorCode.COVARIANT_AFTER_VAR, offset, length);
-        return;
       case "COVARIANT_AND_STATIC":
         errorReporter?.reportErrorForOffset(
             ParserErrorCode.COVARIANT_AND_STATIC, offset, length);
@@ -184,12 +176,6 @@
         errorReporter?.reportErrorForOffset(
             ParserErrorCode.ENUM_IN_CLASS, offset, length);
         return;
-      case "EQUALITY_CANNOT_BE_EQUALITY_OPERAND":
-        errorReporter?.reportErrorForOffset(
-            ParserErrorCode.EQUALITY_CANNOT_BE_EQUALITY_OPERAND,
-            offset,
-            length);
-        return;
       case "EXPECTED_CLASS_MEMBER":
         errorReporter?.reportErrorForOffset(
             ParserErrorCode.EXPECTED_CLASS_MEMBER, offset, length);
@@ -228,18 +214,10 @@
         errorReporter?.reportErrorForOffset(
             ParserErrorCode.EXTERNAL_AFTER_STATIC, offset, length);
         return;
-      case "EXTERNAL_CLASS":
-        errorReporter?.reportErrorForOffset(
-            ParserErrorCode.EXTERNAL_CLASS, offset, length);
-        return;
       case "EXTERNAL_CONSTRUCTOR_WITH_BODY":
         errorReporter?.reportErrorForOffset(
             ParserErrorCode.EXTERNAL_CONSTRUCTOR_WITH_BODY, offset, length);
         return;
-      case "EXTERNAL_ENUM":
-        errorReporter?.reportErrorForOffset(
-            ParserErrorCode.EXTERNAL_ENUM, offset, length);
-        return;
       case "EXTERNAL_FIELD":
         errorReporter?.reportErrorForOffset(
             ParserErrorCode.EXTERNAL_FIELD, offset, length);
@@ -324,14 +302,14 @@
             length,
             [type1, type2]);
         return;
+      case "INVALID_INLINE_FUNCTION_TYPE":
+        errorReporter?.reportErrorForOffset(
+            CompileTimeErrorCode.INVALID_INLINE_FUNCTION_TYPE, offset, length);
+        return;
       case "INVALID_LITERAL_IN_CONFIGURATION":
         errorReporter?.reportErrorForOffset(
             ParserErrorCode.INVALID_LITERAL_IN_CONFIGURATION, offset, length);
         return;
-      case "INVALID_AWAIT_IN_FOR":
-        errorReporter?.reportErrorForOffset(
-            ParserErrorCode.INVALID_AWAIT_IN_FOR, offset, length);
-        return;
       case "IMPLEMENTS_BEFORE_EXTENDS":
         errorReporter?.reportErrorForOffset(
             ParserErrorCode.IMPLEMENTS_BEFORE_EXTENDS, offset, length);
@@ -344,12 +322,6 @@
         errorReporter?.reportErrorForOffset(
             ParserErrorCode.IMPLEMENTS_BEFORE_WITH, offset, length);
         return;
-      case "IMPORT_DIRECTIVE_AFTER_PART_DIRECTIVE":
-        errorReporter?.reportErrorForOffset(
-            ParserErrorCode.IMPORT_DIRECTIVE_AFTER_PART_DIRECTIVE,
-            offset,
-            length);
-        return;
       case "IMPORT_OF_NON_LIBRARY":
         errorReporter?.reportErrorForOffset(
             CompileTimeErrorCode.IMPORT_OF_NON_LIBRARY, offset, length);
@@ -482,46 +454,18 @@
         errorReporter?.reportErrorForOffset(
             ParserErrorCode.MISSING_METHOD_PARAMETERS, offset, length);
         return;
-      case "MISSING_PREFIX_IN_DEFERRED_IMPORT":
-        errorReporter?.reportErrorForOffset(
-            ParserErrorCode.MISSING_PREFIX_IN_DEFERRED_IMPORT, offset, length);
-        return;
       case "MISSING_STAR_AFTER_SYNC":
         errorReporter?.reportErrorForOffset(
             ParserErrorCode.MISSING_STAR_AFTER_SYNC, offset, length);
         return;
-      case "MISSING_STATEMENT":
-        errorReporter?.reportErrorForOffset(
-            ParserErrorCode.MISSING_STATEMENT, offset, length);
-        return;
       case "MISSING_TYPEDEF_PARAMETERS":
         errorReporter?.reportErrorForOffset(
             ParserErrorCode.MISSING_TYPEDEF_PARAMETERS, offset, length);
         return;
-      case "MULTIPLE_EXTENDS_CLAUSES":
-        errorReporter?.reportErrorForOffset(
-            ParserErrorCode.MULTIPLE_EXTENDS_CLAUSES, offset, length);
-        return;
       case "MULTIPLE_IMPLEMENTS_CLAUSES":
         errorReporter?.reportErrorForOffset(
             ParserErrorCode.MULTIPLE_IMPLEMENTS_CLAUSES, offset, length);
         return;
-      case "MULTIPLE_LIBRARY_DIRECTIVES":
-        errorReporter?.reportErrorForOffset(
-            ParserErrorCode.MULTIPLE_LIBRARY_DIRECTIVES, offset, length);
-        return;
-      case "MULTIPLE_ON_CLAUSES":
-        errorReporter?.reportErrorForOffset(
-            ParserErrorCode.MULTIPLE_ON_CLAUSES, offset, length);
-        return;
-      case "MULTIPLE_WITH_CLAUSES":
-        errorReporter?.reportErrorForOffset(
-            ParserErrorCode.MULTIPLE_WITH_CLAUSES, offset, length);
-        return;
-      case "MULTIPLE_PART_OF_DIRECTIVES":
-        errorReporter?.reportErrorForOffset(
-            ParserErrorCode.MULTIPLE_PART_OF_DIRECTIVES, offset, length);
-        return;
       case "NAMED_FUNCTION_EXPRESSION":
         errorReporter?.reportErrorForOffset(
             ParserErrorCode.NAMED_FUNCTION_EXPRESSION, offset, length);
@@ -530,10 +474,6 @@
         errorReporter?.reportErrorForOffset(
             ParserErrorCode.NAMED_PARAMETER_OUTSIDE_GROUP, offset, length);
         return;
-      case "NATIVE_CLAUSE_SHOULD_BE_ANNOTATION":
-        errorReporter?.reportErrorForOffset(
-            ParserErrorCode.NATIVE_CLAUSE_SHOULD_BE_ANNOTATION, offset, length);
-        return;
       case "NON_PART_OF_DIRECTIVE_IN_PART":
         errorReporter?.reportErrorForOffset(
             ParserErrorCode.NON_PART_OF_DIRECTIVE_IN_PART, offset, length);
@@ -546,26 +486,12 @@
         errorReporter?.reportErrorForOffset(
             ParserErrorCode.POSITIONAL_AFTER_NAMED_ARGUMENT, offset, length);
         return;
-      case "PREFIX_AFTER_COMBINATOR":
-        errorReporter?.reportErrorForOffset(
-            ParserErrorCode.PREFIX_AFTER_COMBINATOR, offset, length);
-        return;
       case "RECURSIVE_CONSTRUCTOR_REDIRECT":
         errorReporter?.reportErrorForOffset(
             CompileTimeErrorCode.RECURSIVE_CONSTRUCTOR_REDIRECT,
             offset,
             length);
         return;
-      case "REDIRECTING_CONSTRUCTOR_WITH_BODY":
-        errorReporter?.reportErrorForOffset(
-            ParserErrorCode.REDIRECTING_CONSTRUCTOR_WITH_BODY, offset, length);
-        return;
-      case "REDIRECTION_IN_NON_FACTORY_CONSTRUCTOR":
-        errorReporter?.reportErrorForOffset(
-            ParserErrorCode.REDIRECTION_IN_NON_FACTORY_CONSTRUCTOR,
-            offset,
-            length);
-        return;
       case "RETURN_IN_GENERATOR":
         errorReporter?.reportErrorForOffset(
             CompileTimeErrorCode.RETURN_IN_GENERATOR, offset, length,
@@ -577,59 +503,16 @@
         errorReporter?.reportErrorForOffset(
             ParserErrorCode.STACK_OVERFLOW, offset, length);
         return;
-      case "STATIC_AFTER_CONST":
-        errorReporter?.reportErrorForOffset(
-            ParserErrorCode.STATIC_AFTER_CONST, offset, length);
-        return;
-      case "STATIC_AFTER_FINAL":
-        errorReporter?.reportErrorForOffset(
-            ParserErrorCode.STATIC_AFTER_FINAL, offset, length);
-        return;
-      case "STATIC_AFTER_VAR":
-        errorReporter?.reportErrorForOffset(
-            ParserErrorCode.STATIC_AFTER_VAR, offset, length);
-        return;
-      case "STATIC_CONSTRUCTOR":
-        errorReporter?.reportErrorForOffset(
-            ParserErrorCode.STATIC_CONSTRUCTOR, offset, length);
-        return;
-      case "STATIC_OPERATOR":
-        errorReporter?.reportErrorForOffset(
-            ParserErrorCode.STATIC_OPERATOR, offset, length);
-        return;
       case "SUPER_IN_REDIRECTING_CONSTRUCTOR":
         errorReporter?.reportErrorForOffset(
             CompileTimeErrorCode.SUPER_IN_REDIRECTING_CONSTRUCTOR,
             offset,
             length);
         return;
-      case "SWITCH_HAS_CASE_AFTER_DEFAULT_CASE":
-        errorReporter?.reportErrorForOffset(
-            ParserErrorCode.SWITCH_HAS_CASE_AFTER_DEFAULT_CASE, offset, length);
-        return;
-      case "SWITCH_HAS_MULTIPLE_DEFAULT_CASES":
-        errorReporter?.reportErrorForOffset(
-            ParserErrorCode.SWITCH_HAS_MULTIPLE_DEFAULT_CASES, offset, length);
-        return;
-      case "TOP_LEVEL_OPERATOR":
-        errorReporter?.reportErrorForOffset(
-            ParserErrorCode.TOP_LEVEL_OPERATOR, offset, length);
-        return;
-      case "TYPE_ARGUMENTS_ON_TYPE_VARIABLE":
-        errorReporter?.reportErrorForOffset(
-            ParserErrorCode.TYPE_ARGUMENTS_ON_TYPE_VARIABLE,
-            offset,
-            length,
-            [arguments['name']]);
-        return;
       case "TYPE_PARAMETER_ON_CONSTRUCTOR":
         errorReporter?.reportErrorForOffset(
             CompileTimeErrorCode.TYPE_PARAMETER_ON_CONSTRUCTOR, offset, length);
         return;
-      case "TYPEDEF_IN_CLASS":
-        errorReporter?.reportErrorForOffset(
-            ParserErrorCode.TYPEDEF_IN_CLASS, offset, length);
-        return;
       case "UNDEFINED_CLASS":
         errorReporter?.reportErrorForOffset(
             CompileTimeErrorCode.UNDEFINED_CLASS, offset, length);
@@ -666,18 +549,6 @@
         errorReporter?.reportErrorForOffset(
             ParserErrorCode.VAR_AND_TYPE, offset, length);
         return;
-      case "VAR_RETURN_TYPE":
-        errorReporter?.reportErrorForOffset(
-            ParserErrorCode.VAR_RETURN_TYPE, offset, length);
-        return;
-      case "WITH_BEFORE_EXTENDS":
-        errorReporter?.reportErrorForOffset(
-            ParserErrorCode.WITH_BEFORE_EXTENDS, offset, length);
-        return;
-      case "WITH_WITHOUT_EXTENDS":
-        errorReporter?.reportErrorForOffset(
-            ParserErrorCode.WITH_WITHOUT_EXTENDS, offset, length);
-        return;
       case "WRONG_NUMBER_OF_PARAMETERS_FOR_SETTER":
         errorReporter?.reportErrorForOffset(
             CompileTimeErrorCode.WRONG_NUMBER_OF_PARAMETERS_FOR_SETTER,
@@ -724,7 +595,20 @@
   /// the given [offset] and [length].
   void reportMessage(Message message, int offset, int length) {
     Code code = message.code;
-
+    int index = code.index;
+    if (index != null && index > 0 && index < fastaAnalyzerErrorCodes.length) {
+      ErrorCode errorCode = fastaAnalyzerErrorCodes[index];
+      if (errorCode != null) {
+        errorReporter.reportError(new AnalysisError.forValues(
+            errorReporter.source,
+            offset,
+            length,
+            errorCode,
+            message.message,
+            message.tip));
+        return;
+      }
+    }
     reportByCode(code.analyzerCode, offset, length, message);
   }
 
diff --git a/pkg/analyzer/lib/src/generated/element_resolver.dart b/pkg/analyzer/lib/src/generated/element_resolver.dart
index 974721e..cc387c5 100644
--- a/pkg/analyzer/lib/src/generated/element_resolver.dart
+++ b/pkg/analyzer/lib/src/generated/element_resolver.dart
@@ -593,8 +593,31 @@
               _computeCorrespondingParameters(node.argumentList, staticType);
           return null;
         }
-        staticElement = _resolveInvokedElementWithTarget(
-            target, staticType, methodName, isConditional);
+
+        if (target is SuperExpression) {
+          if (staticType is InterfaceTypeImpl) {
+            staticElement = staticType.lookUpInheritedMember(
+                methodName.name, _definingLibrary,
+                concrete: true);
+            // We were not able to find the concrete dispatch target.
+            // But we would like to give the user at least some resolution.
+            // So, we retry without the "concrete" requirement.
+            if (staticElement == null) {
+              staticElement = staticType.lookUpInheritedMember(
+                  methodName.name, _definingLibrary,
+                  concrete: false);
+              if (staticElement != null) {
+                _resolver.errorReporter.reportErrorForNode(
+                    CompileTimeErrorCode.ABSTRACT_SUPER_MEMBER_REFERENCE,
+                    methodName,
+                    [staticElement.kind.displayName, methodName.name]);
+              }
+            }
+          }
+        } else {
+          staticElement = _resolveInvokedElementWithTarget(
+              target, staticType, methodName, isConditional);
+        }
       }
     }
 
@@ -696,8 +719,9 @@
       // Generate the type name.
       // The error code will never be generated via type propagation
       DartType getSuperType(DartType type) {
-        if (type is InterfaceType && !type.isObject) {
-          return type.superclass;
+        if (type is InterfaceType) {
+          InterfaceType superclass = type.superclass;
+          if (superclass != null) return superclass;
         }
         return type;
       }
@@ -784,7 +808,7 @@
       if (element == null) {
         if (identifier.inSetterContext()) {
           _resolver.errorReporter.reportErrorForNode(
-              StaticWarningCode.UNDEFINED_SETTER,
+              StaticTypeWarningCode.UNDEFINED_SETTER,
               identifier,
               [identifier.name, prefixElement.name]);
           return null;
@@ -797,7 +821,7 @@
               [identifier.name]);
         } else {
           _resolver.errorReporter.reportErrorForNode(
-              StaticWarningCode.UNDEFINED_GETTER,
+              StaticTypeWarningCode.UNDEFINED_GETTER,
               identifier,
               [identifier.name, prefixElement.name]);
         }
@@ -2064,7 +2088,29 @@
       }
       staticElement = _resolveElement(typeReference, propertyName);
     } else {
-      staticElement = _resolveProperty(target, staticType, propertyName);
+      if (target is SuperExpression) {
+        if (staticType is InterfaceTypeImpl) {
+          staticElement = staticType.lookUpInheritedMember(
+              propertyName.name, _definingLibrary,
+              setter: propertyName.inSetterContext(), concrete: true);
+          // We were not able to find the concrete dispatch target.
+          // But we would like to give the user at least some resolution.
+          // So, we retry without the "concrete" requirement.
+          if (staticElement == null) {
+            staticElement = staticType.lookUpInheritedMember(
+                propertyName.name, _definingLibrary,
+                setter: propertyName.inSetterContext(), concrete: false);
+            if (staticElement != null) {
+              _resolver.errorReporter.reportErrorForNode(
+                  CompileTimeErrorCode.ABSTRACT_SUPER_MEMBER_REFERENCE,
+                  propertyName,
+                  [staticElement.kind.displayName, propertyName.name]);
+            }
+          }
+        }
+      } else {
+        staticElement = _resolveProperty(target, staticType, propertyName);
+      }
     }
     // May be part of annotation, record property element only if exists.
     // Error was already reported in validateAnnotationElement().
@@ -2103,17 +2149,11 @@
         ErrorCode errorCode;
         var arguments = [propertyName.name, staticType.displayName];
         if (target is SuperExpression) {
-          if (isStaticProperty && !staticType.isVoid) {
-            errorCode = StaticWarningCode.UNDEFINED_SUPER_SETTER;
-          } else {
-            errorCode = StaticTypeWarningCode.UNDEFINED_SUPER_SETTER;
-          }
+          errorCode = StaticTypeWarningCode.UNDEFINED_SUPER_SETTER;
         } else {
           if (staticType.isVoid) {
             errorCode = StaticWarningCode.USE_OF_VOID_RESULT;
             arguments = [];
-          } else if (isStaticProperty) {
-            errorCode = StaticWarningCode.UNDEFINED_SETTER;
           } else {
             errorCode = StaticTypeWarningCode.UNDEFINED_SETTER;
           }
@@ -2124,17 +2164,11 @@
         ErrorCode errorCode;
         var arguments = [propertyName.name, staticType.displayName];
         if (target is SuperExpression) {
-          if (isStaticProperty && !staticType.isVoid) {
-            errorCode = StaticWarningCode.UNDEFINED_SUPER_GETTER;
-          } else {
-            errorCode = StaticTypeWarningCode.UNDEFINED_SUPER_GETTER;
-          }
+          errorCode = StaticTypeWarningCode.UNDEFINED_SUPER_GETTER;
         } else {
           if (staticType.isVoid) {
             errorCode = StaticWarningCode.USE_OF_VOID_RESULT;
             arguments = [];
-          } else if (isStaticProperty) {
-            errorCode = StaticWarningCode.UNDEFINED_GETTER;
           } else {
             errorCode = StaticTypeWarningCode.UNDEFINED_GETTER;
           }
diff --git a/pkg/analyzer/lib/src/generated/engine.dart b/pkg/analyzer/lib/src/generated/engine.dart
index 20824a9..75b6951 100644
--- a/pkg/analyzer/lib/src/generated/engine.dart
+++ b/pkg/analyzer/lib/src/generated/engine.dart
@@ -1136,7 +1136,7 @@
  */
 abstract class AnalysisOptions {
   /**
-   * The length of the list returned by [encodeCrossContextOptions].
+   * The length of the list returned by [signature].
    */
   static const int signatureLength = 4;
 
@@ -1377,6 +1377,11 @@
   static const List<String> NONNULLABLE_TYPES = const <String>[];
 
   /**
+   * The length of the list returned by [unlinkedSignature].
+   */
+  static const int unlinkedSignatureLength = 4;
+
+  /**
    * A predicate indicating whether analysis is to parse and analyze function
    * bodies.
    */
@@ -1384,6 +1389,11 @@
       _analyzeAllFunctionBodies;
 
   /**
+   * The cached [unlinkedSignature].
+   */
+  Uint32List _unlinkedSignature;
+
+  /**
    * The cached [signature].
    */
   Uint32List _signature;
@@ -1705,6 +1715,26 @@
       "The strongMode field is deprecated, and shouldn't be assigned to")
   set strongMode(bool value) {}
 
+  /**
+   * Return the opaque signature of the options that affect unlinked data.
+   *
+   * The length of the list is guaranteed to equal [unlinkedSignatureLength].
+   */
+  Uint32List get unlinkedSignature {
+    if (_unlinkedSignature == null) {
+      ApiSignature buffer = new ApiSignature();
+
+      // Append boolean flags.
+      buffer.addBool(enableLazyAssignmentOperators);
+      buffer.addBool(useFastaParser);
+
+      // Hash and convert to Uint32List.
+      List<int> bytes = buffer.toByteList();
+      _unlinkedSignature = new Uint8List.fromList(bytes).buffer.asUint32List();
+    }
+    return _unlinkedSignature;
+  }
+
   @override
   void resetToDefaults() {
     declarationCasts = true;
diff --git a/pkg/analyzer/lib/src/generated/error_verifier.dart b/pkg/analyzer/lib/src/generated/error_verifier.dart
index 030cb13..a38db59 100644
--- a/pkg/analyzer/lib/src/generated/error_verifier.dart
+++ b/pkg/analyzer/lib/src/generated/error_verifier.dart
@@ -506,8 +506,6 @@
 
       _initializeInitialFieldElementsMap(_enclosingClass.fields);
       _checkForFinalNotInitializedInClass(members);
-      _checkForDuplicateDefinitionInheritance();
-      _checkForConflictingInstanceMethodSetter(node);
       _checkForBadFunctionUse(node);
       return super.visitClassDeclaration(node);
     } finally {
@@ -570,7 +568,6 @@
           node.body, CompileTimeErrorCode.INVALID_MODIFIER_ON_CONSTRUCTOR);
       _checkForConstConstructorWithNonFinalField(node, constructorElement);
       _checkForConstConstructorWithNonConstSuper(node);
-      _checkForConflictingConstructorNameAndMember(node, constructorElement);
       _checkForAllFinalInitializedErrorCodes(node);
       _checkForRedirectingConstructorErrorCodes(node);
       _checkForMixinDeclaresConstructor(node);
@@ -905,6 +902,7 @@
       if (type is InterfaceType) {
         _checkForConstOrNewWithAbstractClass(node, typeName, type);
         _checkForConstOrNewWithEnum(node, typeName, type);
+        _checkForConstOrNewWithMixin(node, typeName, type);
         if (_isInConstInstanceCreation) {
           _checkForConstWithNonConst(node);
           _checkForConstWithUndefinedConstructor(
@@ -987,14 +985,11 @@
       if (node.isSetter || node.isGetter) {
         _checkForMismatchedAccessorTypes(node, methodName);
       }
-      if (node.isGetter) {
-        _checkForConflictingStaticGetterAndInstanceSetter(node);
-      } else if (node.isSetter) {
+      if (node.isSetter) {
         _checkForInvalidModifierOnBody(
             node.body, CompileTimeErrorCode.INVALID_MODIFIER_ON_SETTER);
         _checkForWrongNumberOfParametersForSetter(node.name, node.parameters);
         _checkForNonVoidReturnTypeForSetter(returnType);
-        _checkForConflictingStaticSetterAndInstanceMember(node);
       } else if (node.isOperator) {
         _checkForOptionalParameterInOperator(node);
         _checkForWrongNumberOfParametersForOperator(node);
@@ -1031,17 +1026,15 @@
   @override
   Object visitMixinDeclaration(MixinDeclaration node) {
     // TODO(scheglov) Verify for all mixin errors.
-//    ClassElementImpl outerClass = _enclosingClass;
+    ClassElementImpl outerClass = _enclosingClass;
     try {
-//      _isInNativeClass = node.nativeClause != null;
       _enclosingClass = AbstractClassElementImpl.getImpl(node.declaredElement);
 
       List<ClassMember> members = node.members;
       _checkDuplicateClassMembers(members);
-//      _checkForBuiltInIdentifierAsName(
-//          node.name, CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_NAME);
+      _checkForBuiltInIdentifierAsName(
+          node.name, CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_NAME);
       _checkForMemberWithClassName();
-//      _checkForNoDefaultSuperConstructorImplicit(node);
       _checkForConflictingTypeVariableErrorCodes();
 
       OnClause onClause = node.onClause;
@@ -1054,14 +1047,11 @@
 
       _initializeInitialFieldElementsMap(_enclosingClass.fields);
       _checkForFinalNotInitializedInClass(members);
-//      _checkForDuplicateDefinitionInheritance();
-//      _checkForConflictingInstanceMethodSetter(node);
 //      _checkForBadFunctionUse(node);
       return super.visitMixinDeclaration(node);
     } finally {
-//      _isInNativeClass = false;
       _initialFieldElementsMap = null;
-//      _enclosingClass = outerClass;
+      _enclosingClass = outerClass;
     }
   }
 
@@ -1353,15 +1343,16 @@
     // isn't an error code such as "Cannot extend double" already on the
     // class.
     if (!_checkForExtendsDisallowedClass(superclass) &&
-        !_checkForImplementsDisallowedClass(implementsClause) &&
+        !_checkForImplementsClauseErrorCodes(implementsClause) &&
         !_checkForAllMixinErrorCodes(withClause)) {
       _checkForImplicitDynamicType(superclass);
       _checkForExtendsDeferredClass(superclass);
-      _checkForImplementsDeferredClass(implementsClause);
       _checkForNonAbstractClassInheritsAbstractMember(node.name);
       _checkForInconsistentMethodInheritance();
       _checkForRecursiveInterfaceInheritance(_enclosingClass);
-      _checkForConflictingGetterAndMethod();
+      _checkForConflictingClassMembers();
+      _checkForRepeatedType(implementsClause?.interfaces,
+          CompileTimeErrorCode.IMPLEMENTS_REPEATED);
       _checkImplementsSuperClass(implementsClause);
       _checkForMixinHasNoConstructors(node);
       _checkMixinInference(node, withClause);
@@ -1395,26 +1386,94 @@
    * Check that there are no members with the same name.
    */
   void _checkDuplicateClassMembers(List<ClassMember> members) {
-    Map<String, Element> definedNames = new HashMap<String, Element>();
-    Set<String> visitedFields = new HashSet<String>();
+    Set<String> constructorNames = new HashSet<String>();
+    Map<String, Element> instanceGetters = new HashMap<String, Element>();
+    Map<String, Element> instanceSetters = new HashMap<String, Element>();
+    Map<String, Element> staticGetters = new HashMap<String, Element>();
+    Map<String, Element> staticSetters = new HashMap<String, Element>();
+
     for (ClassMember member in members) {
-      // We ignore constructors because they are checked in the method
-      // _checkForConflictingConstructorNameAndMember.
-      if (member is FieldDeclaration) {
+      if (member is ConstructorDeclaration) {
+        var name = member.name?.name ?? '';
+        if (!constructorNames.add(name)) {
+          if (name.isEmpty) {
+            _errorReporter.reportErrorForNode(
+                CompileTimeErrorCode.DUPLICATE_CONSTRUCTOR_DEFAULT, member);
+          } else {
+            _errorReporter.reportErrorForNode(
+                CompileTimeErrorCode.DUPLICATE_CONSTRUCTOR_NAME,
+                member,
+                [name]);
+          }
+        }
+      } else if (member is FieldDeclaration) {
         for (VariableDeclaration field in member.fields.variables) {
           SimpleIdentifier identifier = field.name;
-          _checkDuplicateIdentifier(definedNames, identifier);
-          String name = identifier.name;
-          if (!field.isFinal &&
-              !field.isConst &&
-              !visitedFields.contains(name)) {
-            _checkDuplicateIdentifier(definedNames, identifier,
-                implicitSetter: true);
-          }
-          visitedFields.add(name);
+          _checkDuplicateIdentifier(
+            member.isStatic ? staticGetters : instanceGetters,
+            identifier,
+            setterScope: member.isStatic ? staticSetters : instanceSetters,
+          );
         }
       } else if (member is MethodDeclaration) {
-        _checkDuplicateIdentifier(definedNames, member.name);
+        _checkDuplicateIdentifier(
+          member.isStatic ? staticGetters : instanceGetters,
+          member.name,
+          setterScope: member.isStatic ? staticSetters : instanceSetters,
+        );
+      }
+    }
+
+    // Check for local static members conflicting with local instance members.
+    for (ClassMember member in members) {
+      if (member is ConstructorDeclaration) {
+        if (member.name != null) {
+          String name = member.name.name;
+          var staticMember = staticGetters[name] ?? staticSetters[name];
+          if (staticMember != null) {
+            if (staticMember is PropertyAccessorElement) {
+              _errorReporter.reportErrorForNode(
+                CompileTimeErrorCode.CONFLICTING_CONSTRUCTOR_AND_STATIC_FIELD,
+                member.name,
+                [name],
+              );
+            } else {
+              _errorReporter.reportErrorForNode(
+                CompileTimeErrorCode.CONFLICTING_CONSTRUCTOR_AND_STATIC_METHOD,
+                member.name,
+                [name],
+              );
+            }
+          }
+        }
+      } else if (member is FieldDeclaration) {
+        if (member.isStatic) {
+          for (VariableDeclaration field in member.fields.variables) {
+            SimpleIdentifier identifier = field.name;
+            String name = identifier.name;
+            if (instanceGetters.containsKey(name) ||
+                instanceSetters.containsKey(name)) {
+              String className = _enclosingClass.displayName;
+              _errorReporter.reportErrorForNode(
+                  CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE,
+                  identifier,
+                  [className, name, className]);
+            }
+          }
+        }
+      } else if (member is MethodDeclaration) {
+        if (member.isStatic) {
+          SimpleIdentifier identifier = member.name;
+          String name = identifier.name;
+          if (instanceGetters.containsKey(name) ||
+              instanceSetters.containsKey(name)) {
+            String className = identifier.staticElement.enclosingElement.name;
+            _errorReporter.reportErrorForNode(
+                CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE,
+                identifier,
+                [className, name, className]);
+          }
+        }
       }
     }
   }
@@ -1482,58 +1541,101 @@
    * Check that there are no members with the same name.
    */
   void _checkDuplicateEnumMembers(EnumDeclaration node) {
-    Map<String, Element> definedNames = new HashMap<String, Element>();
     ClassElement element = node.declaredElement;
+
+    Map<String, Element> instanceGetters = new HashMap<String, Element>();
+    Map<String, Element> staticGetters = new HashMap<String, Element>();
+
     String indexName = 'index';
     String valuesName = 'values';
-    definedNames[indexName] = element.getField(indexName);
-    definedNames[valuesName] = element.getField(valuesName);
+    instanceGetters[indexName] = element.getGetter(indexName);
+    staticGetters[valuesName] = element.getGetter(valuesName);
+
     for (EnumConstantDeclaration constant in node.constants) {
-      _checkDuplicateIdentifier(definedNames, constant.name);
+      _checkDuplicateIdentifier(staticGetters, constant.name);
+    }
+
+    for (EnumConstantDeclaration constant in node.constants) {
+      SimpleIdentifier identifier = constant.name;
+      String name = identifier.name;
+      if (instanceGetters.containsKey(name)) {
+        String enumName = element.displayName;
+        _errorReporter.reportErrorForNode(
+            CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE,
+            identifier,
+            [enumName, name, enumName]);
+      }
     }
   }
 
   /**
-   * Check whether the given [identifier] is already in the set of
-   * [definedNames], and produce an error if it is. If [implicitSetter] is
-   * `true`, then the identifier represents the definition of a setter.
+   * Check whether the given [element] defined by the [identifier] is already
+   * in one of the scopes - [getterScope] or [setterScope], and produce an
+   * error if it is.
    */
   void _checkDuplicateIdentifier(
-      Map<String, Element> definedNames, SimpleIdentifier identifier,
-      {bool implicitSetter: false}) {
+      Map<String, Element> getterScope, SimpleIdentifier identifier,
+      {Element element, Map<String, Element> setterScope}) {
+    element ??= identifier.staticElement;
+
+    // Fields define getters and setters, so check them separately.
+    if (element is PropertyInducingElement) {
+      _checkDuplicateIdentifier(getterScope, identifier,
+          element: element.getter, setterScope: setterScope);
+      if (!element.isConst && !element.isFinal) {
+        _checkDuplicateIdentifier(getterScope, identifier,
+            element: element.setter, setterScope: setterScope);
+      }
+      return;
+    }
+
     ErrorCode getError(Element previous, Element current) {
-      if (previous is MethodElement && current is PropertyAccessorElement) {
-        if (current.isGetter) {
-          return CompileTimeErrorCode.GETTER_AND_METHOD_WITH_SAME_NAME;
-        }
-      } else if (previous is PropertyAccessorElement &&
-          current is MethodElement) {
-        if (previous.isGetter) {
-          return CompileTimeErrorCode.METHOD_AND_GETTER_WITH_SAME_NAME;
-        }
-      } else if (previous is PrefixElement) {
+      if (previous is PrefixElement) {
         return CompileTimeErrorCode.PREFIX_COLLIDES_WITH_TOP_LEVEL_MEMBER;
       }
       return CompileTimeErrorCode.DUPLICATE_DEFINITION;
     }
 
-    Element current = identifier.staticElement;
+    bool isGetterSetterPair(Element a, Element b) {
+      if (a is PropertyAccessorElement && b is PropertyAccessorElement) {
+        return a.isGetter && b.isSetter || a.isSetter && b.isGetter;
+      }
+      return false;
+    }
+
     String name = identifier.name;
-    if (current is PropertyAccessorElement && current.isSetter) {
-      name += '=';
-    } else if (current is MethodElement && current.isOperator && name == '-') {
-      if (current.parameters.length == 0) {
+    if (element is MethodElement && element.isOperator && name == '-') {
+      if (element.parameters.length == 0) {
         name = 'unary-';
       }
-    } else if (implicitSetter) {
-      name += '=';
     }
-    Element previous = definedNames[name];
+
+    Element previous = getterScope[name];
     if (previous != null) {
-      _errorReporter
-          .reportErrorForNode(getError(previous, current), identifier, [name]);
+      if (isGetterSetterPair(element, previous)) {
+        // OK
+      } else {
+        _errorReporter.reportErrorForNode(
+          getError(previous, element),
+          identifier,
+          [name],
+        );
+      }
     } else {
-      definedNames[name] = identifier.staticElement;
+      getterScope[name] = element;
+    }
+
+    if (element is PropertyAccessorElement && element.isSetter) {
+      previous = setterScope[name];
+      if (previous != null) {
+        _errorReporter.reportErrorForNode(
+          getError(previous, element),
+          identifier,
+          [name],
+        );
+      } else {
+        setterScope[name] = element;
+      }
     }
   }
 
@@ -1541,39 +1643,41 @@
    * Check that there are no members with the same name.
    */
   void _checkDuplicateUnitMembers(CompilationUnit node) {
-    Map<String, Element> definedNames = new HashMap<String, Element>();
+    Map<String, Element> definedGetters = new HashMap<String, Element>();
+    Map<String, Element> definedSetters = new HashMap<String, Element>();
+
     void addWithoutChecking(CompilationUnitElement element) {
       for (PropertyAccessorElement accessor in element.accessors) {
         String name = accessor.name;
         if (accessor.isSetter) {
           name += '=';
         }
-        definedNames[name] = accessor;
+        definedGetters[name] = accessor;
       }
       for (ClassElement type in element.enums) {
-        definedNames[type.name] = type;
+        definedGetters[type.name] = type;
       }
       for (FunctionElement function in element.functions) {
-        definedNames[function.name] = function;
+        definedGetters[function.name] = function;
       }
       for (FunctionTypeAliasElement alias in element.functionTypeAliases) {
-        definedNames[alias.name] = alias;
+        definedGetters[alias.name] = alias;
       }
       for (TopLevelVariableElement variable in element.topLevelVariables) {
-        definedNames[variable.name] = variable;
+        definedGetters[variable.name] = variable;
         if (!variable.isFinal && !variable.isConst) {
-          definedNames[variable.name + '='] = variable;
+          definedGetters[variable.name + '='] = variable;
         }
       }
       for (ClassElement type in element.types) {
-        definedNames[type.name] = type;
+        definedGetters[type.name] = type;
       }
     }
 
     for (ImportElement importElement in _currentLibrary.imports) {
       PrefixElement prefix = importElement.prefix;
       if (prefix != null) {
-        definedNames[prefix.name] = prefix;
+        definedGetters[prefix.name] = prefix;
       }
     }
     CompilationUnitElement element = node.declaredElement;
@@ -1588,14 +1692,12 @@
     }
     for (CompilationUnitMember member in node.declarations) {
       if (member is NamedCompilationUnitMember) {
-        _checkDuplicateIdentifier(definedNames, member.name);
+        _checkDuplicateIdentifier(definedGetters, member.name,
+            setterScope: definedSetters);
       } else if (member is TopLevelVariableDeclaration) {
         for (VariableDeclaration variable in member.variables.variables) {
-          _checkDuplicateIdentifier(definedNames, variable.name);
-          if (!variable.isFinal && !variable.isConst) {
-            _checkDuplicateIdentifier(definedNames, variable.name,
-                implicitSetter: true);
-          }
+          _checkDuplicateIdentifier(definedGetters, variable.name,
+              setterScope: definedSetters);
         }
       }
     }
@@ -1808,7 +1910,8 @@
       return false;
     }
     bool problemReported = false;
-    for (TypeName mixinName in withClause.mixinTypes) {
+    for (int i = 0; i < withClause.mixinTypes.length; i++) {
+      TypeName mixinName = withClause.mixinTypes[i];
       DartType mixinType = mixinName.type;
       if (mixinType is InterfaceType) {
         if (_checkForExtendsOrImplementsDisallowedClass(
@@ -1820,15 +1923,25 @@
               mixinName, CompileTimeErrorCode.MIXIN_DEFERRED_CLASS)) {
             problemReported = true;
           }
-          if (_checkForMixinClassDeclaresConstructor(mixinName, mixinElement)) {
-            problemReported = true;
-          }
-          if (!enableSuperMixins &&
-              _checkForMixinInheritsNotFromObject(mixinName, mixinElement)) {
-            problemReported = true;
-          }
-          if (_checkForMixinReferencesSuper(mixinName, mixinElement)) {
-            problemReported = true;
+          if (mixinElement.isMixin) {
+            if (_checkForMixinSuperclassConstraints(mixinName, i)) {
+              problemReported = true;
+            }
+            if (_checkForMixinSuperInvokedMembers(mixinName, mixinElement)) {
+              problemReported = true;
+            }
+          } else {
+            if (_checkForMixinClassDeclaresConstructor(
+                mixinName, mixinElement)) {
+              problemReported = true;
+            }
+            if (!enableSuperMixins &&
+                _checkForMixinInheritsNotFromObject(mixinName, mixinElement)) {
+              problemReported = true;
+            }
+            if (_checkForMixinReferencesSuper(mixinName, mixinElement)) {
+              problemReported = true;
+            }
           }
         }
       }
@@ -2353,56 +2466,69 @@
   }
 
   /**
-   * Verify all possible conflicts of the given [constructor]'s name with other
-   * constructors and members of the same class. The [constructorElement] is the
-   * constructor's element.
+   * Verify that the [_enclosingClass] does not have a method and getter pair
+   * with the same name on, via inheritance.
    *
-   * See [CompileTimeErrorCode.DUPLICATE_CONSTRUCTOR_DEFAULT],
-   * [CompileTimeErrorCode.DUPLICATE_CONSTRUCTOR_NAME],
-   * [CompileTimeErrorCode.CONFLICTING_CONSTRUCTOR_NAME_AND_FIELD], and
-   * [CompileTimeErrorCode.CONFLICTING_CONSTRUCTOR_NAME_AND_METHOD].
+   * See [CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE],
+   * [CompileTimeErrorCode.CONFLICTING_METHOD_AND_FIELD], and
+   * [CompileTimeErrorCode.CONFLICTING_FIELD_AND_METHOD].
    */
-  void _checkForConflictingConstructorNameAndMember(
-      ConstructorDeclaration constructor,
-      ConstructorElement constructorElement) {
-    SimpleIdentifier constructorName = constructor.name;
-    String name = constructorElement.name;
-    ClassElement classElement = constructorElement.enclosingElement;
-    // constructors
-    List<ConstructorElement> constructors = classElement.constructors;
-    for (ConstructorElement otherConstructor in constructors) {
-      if (identical(otherConstructor, constructorElement)) {
-        continue;
-      }
-      if (name == otherConstructor.name) {
-        if (name == null || name.length == 0) {
-          _errorReporter.reportErrorForNode(
-              CompileTimeErrorCode.DUPLICATE_CONSTRUCTOR_DEFAULT, constructor);
-        } else {
-          _errorReporter.reportErrorForNode(
-              CompileTimeErrorCode.DUPLICATE_CONSTRUCTOR_NAME,
-              constructor,
-              [name]);
-        }
-        return;
+  void _checkForConflictingClassMembers() {
+    if (_enclosingClass == null) {
+      return;
+    }
+
+    // method declared in the enclosing class vs. inherited getter/setter
+    for (MethodElement method in _enclosingClass.methods) {
+      String name = method.name;
+
+      // find inherited property accessor
+      ExecutableElement inherited =
+          _inheritanceManager.lookupInheritance(_enclosingClass, name);
+      inherited ??=
+          _inheritanceManager.lookupInheritance(_enclosingClass, '$name=');
+
+      if (method.isStatic && inherited != null) {
+        _errorReporter.reportErrorForElement(
+            CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, method, [
+          _enclosingClass.displayName,
+          name,
+          inherited.enclosingElement.displayName,
+        ]);
+      } else if (inherited is PropertyAccessorElement) {
+        _errorReporter.reportErrorForElement(
+            CompileTimeErrorCode.CONFLICTING_METHOD_AND_FIELD, method, [
+          _enclosingClass.displayName,
+          inherited.enclosingElement.displayName,
+          name
+        ]);
       }
     }
-    // conflict with class member
-    if (constructorName != null &&
-        constructorElement != null &&
-        !constructorName.isSynthetic) {
-      FieldElement field = classElement.getField(name);
-      if (field != null && field.getter != null) {
-        _errorReporter.reportErrorForNode(
-            CompileTimeErrorCode.CONFLICTING_CONSTRUCTOR_NAME_AND_FIELD,
-            constructor,
-            [name]);
-      } else if (classElement.getMethod(name) != null) {
-        // methods
-        _errorReporter.reportErrorForNode(
-            CompileTimeErrorCode.CONFLICTING_CONSTRUCTOR_NAME_AND_METHOD,
-            constructor,
-            [name]);
+
+    // getter declared in the enclosing class vs. inherited method
+    for (PropertyAccessorElement accessor in _enclosingClass.accessors) {
+      String name = accessor.displayName;
+
+      // find inherited method or property accessor
+      ExecutableElement inherited =
+          _inheritanceManager.lookupInheritance(_enclosingClass, name);
+      inherited ??=
+          _inheritanceManager.lookupInheritance(_enclosingClass, '$name=');
+
+      if (accessor.isStatic && inherited != null) {
+        _errorReporter.reportErrorForElement(
+            CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, accessor, [
+          _enclosingClass.displayName,
+          name,
+          inherited.enclosingElement.displayName,
+        ]);
+      } else if (inherited is MethodElement) {
+        _errorReporter.reportErrorForElement(
+            CompileTimeErrorCode.CONFLICTING_FIELD_AND_METHOD, accessor, [
+          _enclosingClass.displayName,
+          name,
+          inherited.enclosingElement.displayName
+        ]);
       }
     }
   }
@@ -2428,6 +2554,7 @@
       }
       visit(type.superclass);
       type.mixins.forEach(visit);
+      type.superclassConstraints.forEach(visit);
       type.interfaces.forEach(visit);
       visitedClasses.removeLast();
     }
@@ -2436,235 +2563,6 @@
   }
 
   /**
-   * Verify that the [_enclosingClass] does not have a method and getter pair
-   * with the same name on, via inheritance.
-   *
-   * See [CompileTimeErrorCode.CONFLICTING_GETTER_AND_METHOD], and
-   * [CompileTimeErrorCode.CONFLICTING_METHOD_AND_GETTER].
-   */
-  void _checkForConflictingGetterAndMethod() {
-    if (_enclosingClass == null) {
-      return;
-    }
-
-    // method declared in the enclosing class vs. inherited getter
-    for (MethodElement method in _enclosingClass.methods) {
-      String name = method.name;
-      // find inherited property accessor (and can be only getter)
-      ExecutableElement inherited =
-          _inheritanceManager.lookupInheritance(_enclosingClass, name);
-      if (inherited is! PropertyAccessorElement) {
-        continue;
-      }
-
-      _errorReporter.reportErrorForElement(
-          CompileTimeErrorCode.CONFLICTING_GETTER_AND_METHOD, method, [
-        _enclosingClass.displayName,
-        inherited.enclosingElement.displayName,
-        name
-      ]);
-    }
-    // getter declared in the enclosing class vs. inherited method
-    for (PropertyAccessorElement accessor in _enclosingClass.accessors) {
-      if (!accessor.isGetter) {
-        continue;
-      }
-      String name = accessor.name;
-      // find inherited method
-      ExecutableElement inherited =
-          _inheritanceManager.lookupInheritance(_enclosingClass, name);
-      if (inherited is! MethodElement) {
-        continue;
-      }
-
-      _errorReporter.reportErrorForElement(
-          CompileTimeErrorCode.CONFLICTING_METHOD_AND_GETTER, accessor, [
-        _enclosingClass.displayName,
-        inherited.enclosingElement.displayName,
-        name
-      ]);
-    }
-  }
-
-  /**
-   * Verify that the enclosing class does not have a setter with the same name
-   * as the given instance method declaration.
-   *
-   * TODO(jwren) add other "conflicting" error codes into algorithm/ data
-   * structure.
-   *
-   * See [StaticWarningCode.CONFLICTING_INSTANCE_METHOD_SETTER].
-   */
-  void _checkForConflictingInstanceMethodSetter(ClassDeclaration declaration) {
-    // Reference all of the class members in this class.
-    NodeList<ClassMember> classMembers = declaration.members;
-    if (classMembers.isEmpty) {
-      return;
-    }
-    // Create a HashMap to track conflicting members, and then loop through
-    // members in the class to construct the HashMap, at the same time,
-    // look for violations.  Don't add members if they are part of a conflict,
-    // this prevents multiple warnings for one issue.
-    Map<String, ClassMember> memberHashMap = new HashMap<String, ClassMember>();
-    for (ClassMember member in classMembers) {
-      if (member is MethodDeclaration) {
-        if (member.isStatic) {
-          continue;
-        }
-        // prepare name
-        SimpleIdentifier name = member.name;
-        if (name == null) {
-          continue;
-        }
-        bool addThisMemberToTheMap = true;
-        bool isGetter = member.isGetter;
-        bool isSetter = member.isSetter;
-        bool isOperator = member.isOperator;
-        bool isMethod = !isGetter && !isSetter && !isOperator;
-        // Do lookups in the enclosing class (and the inherited member) if the
-        // member is a method or a setter for
-        // StaticWarningCode.CONFLICTING_INSTANCE_METHOD_SETTER warning.
-        if (isMethod) {
-          String setterName = "${name.name}=";
-          Element enclosingElementOfSetter = null;
-          ClassMember conflictingSetter = memberHashMap[setterName];
-          if (conflictingSetter != null) {
-            enclosingElementOfSetter = resolutionMap
-                .elementDeclaredByDeclaration(conflictingSetter)
-                .enclosingElement;
-          } else {
-            ExecutableElement elementFromInheritance = _inheritanceManager
-                .lookupInheritance(_enclosingClass, setterName);
-            if (elementFromInheritance != null) {
-              enclosingElementOfSetter =
-                  elementFromInheritance.enclosingElement;
-            }
-          }
-          if (enclosingElementOfSetter != null) {
-            _errorReporter.reportErrorForNode(
-                StaticWarningCode.CONFLICTING_INSTANCE_METHOD_SETTER, name, [
-              _enclosingClass.displayName,
-              name.name,
-              enclosingElementOfSetter.displayName
-            ]);
-            addThisMemberToTheMap = false;
-          }
-        } else if (isSetter) {
-          String methodName = name.name;
-          ClassMember conflictingMethod = memberHashMap[methodName];
-          if (conflictingMethod != null &&
-              conflictingMethod is MethodDeclaration &&
-              !conflictingMethod.isGetter) {
-            _errorReporter.reportErrorForNode(
-                StaticWarningCode.CONFLICTING_INSTANCE_METHOD_SETTER2,
-                name,
-                [_enclosingClass.displayName, name.name]);
-            addThisMemberToTheMap = false;
-          }
-        }
-        // Finally, add this member into the HashMap.
-        if (addThisMemberToTheMap) {
-          if (member.isSetter) {
-            memberHashMap["${name.name}="] = member;
-          } else {
-            memberHashMap[name.name] = member;
-          }
-        }
-      }
-    }
-  }
-
-  /**
-   * Verify that the enclosing class does not have an instance member with the
-   * same name as the given static [method] declaration.
-   *
-   * See [StaticWarningCode.CONFLICTING_STATIC_GETTER_AND_INSTANCE_SETTER].
-   */
-  void _checkForConflictingStaticGetterAndInstanceSetter(
-      MethodDeclaration method) {
-    if (!method.isStatic) {
-      return;
-    }
-    // prepare name
-    SimpleIdentifier nameNode = method.name;
-    if (nameNode == null) {
-      return;
-    }
-    String name = nameNode.name;
-    // prepare enclosing type
-    if (_enclosingClass == null) {
-      return;
-    }
-    InterfaceType enclosingType = _enclosingClass.type;
-    // try to find setter
-    ExecutableElement setter =
-        enclosingType.lookUpSetter(name, _currentLibrary);
-    if (setter == null) {
-      return;
-    }
-    // OK, also static
-    if (setter.isStatic) {
-      return;
-    }
-    // prepare "setter" type to report its name
-    ClassElement setterClass = setter.enclosingElement as ClassElement;
-    InterfaceType setterType = setterClass.type;
-
-    _errorReporter.reportErrorForNode(
-        StaticWarningCode.CONFLICTING_STATIC_GETTER_AND_INSTANCE_SETTER,
-        nameNode,
-        [setterType.displayName]);
-  }
-
-  /**
-   * Verify that the enclosing class does not have an instance member with the
-   * same name as the given static [method] declaration.
-   *
-   * See [StaticWarningCode.CONFLICTING_STATIC_SETTER_AND_INSTANCE_MEMBER].
-   */
-  void _checkForConflictingStaticSetterAndInstanceMember(
-      MethodDeclaration method) {
-    if (!method.isStatic) {
-      return;
-    }
-    // prepare name
-    SimpleIdentifier nameNode = method.name;
-    if (nameNode == null) {
-      return;
-    }
-    String name = nameNode.name;
-    // prepare enclosing type
-    if (_enclosingClass == null) {
-      return;
-    }
-    InterfaceType enclosingType = _enclosingClass.type;
-    // try to find member
-    ExecutableElement member;
-    member = enclosingType.lookUpMethod(name, _currentLibrary);
-    if (member == null) {
-      member = enclosingType.lookUpGetter(name, _currentLibrary);
-    }
-    if (member == null) {
-      member = enclosingType.lookUpSetter(name, _currentLibrary);
-    }
-    if (member == null) {
-      return;
-    }
-    // OK, also static
-    if (member.isStatic) {
-      return;
-    }
-    // prepare "member" type to report its name
-    ClassElement memberClass = member.enclosingElement as ClassElement;
-    InterfaceType memberType = memberClass.type;
-
-    _errorReporter.reportErrorForNode(
-        StaticWarningCode.CONFLICTING_STATIC_SETTER_AND_INSTANCE_MEMBER,
-        nameNode,
-        [memberType.displayName]);
-  }
-
-  /**
    * Verify all conflicts between type variable and enclosing class.
    * TODO(scheglov)
    *
@@ -2872,6 +2770,17 @@
   }
 
   /**
+   * Verify that the given [expression] is not a mixin instantiation.
+   */
+  void _checkForConstOrNewWithMixin(InstanceCreationExpression expression,
+      TypeName typeName, InterfaceType type) {
+    if (type.element.isMixin) {
+      _errorReporter.reportErrorForNode(
+          CompileTimeErrorCode.MIXIN_INSTANTIATE, typeName);
+    }
+  }
+
+  /**
    * Verify that the given 'const' instance creation [expression] is not being
    * invoked on a constructor that is not 'const'.
    *
@@ -3009,67 +2918,6 @@
   }
 
   /**
-   * Verify that the enclosing class does not have an instance member with the
-   * given name of the static member.
-   *
-   * See [CompileTimeErrorCode.DUPLICATE_DEFINITION_INHERITANCE].
-   */
-  void _checkForDuplicateDefinitionInheritance() {
-    if (_enclosingClass == null) {
-      return;
-    }
-
-    for (ExecutableElement member in _enclosingClass.methods) {
-      if (member.isStatic) {
-        _checkForDuplicateDefinitionOfMember(member);
-      }
-    }
-    for (ExecutableElement member in _enclosingClass.accessors) {
-      if (member.isStatic) {
-        _checkForDuplicateDefinitionOfMember(member);
-      }
-    }
-  }
-
-  /**
-   * Verify that the enclosing class does not have an instance member with the
-   * given name of the [staticMember].
-   *
-   * See [CompileTimeErrorCode.DUPLICATE_DEFINITION_INHERITANCE].
-   */
-  void _checkForDuplicateDefinitionOfMember(ExecutableElement staticMember) {
-    // prepare name
-    String name = staticMember.name;
-    if (name == null) {
-      return;
-    }
-    // try to find member
-    ExecutableElement inheritedMember =
-        _inheritanceManager.lookupInheritance(_enclosingClass, name);
-    if (inheritedMember == null) {
-      return;
-    }
-    // OK, also static
-    if (inheritedMember.isStatic) {
-      return;
-    }
-    // determine the display name, use the extended display name if the
-    // enclosing class of the inherited member is in a different source
-    String displayName;
-    Element enclosingElement = inheritedMember.enclosingElement;
-    if (enclosingElement.source == _enclosingClass.source) {
-      displayName = enclosingElement.displayName;
-    } else {
-      displayName = enclosingElement.getExtendedDisplayName(null);
-    }
-
-    _errorReporter.reportErrorForElement(
-        CompileTimeErrorCode.DUPLICATE_DEFINITION_INHERITANCE,
-        staticMember,
-        [name, displayName]);
-  }
-
-  /**
    * Verify that if the given list [literal] has type arguments then there is
    * exactly one. The [typeArguments] are the type arguments.
    *
@@ -3214,7 +3062,7 @@
    *
    * See [_checkForExtendsDisallowedClass],
    * [_checkForExtendsDisallowedClassInTypeAlias],
-   * [_checkForImplementsDisallowedClass],
+   * [_checkForImplementsClauseErrorCodes],
    * [_checkForAllMixinErrorCodes],
    * [CompileTimeErrorCode.EXTENDS_DISALLOWED_CLASS],
    * [CompileTimeErrorCode.IMPLEMENTS_DISALLOWED_CLASS], and
@@ -3498,28 +3346,13 @@
   }
 
   /**
-   * Verify that the given implements [clause] does not implement classes that
-   * are deferred.
-   *
-   * See [CompileTimeErrorCode.IMPLEMENTS_DEFERRED_CLASS].
-   */
-  void _checkForImplementsDeferredClass(ImplementsClause clause) {
-    if (clause == null) {
-      return;
-    }
-    for (TypeName type in clause.interfaces) {
-      _checkForExtendsOrImplementsDeferredClass(
-          type, CompileTimeErrorCode.IMPLEMENTS_DEFERRED_CLASS);
-    }
-  }
-
-  /**
    * Verify that the given implements [clause] does not implement classes such
    * as 'num' or 'String'.
    *
-   * See [CompileTimeErrorCode.IMPLEMENTS_DISALLOWED_CLASS].
+   * See [CompileTimeErrorCode.IMPLEMENTS_DISALLOWED_CLASS],
+   * [CompileTimeErrorCode.IMPLEMENTS_DEFERRED_CLASS].
    */
-  bool _checkForImplementsDisallowedClass(ImplementsClause clause) {
+  bool _checkForImplementsClauseErrorCodes(ImplementsClause clause) {
     if (clause == null) {
       return false;
     }
@@ -3528,6 +3361,9 @@
       if (_checkForExtendsOrImplementsDisallowedClass(
           type, CompileTimeErrorCode.IMPLEMENTS_DISALLOWED_CLASS)) {
         foundError = true;
+      } else if (_checkForExtendsOrImplementsDeferredClass(
+          type, CompileTimeErrorCode.IMPLEMENTS_DEFERRED_CLASS)) {
+        foundError = true;
       }
     }
     return foundError;
@@ -4420,6 +4256,66 @@
     return false;
   }
 
+  /// Check that superclass constrains for the mixin type of [mixinName] at
+  /// the [index] position in the mixins list are satisfied by the
+  /// [_enclosingClass], or a previous mixin.
+  bool _checkForMixinSuperclassConstraints(TypeName mixinName, int index) {
+    InterfaceType mixinType = mixinName.type;
+    for (var constraint in mixinType.superclassConstraints) {
+      bool isSatisfied =
+          _typeSystem.isSubtypeOf(_enclosingClass.supertype, constraint);
+      if (!isSatisfied) {
+        for (int i = 0; i < index && !isSatisfied; i++) {
+          isSatisfied =
+              _typeSystem.isSubtypeOf(_enclosingClass.mixins[i], constraint);
+        }
+      }
+      if (!isSatisfied) {
+        _errorReporter.reportErrorForNode(
+            CompileTimeErrorCode.MIXIN_APPLICATION_NOT_IMPLEMENTED_INTERFACE,
+            mixinName.name,
+            [constraint.displayName]);
+        return true;
+      }
+    }
+    return false;
+  }
+
+  /// Check that the [_enclosingClass] has concrete implementations of all
+  /// the super-invoked members of the [mixinElement].
+  bool _checkForMixinSuperInvokedMembers(
+      TypeName mixinName, ClassElementImpl mixinElement) {
+    InterfaceTypeImpl enclosingType = _enclosingClass.type;
+    for (var name in mixinElement.superInvokedNames) {
+      var superMember = enclosingType.lookUpInheritedMember(
+          name, _currentLibrary,
+          concrete: true, setter: name.endsWith('='));
+      if (superMember == null) {
+        _errorReporter.reportErrorForNode(
+            CompileTimeErrorCode
+                .MIXIN_APPLICATION_NO_CONCRETE_SUPER_INVOKED_MEMBER,
+            mixinName.name,
+            [name]);
+        return true;
+      }
+
+      var mixinMember =
+          _inheritanceManager.lookupInheritance(mixinElement, name);
+      var superMemberType = superMember.type;
+      var mixinMemberType = mixinMember?.type;
+      if (mixinMemberType != null &&
+          !_typeSystem.isSubtypeOf(superMemberType, mixinMemberType)) {
+        _errorReporter.reportErrorForNode(
+            CompileTimeErrorCode
+                .MIXIN_APPLICATION_CONCRETE_SUPER_INVOKED_MEMBER_TYPE,
+            mixinName.name,
+            [name, mixinMemberType.displayName, superMemberType.displayName]);
+        return true;
+      }
+    }
+    return false;
+  }
+
   /**
    * Check for the declaration of a mixin from a library other than the current
    * library that defines a private member that conflicts with a private name
@@ -4846,9 +4742,8 @@
   /**
    * Verify that all classes of the given [onClause] are valid.
    *
-   * See [CompileTimeErrorCode.MIXIN_CLASS_DECLARES_CONSTRUCTOR],
-   * [CompileTimeErrorCode.MIXIN_INHERITS_FROM_NOT_OBJECT], and
-   * [CompileTimeErrorCode.MIXIN_REFERENCES_SUPER].
+   * See [CompileTimeErrorCode.MIXIN_SUPER_CLASS_CONSTRAINT_DISALLOWED_CLASS],
+   * [CompileTimeErrorCode.MIXIN_SUPER_CLASS_CONSTRAINT_DEFERRED_CLASS].
    */
   bool _checkForOnClauseErrorCodes(OnClause onClause) {
     if (onClause == null) {
@@ -4899,17 +4794,52 @@
     }
   }
 
+  /**
+   * Via informal specification: dart-lang/language/issues/4
+   *
+   * If e is an integer literal which is not the operand of a unary minus
+   * operator, then:
+   *   - If the context type is double, it is a compile-time error if the
+   *   numerical value of e is not precisely representable by a double.
+   *   Otherwise the static type of e is double and the result of evaluating e
+   *   is a double instance representing that value.
+   *   - Otherwise (the current behavior of e, with a static type of int).
+   *
+   * and
+   *
+   * If e is -n and n is an integer literal, then
+   *   - If the context type is double, it is a compile-time error if the
+   *   numerical value of n is not precisley representable by a double.
+   *   Otherwise the static type of e is double and the result of evaluating e
+   *   is the result of calling the unary minus operator on a double instance
+   *   representing the numerical value of n.
+   *   - Otherwise (the current behavior of -n)
+   */
   void _checkForOutOfRange(IntegerLiteral node) {
     String lexeme = node.literal.lexeme;
-    AstNode parent = node.parent;
-    bool isNegated =
-        parent is PrefixExpression && parent.operator.type == TokenType.MINUS;
-    if (!IntegerLiteralImpl.isValidLiteral(lexeme, isNegated)) {
-      if (isNegated) {
-        lexeme = '-$lexeme';
+    final bool isNegated = (node as IntegerLiteralImpl).immediatelyNegated;
+    final List<Object> extraErrorArgs = [];
+
+    final bool treatedAsDouble = node.staticType == _typeProvider.doubleType;
+    final bool valid = treatedAsDouble
+        ? IntegerLiteralImpl.isValidAsDouble(lexeme)
+        : IntegerLiteralImpl.isValidAsInteger(lexeme, isNegated);
+
+    if (!valid) {
+      extraErrorArgs.add(isNegated ? '-$lexeme' : lexeme);
+
+      if (treatedAsDouble) {
+        // Suggest the nearest valid double (as a BigInt for printing reasons).
+        extraErrorArgs
+            .add(BigInt.from(IntegerLiteralImpl.nearestValidDouble(lexeme)));
       }
+
       _errorReporter.reportErrorForNode(
-          CompileTimeErrorCode.INTEGER_LITERAL_OUT_OF_RANGE, node, [lexeme]);
+          treatedAsDouble
+              ? CompileTimeErrorCode.INTEGER_LITERAL_IMPRECISE_AS_DOUBLE
+              : CompileTimeErrorCode.INTEGER_LITERAL_OUT_OF_RANGE,
+          node,
+          extraErrorArgs);
     }
   }
 
@@ -4988,18 +4918,83 @@
   }
 
   /**
-   * Check that the class [element] is not a superinterface to itself.
+   * Check that [_enclosingClass] is not a superinterface to itself.
+   *  The [path] is a list containing the potentially cyclic implements path.
    *
    * See [CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE],
-   * [CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_EXTENDS], and
-   * [CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_IMPLEMENTS].
+   * [CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_EXTENDS],
+   * [CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_IMPLEMENTS],
+   * [CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_ON],
+   * [CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_WITH].
    */
-  void _checkForRecursiveInterfaceInheritance(ClassElement element) {
-    if (element == null) {
-      return;
+  bool _checkForRecursiveInterfaceInheritance(ClassElement element,
+      [List<ClassElement> path]) {
+    path ??= <ClassElement>[];
+
+    // Detect error condition.
+    int size = path.length;
+    // If this is not the base case (size > 0), and the enclosing class is the
+    // given class element then an error an error.
+    if (size > 0 && _enclosingClass == element) {
+      String enclosingClassName = _enclosingClass.displayName;
+      if (size > 1) {
+        // Construct a string showing the cyclic implements path:
+        // "A, B, C, D, A"
+        String separator = ", ";
+        StringBuffer buffer = new StringBuffer();
+        for (int i = 0; i < size; i++) {
+          buffer.write(path[i].displayName);
+          buffer.write(separator);
+        }
+        buffer.write(element.displayName);
+        _errorReporter.reportErrorForElement(
+            CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE,
+            _enclosingClass,
+            [enclosingClassName, buffer.toString()]);
+        return true;
+      } else {
+        // RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_EXTENDS or
+        // RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_IMPLEMENTS or
+        // RECURSIVE_INTERFACE_INHERITANCE_ON or
+        // RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_WITH
+        _errorReporter.reportErrorForElement(_getBaseCaseErrorCode(element),
+            _enclosingClass, [enclosingClassName]);
+        return true;
+      }
     }
 
-    _safeCheckForRecursiveInterfaceInheritance(element, <ClassElement>[]);
+    if (path.indexOf(element) > 0) {
+      return false;
+    }
+    path.add(element);
+
+    // n-case
+    InterfaceType supertype = element.supertype;
+    if (supertype != null &&
+        _checkForRecursiveInterfaceInheritance(supertype.element, path)) {
+      return true;
+    }
+
+    for (InterfaceType type in element.mixins) {
+      if (_checkForRecursiveInterfaceInheritance(type.element, path)) {
+        return true;
+      }
+    }
+
+    for (InterfaceType type in element.superclassConstraints) {
+      if (_checkForRecursiveInterfaceInheritance(type.element, path)) {
+        return true;
+      }
+    }
+
+    for (InterfaceType type in element.interfaces) {
+      if (_checkForRecursiveInterfaceInheritance(type.element, path)) {
+        return true;
+      }
+    }
+
+    path.removeAt(path.length - 1);
+    return false;
   }
 
   /**
@@ -5129,6 +5124,31 @@
     }
   }
 
+  void _checkForRepeatedType(List<TypeName> typeNames, ErrorCode errorCode) {
+    if (typeNames == null) {
+      return;
+    }
+
+    int count = typeNames.length;
+    List<bool> detectedRepeatOnIndex = new List<bool>.filled(count, false);
+    for (int i = 0; i < detectedRepeatOnIndex.length; i++) {
+      detectedRepeatOnIndex[i] = false;
+    }
+    for (int i = 0; i < count; i++) {
+      if (!detectedRepeatOnIndex[i]) {
+        Element element = typeNames[i].name.staticElement;
+        for (int j = i + 1; j < count; j++) {
+          TypeName typeName = typeNames[j];
+          if (typeName.name.staticElement == element) {
+            detectedRepeatOnIndex[j] = true;
+            _errorReporter
+                .reportErrorForNode(errorCode, typeName, [typeName.name.name]);
+          }
+        }
+      }
+    }
+  }
+
   /**
    * Check that the given rethrow [expression] is inside of a catch clause.
    *
@@ -5852,25 +5872,25 @@
    */
   void _checkMixinInheritance(MixinDeclaration node, OnClause onClause,
       ImplementsClause implementsClause) {
-    // TODO(scheglov) Verify for all mixin errors.
     // Only check for all of the inheritance logic around clauses if there
     // isn't an error code such as "Cannot implement double" already.
     if (!_checkForOnClauseErrorCodes(onClause) &&
-        !_checkForImplementsDisallowedClass(implementsClause)) {
+        !_checkForImplementsClauseErrorCodes(implementsClause)) {
 //      _checkForImplicitDynamicType(superclass);
-//      _checkForExtendsDeferredClass(superclass);
-      _checkForImplementsDeferredClass(implementsClause);
-//      _checkForNonAbstractClassInheritsAbstractMember(node.name);
-//      _checkForInconsistentMethodInheritance();
-//      _checkForRecursiveInterfaceInheritance(_enclosingClass);
-//      _checkForConflictingGetterAndMethod();
-//      _checkImplementsSuperClass(implementsClause);
-//      _checkForMixinHasNoConstructors(node);
-//      _checkMixinInference(node, onClause);
-//      _checkForMixinWithConflictingPrivateMember(onClause, superclass);
-//      if (!disableConflictingGenericsCheck) {
-//        _checkForConflictingGenerics(node);
-//      }
+      _checkForInconsistentMethodInheritance();
+      _checkForRecursiveInterfaceInheritance(_enclosingClass);
+      _checkForConflictingClassMembers();
+      _checkForRepeatedType(
+        onClause?.superclassConstraints,
+        CompileTimeErrorCode.ON_REPEATED,
+      );
+      _checkForRepeatedType(
+        implementsClause?.interfaces,
+        CompileTimeErrorCode.IMPLEMENTS_REPEATED,
+      );
+      if (!disableConflictingGenericsCheck) {
+        _checkForConflictingGenerics(node);
+      }
     }
   }
 
@@ -6023,20 +6043,23 @@
    * references itself directly.
    */
   ErrorCode _getBaseCaseErrorCode(ClassElement element) {
-    InterfaceType supertype = element.supertype;
-    if (supertype != null && _enclosingClass == supertype.element) {
-      return CompileTimeErrorCode
-          .RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_EXTENDS;
+    if (element.supertype?.element == _enclosingClass) {
+      return CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_EXTENDS;
     }
-    List<InterfaceType> mixins = element.mixins;
-    for (int i = 0; i < mixins.length; i++) {
-      if (_enclosingClass == mixins[i].element) {
-        return CompileTimeErrorCode
-            .RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_WITH;
+
+    for (InterfaceType type in element.superclassConstraints) {
+      if (type.element == _enclosingClass) {
+        return CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_ON;
       }
     }
-    return CompileTimeErrorCode
-        .RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_IMPLEMENTS;
+
+    for (InterfaceType type in element.mixins) {
+      if (type.element == _enclosingClass) {
+        return CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_WITH;
+      }
+    }
+
+    return CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_IMPLEMENTS;
   }
 
   /**
@@ -6292,74 +6315,6 @@
   }
 
   /**
-   * Check that the given class [element] is not a superinterface to itself. The
-   * [path] is a list containing the potentially cyclic implements path.
-   *
-   * See [CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE],
-   * [CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_EXTENDS],
-   * [CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_IMPLEMENTS],
-   * and [CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_WITH].
-   */
-  bool _safeCheckForRecursiveInterfaceInheritance(
-      ClassElement element, List<ClassElement> path) {
-    // Detect error condition.
-    int size = path.length;
-    // If this is not the base case (size > 0), and the enclosing class is the
-    // given class element then an error an error.
-    if (size > 0 && _enclosingClass == element) {
-      String enclosingClassName = _enclosingClass.displayName;
-      if (size > 1) {
-        // Construct a string showing the cyclic implements path:
-        // "A, B, C, D, A"
-        String separator = ", ";
-        StringBuffer buffer = new StringBuffer();
-        for (int i = 0; i < size; i++) {
-          buffer.write(path[i].displayName);
-          buffer.write(separator);
-        }
-        buffer.write(element.displayName);
-        _errorReporter.reportErrorForElement(
-            CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE,
-            _enclosingClass,
-            [enclosingClassName, buffer.toString()]);
-        return true;
-      } else {
-        // RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_EXTENDS or
-        // RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_IMPLEMENTS or
-        // RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_WITH
-        _errorReporter.reportErrorForElement(_getBaseCaseErrorCode(element),
-            _enclosingClass, [enclosingClassName]);
-        return true;
-      }
-    }
-    if (path.indexOf(element) > 0) {
-      return false;
-    }
-    path.add(element);
-    // n-case
-    InterfaceType supertype = element.supertype;
-    if (supertype != null &&
-        _safeCheckForRecursiveInterfaceInheritance(supertype.element, path)) {
-      return true;
-    }
-    List<InterfaceType> interfaceTypes = element.interfaces;
-    for (InterfaceType interfaceType in interfaceTypes) {
-      if (_safeCheckForRecursiveInterfaceInheritance(
-          interfaceType.element, path)) {
-        return true;
-      }
-    }
-    List<InterfaceType> mixinTypes = element.mixins;
-    for (InterfaceType mixinType in mixinTypes) {
-      if (_safeCheckForRecursiveInterfaceInheritance(mixinType.element, path)) {
-        return true;
-      }
-    }
-    path.removeAt(path.length - 1);
-    return false;
-  }
-
-  /**
    * Returns [ExecutableElement]s that are declared in interfaces implemented
    * by the [classElement], but not implemented by the [classElement] or its
    * superclasses.
diff --git a/pkg/analyzer/lib/src/generated/parser.dart b/pkg/analyzer/lib/src/generated/parser.dart
index fe33ae00..50e1c08 100644
--- a/pkg/analyzer/lib/src/generated/parser.dart
+++ b/pkg/analyzer/lib/src/generated/parser.dart
@@ -1270,10 +1270,6 @@
         foundClause = false;
       }
     }
-    if (withClause != null && extendsClause == null) {
-      _reportErrorForToken(
-          ParserErrorCode.WITH_WITHOUT_EXTENDS, withClause.withKeyword);
-    }
     //
     // Look for and skip over the extra-lingual 'native' specification.
     //
diff --git a/pkg/analyzer/lib/src/generated/parser_fasta.dart b/pkg/analyzer/lib/src/generated/parser_fasta.dart
index 8cbdd21..43b0b5f 100644
--- a/pkg/analyzer/lib/src/generated/parser_fasta.dart
+++ b/pkg/analyzer/lib/src/generated/parser_fasta.dart
@@ -27,7 +27,6 @@
       {bool allowNativeClause: false})
       : fastaParser = new fasta.Parser(null),
         astBuilder = new AstBuilder(errorReporter, fileUri, true) {
-    fastaParser.isMixinSupportEnabled = true;
     fastaParser.listener = astBuilder;
     astBuilder.parser = fastaParser;
     astBuilder.allowNativeClause = allowNativeClause;
diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart
index 911c655..8eed8da 100644
--- a/pkg/analyzer/lib/src/generated/resolver.dart
+++ b/pkg/analyzer/lib/src/generated/resolver.dart
@@ -109,18 +109,28 @@
         // Possible case: C.n()
         var constructorElement = element.getNamedConstructor(methodName.name);
         if (constructorElement != null) {
+          var typeArguments = node.typeArguments;
+          if (typeArguments != null) {
+            errorReporter.reportErrorForNode(
+                StaticTypeWarningCode
+                    .WRONG_NUMBER_OF_TYPE_ARGUMENTS_CONSTRUCTOR,
+                node,
+                [element.name, constructorElement.name]);
+          }
           AstFactory astFactory = new AstFactoryImpl();
-          TypeName typeName = astFactory.typeName(target, node.typeArguments);
+          TypeName typeName = astFactory.typeName(target, typeArguments);
           ConstructorName constructorName =
               astFactory.constructorName(typeName, node.operator, methodName);
           InstanceCreationExpression instanceCreationExpression =
               astFactory.instanceCreationExpression(
                   _getKeyword(node), constructorName, node.argumentList);
-          InterfaceType type = _getType(element, node.typeArguments);
+          InterfaceType type = _getType(element, typeArguments);
           constructorElement =
               type.lookUpConstructor(methodName.name, definingLibrary);
           methodName.staticElement = element;
           methodName.staticType = type;
+          target.staticElement = element;
+          target.staticType = type; // TODO(scheglov) remove this
           typeName.type = type;
           constructorName.staticElement = constructorElement;
           instanceCreationExpression.staticType = type;
@@ -159,23 +169,33 @@
     } else if (target is PrefixedIdentifier) {
       // Possible case: p.C.n()
       Element prefixElement = nameScope.lookup(target.prefix, definingLibrary);
+      target.prefix.staticElement = prefixElement;
       if (prefixElement is PrefixElement) {
         Element element = nameScope.lookup(target, definingLibrary);
         if (element is ClassElement) {
           var constructorElement = element.getNamedConstructor(methodName.name);
           if (constructorElement != null) {
+            var typeArguments = node.typeArguments;
+            if (typeArguments != null) {
+              errorReporter.reportErrorForNode(
+                  StaticTypeWarningCode
+                      .WRONG_NUMBER_OF_TYPE_ARGUMENTS_CONSTRUCTOR,
+                  node,
+                  [element.name, constructorElement.name]);
+            }
             AstFactory astFactory = new AstFactoryImpl();
-            TypeName typeName = astFactory.typeName(target, node.typeArguments);
+            TypeName typeName = astFactory.typeName(target, typeArguments);
             ConstructorName constructorName =
                 astFactory.constructorName(typeName, node.operator, methodName);
             InstanceCreationExpression instanceCreationExpression =
                 astFactory.instanceCreationExpression(
                     _getKeyword(node), constructorName, node.argumentList);
-            InterfaceType type = _getType(element, node.typeArguments);
+            InterfaceType type = _getType(element, typeArguments);
             constructorElement =
                 type.lookUpConstructor(methodName.name, definingLibrary);
             methodName.staticElement = element;
             methodName.staticType = type;
+            target.identifier.staticElement = element;
             typeName.type = type;
             constructorName.staticElement = constructorElement;
             instanceCreationExpression.staticType = type;
@@ -464,8 +484,6 @@
 
   @override
   Object visitMethodInvocation(MethodInvocation node) {
-    Expression realTarget = node.realTarget;
-    _checkForAbstractSuperMemberReference(realTarget, node.methodName);
     _checkForNullAwareHints(node, node.operator);
     DartType staticInvokeType = node.staticInvokeType;
     Element callElement = staticInvokeType?.element;
@@ -490,8 +508,6 @@
 
   @override
   Object visitPropertyAccess(PropertyAccess node) {
-    Expression realTarget = node.realTarget;
-    _checkForAbstractSuperMemberReference(realTarget, node.propertyName);
     _checkForNullAwareHints(node, node.operator);
     return super.visitPropertyAccess(node);
   }
@@ -585,33 +601,6 @@
     return false;
   }
 
-  void _checkForAbstractSuperMemberReference(
-      Expression target, SimpleIdentifier name) {
-    if (target is SuperExpression &&
-        !_currentLibrary.context.analysisOptions.enableSuperMixins) {
-      Element element = name.staticElement;
-      if (element is ExecutableElement && element.isAbstract) {
-        ExecutableElement concrete = null;
-        if (element.kind == ElementKind.METHOD) {
-          concrete = _enclosingClass.lookUpInheritedConcreteMethod(
-              element.displayName, _currentLibrary);
-        } else if (element.kind == ElementKind.GETTER) {
-          concrete = _enclosingClass.lookUpInheritedConcreteGetter(
-              element.displayName, _currentLibrary);
-        } else if (element.kind == ElementKind.SETTER) {
-          concrete = _enclosingClass.lookUpInheritedConcreteSetter(
-              element.displayName, _currentLibrary);
-        }
-        if (concrete == null) {
-          _errorReporter.reportTypeErrorForNode(
-              HintCode.ABSTRACT_SUPER_MEMBER_REFERENCE,
-              name,
-              [element.kind.displayName, name.name]);
-        }
-      }
-    }
-  }
-
   /**
    * Given some [Element], look at the associated metadata and report the use of the member if
    * it is declared as deprecated.
@@ -7861,175 +7850,6 @@
 }
 
 /**
- * Instances of this class manage the knowledge of what the set of subtypes are for a given type.
- */
-class SubtypeManager {
-  /**
-   * A map between [ClassElement]s and a set of [ClassElement]s that are subtypes of the
-   * key.
-   */
-  Map<ClassElement, HashSet<ClassElement>> _subtypeMap =
-      new HashMap<ClassElement, HashSet<ClassElement>>();
-
-  /**
-   * The set of all [LibraryElement]s that have been visited by the manager. This is used both
-   * to prevent infinite loops in the recursive methods, and also as a marker for the scope of the
-   * libraries visited by this manager.
-   */
-  HashSet<LibraryElement> _visitedLibraries = new HashSet<LibraryElement>();
-
-  /**
-   * Given some [ClassElement], return the set of all subtypes, and subtypes of subtypes.
-   *
-   * @param classElement the class to recursively return the set of subtypes of
-   */
-  HashSet<ClassElement> computeAllSubtypes(ClassElement classElement) {
-    // Ensure that we have generated the subtype map for the library
-    _computeSubtypesInLibrary(classElement.library);
-    // use the subtypeMap to compute the set of all subtypes and subtype's
-    // subtypes
-    HashSet<ClassElement> allSubtypes = new HashSet<ClassElement>();
-    _safelyComputeAllSubtypes(
-        classElement, new HashSet<ClassElement>(), allSubtypes);
-    return allSubtypes;
-  }
-
-  /**
-   * Given some [LibraryElement], visit all of the types in the library, the passed library,
-   * and any imported libraries, will be in the [visitedLibraries] set.
-   *
-   * @param libraryElement the library to visit, it it hasn't been visited already
-   */
-  void ensureLibraryVisited(LibraryElement libraryElement) {
-    _computeSubtypesInLibrary(libraryElement);
-  }
-
-  /**
-   * Given some [ClassElement], this method adds all of the pairs combinations of itself and
-   * all of its supertypes to the [subtypeMap] map.
-   *
-   * @param classElement the class element
-   */
-  void _computeSubtypesInClass(ClassElement classElement) {
-    InterfaceType supertypeType = classElement.supertype;
-    if (supertypeType != null) {
-      ClassElement supertypeElement = supertypeType.element;
-      if (supertypeElement != null) {
-        _putInSubtypeMap(supertypeElement, classElement);
-      }
-    }
-    List<InterfaceType> interfaceTypes = classElement.interfaces;
-    int interfaceLength = interfaceTypes.length;
-    for (int i = 0; i < interfaceLength; i++) {
-      InterfaceType interfaceType = interfaceTypes[i];
-      ClassElement interfaceElement = interfaceType.element;
-      if (interfaceElement != null) {
-        _putInSubtypeMap(interfaceElement, classElement);
-      }
-    }
-    List<InterfaceType> mixinTypes = classElement.mixins;
-    int mixinLength = mixinTypes.length;
-    for (int i = 0; i < mixinLength; i++) {
-      InterfaceType mixinType = mixinTypes[i];
-      ClassElement mixinElement = mixinType.element;
-      if (mixinElement != null) {
-        _putInSubtypeMap(mixinElement, classElement);
-      }
-    }
-  }
-
-  /**
-   * Given some [CompilationUnitElement], this method calls
-   * [computeAllSubtypes] on all of the [ClassElement]s in the
-   * compilation unit.
-   *
-   * @param unitElement the compilation unit element
-   */
-  void _computeSubtypesInCompilationUnit(CompilationUnitElement unitElement) {
-    List<ClassElement> classElements = unitElement.types;
-    int length = classElements.length;
-    for (int i = 0; i < length; i++) {
-      ClassElement classElement = classElements[i];
-      _computeSubtypesInClass(classElement);
-    }
-  }
-
-  /**
-   * Given some [LibraryElement], this method calls
-   * [computeAllSubtypes] on all of the [ClassElement]s in the
-   * compilation unit, and itself for all imported and exported libraries. All visited libraries are
-   * added to the [visitedLibraries] set.
-   *
-   * @param libraryElement the library element
-   */
-  void _computeSubtypesInLibrary(LibraryElement libraryElement) {
-    if (libraryElement == null || _visitedLibraries.contains(libraryElement)) {
-      return;
-    }
-    _visitedLibraries.add(libraryElement);
-    _computeSubtypesInCompilationUnit(libraryElement.definingCompilationUnit);
-    List<CompilationUnitElement> parts = libraryElement.parts;
-    int partLength = parts.length;
-    for (int i = 0; i < partLength; i++) {
-      CompilationUnitElement part = parts[i];
-      _computeSubtypesInCompilationUnit(part);
-    }
-    List<LibraryElement> imports = libraryElement.importedLibraries;
-    int importLength = imports.length;
-    for (int i = 0; i < importLength; i++) {
-      LibraryElement importElt = imports[i];
-      _computeSubtypesInLibrary(importElt.library);
-    }
-    List<LibraryElement> exports = libraryElement.exportedLibraries;
-    int exportLength = exports.length;
-    for (int i = 0; i < exportLength; i++) {
-      LibraryElement exportElt = exports[i];
-      _computeSubtypesInLibrary(exportElt.library);
-    }
-  }
-
-  /**
-   * Add some key/ value pair into the [subtypeMap] map.
-   *
-   * @param supertypeElement the key for the [subtypeMap] map
-   * @param subtypeElement the value for the [subtypeMap] map
-   */
-  void _putInSubtypeMap(
-      ClassElement supertypeElement, ClassElement subtypeElement) {
-    HashSet<ClassElement> subtypes = _subtypeMap[supertypeElement];
-    if (subtypes == null) {
-      subtypes = new HashSet<ClassElement>();
-      _subtypeMap[supertypeElement] = subtypes;
-    }
-    subtypes.add(subtypeElement);
-  }
-
-  /**
-   * Given some [ClassElement] and a [HashSet<ClassElement>], this method recursively
-   * adds all of the subtypes of the [ClassElement] to the passed array.
-   *
-   * @param classElement the type to compute the set of subtypes of
-   * @param visitedClasses the set of class elements that this method has already recursively seen
-   * @param allSubtypes the computed set of subtypes of the passed class element
-   */
-  void _safelyComputeAllSubtypes(ClassElement classElement,
-      HashSet<ClassElement> visitedClasses, HashSet<ClassElement> allSubtypes) {
-    if (!visitedClasses.add(classElement)) {
-      // if this class has already been called on this class element
-      return;
-    }
-    HashSet<ClassElement> subtypes = _subtypeMap[classElement];
-    if (subtypes == null) {
-      return;
-    }
-    for (ClassElement subtype in subtypes) {
-      _safelyComputeAllSubtypes(subtype, visitedClasses, allSubtypes);
-    }
-    allSubtypes.addAll(subtypes);
-  }
-}
-
-/**
  * Instances of the class `ToDoFinder` find to-do comments in Dart code.
  */
 class ToDoFinder {
@@ -9780,7 +9600,8 @@
       ErrorCode errorCode = (withClause == null
           ? CompileTimeErrorCode.EXTENDS_NON_CLASS
           : CompileTimeErrorCode.MIXIN_WITH_NON_CLASS_SUPERCLASS);
-      superclassType = _resolveType(extendsClause.superclass, errorCode);
+      superclassType =
+          _resolveType(extendsClause.superclass, errorCode, asClass: true);
     }
     if (classElement != null) {
       if (superclassType == null) {
@@ -9825,7 +9646,8 @@
   Object visitClassTypeAlias(ClassTypeAlias node) {
     super.visitClassTypeAlias(node);
     ErrorCode errorCode = CompileTimeErrorCode.MIXIN_WITH_NON_CLASS_SUPERCLASS;
-    InterfaceType superclassType = _resolveType(node.superclass, errorCode);
+    InterfaceType superclassType =
+        _resolveType(node.superclass, errorCode, asClass: true);
     if (superclassType == null) {
       superclassType = typeProvider.objectType;
     }
@@ -10296,29 +10118,6 @@
       if (classElement != null) {
         classElement.interfaces = interfaceTypes;
       }
-      // TODO(brianwilkerson) Move the following checks to ErrorVerifier.
-      int count = interfaces.length;
-      List<bool> detectedRepeatOnIndex = new List<bool>.filled(count, false);
-      for (int i = 0; i < detectedRepeatOnIndex.length; i++) {
-        detectedRepeatOnIndex[i] = false;
-      }
-      for (int i = 0; i < count; i++) {
-        TypeName typeName = interfaces[i];
-        if (!detectedRepeatOnIndex[i]) {
-          Element element = typeName.name.staticElement;
-          for (int j = i + 1; j < count; j++) {
-            TypeName typeName2 = interfaces[j];
-            Identifier identifier2 = typeName2.name;
-            String name2 = identifier2.name;
-            Element element2 = identifier2.staticElement;
-            if (element != null && element == element2) {
-              detectedRepeatOnIndex[j] = true;
-              errorReporter.reportErrorForNode(
-                  CompileTimeErrorCode.IMPLEMENTS_REPEATED, typeName2, [name2]);
-            }
-          }
-        }
-      }
     }
   }
 
@@ -10326,7 +10125,7 @@
     List<InterfaceType> types;
     if (clause != null) {
       types = _resolveTypes(clause.superclassConstraints,
-          CompileTimeErrorCode.MIXIN_SUPER_CLASS_CONSTRAINT_NON_CLASS);
+          CompileTimeErrorCode.MIXIN_SUPER_CLASS_CONSTRAINT_NON_INTERFACE);
     }
     if (types == null || types.isEmpty) {
       types = [typeProvider.objectType];
@@ -10335,22 +10134,24 @@
   }
 
   /**
-   * Return the type specified by the given name.
+   * Return the [InterfaceType] of the given [typeName].
    *
-   * @param typeName the type name specifying the type to be returned
-   * @param nonTypeError the error to produce if the type name is defined to be something other than
-   *          a type
-   * @param enumTypeError the error to produce if the type name is defined to be an enum
-   * @param dynamicTypeError the error to produce if the type name is "dynamic"
-   * @return the type specified by the type name
+   * If the resulting type is not a valid interface type, return `null`.
+   *
+   * The flag [asClass] specifies if the type will be used as a class, so mixin
+   * declarations are not valid (they declare interfaces and mixins, but not
+   * classes).
    */
-  InterfaceType _resolveType(TypeName typeName, ErrorCode errorCode) {
+  InterfaceType _resolveType(TypeName typeName, ErrorCode errorCode,
+      {bool asClass: false}) {
     DartType type = typeName.type;
     if (type is InterfaceType) {
       ClassElement element = type.element;
-      if (element != null && element.isEnum) {
-        errorReporter.reportErrorForNode(errorCode, typeName);
-        return null;
+      if (element != null) {
+        if (element.isEnum || element.isMixin && asClass) {
+          errorReporter.reportErrorForNode(errorCode, typeName);
+          return null;
+        }
       }
       return type;
     }
diff --git a/pkg/analyzer/lib/src/generated/static_type_analyzer.dart b/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
index 5e69a5b..e95f2da 100644
--- a/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
+++ b/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
@@ -10,6 +10,7 @@
 import 'package:analyzer/dart/ast/visitor.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/src/dart/ast/ast.dart';
 import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/dart/element/member.dart' show ConstructorMember;
 import 'package:analyzer/src/dart/element/type.dart';
@@ -548,12 +549,34 @@
   }
 
   /**
-   * The Dart Language Specification, 12.3: <blockquote>The static type of an integer literal is
-   * `int`.</blockquote>
+   * <blockquote>
+   * An integer literal has static type \code{int}, unless the surrounding
+   * static context type is a type which \code{int} is not assignable to, and
+   * \code{double} is. In that case the static type of the integer literal is
+   * \code{double}.
+   * <blockquote>
+   *
+   * and
+   *
+   * <blockquote>
+   * If $e$ is an expression of the form \code{-$l$} where $l$ is an integer
+   * literal (\ref{numbers}) with numeric integer value $i$, then the static
+   * type of $e$ is the same as the static type of an integer literal with the
+   * same contexttype
+   * </blockquote>
    */
   @override
   Object visitIntegerLiteral(IntegerLiteral node) {
-    _recordStaticType(node, _typeProvider.intType);
+    // Check the parent context for negated integer literals.
+    var context = InferenceContext.getContext(
+        (node as IntegerLiteralImpl).immediatelyNegated ? node.parent : node);
+    if (context == null ||
+        _typeSystem.isAssignableTo(_typeProvider.intType, context) ||
+        !_typeSystem.isAssignableTo(_typeProvider.doubleType, context)) {
+      _recordStaticType(node, _typeProvider.intType);
+    } else {
+      _recordStaticType(node, _typeProvider.doubleType);
+    }
     return null;
   }
 
diff --git a/pkg/analyzer/lib/src/generated/type_system.dart b/pkg/analyzer/lib/src/generated/type_system.dart
index 2a7ac3e..0f80220d 100644
--- a/pkg/analyzer/lib/src/generated/type_system.dart
+++ b/pkg/analyzer/lib/src/generated/type_system.dart
@@ -1582,7 +1582,9 @@
     visitedTypes ??= new HashSet<ClassElement>();
     if (!visitedTypes.add(i1Element)) return false;
 
-    if (_isInterfaceSubtypeOf(i1.superclass, i2, visitedTypes)) {
+    InterfaceType superclass = i1.superclass;
+    if (superclass != null &&
+        _isInterfaceSubtypeOf(superclass, i2, visitedTypes)) {
       return true;
     }
 
@@ -1598,6 +1600,14 @@
       }
     }
 
+    if (i1Element.isMixin) {
+      for (final parent in i1.superclassConstraints) {
+        if (_isInterfaceSubtypeOf(parent, i2, visitedTypes)) {
+          return true;
+        }
+      }
+    }
+
     return false;
   }
 
diff --git a/pkg/analyzer/lib/src/lint/linter.dart b/pkg/analyzer/lib/src/lint/linter.dart
index e4fde6c..d9050f4 100644
--- a/pkg/analyzer/lib/src/lint/linter.dart
+++ b/pkg/analyzer/lib/src/lint/linter.dart
@@ -288,9 +288,8 @@
     Source source = createSource(node.span.sourceUrl);
 
     // Cache error and location info for creating AnalysisErrorInfos
-    // Note that error columns are 1-based
     AnalysisError error = new AnalysisError(
-        source, node.span.start.column + 1, node.span.length, lintCode);
+        source, node.span.start.offset, node.span.length, lintCode);
     LineInfo lineInfo = new LineInfo.fromContent(source.contents.data);
 
     _locationInfo.add(new AnalysisErrorInfoImpl([error], lineInfo));
diff --git a/pkg/analyzer/lib/src/lint/linter_visitor.dart b/pkg/analyzer/lib/src/lint/linter_visitor.dart
index 141d3d46..fbf259b 100644
--- a/pkg/analyzer/lib/src/lint/linter_visitor.dart
+++ b/pkg/analyzer/lib/src/lint/linter_visitor.dart
@@ -427,6 +427,12 @@
   }
 
   @override
+  void visitMixinDeclaration(MixinDeclaration node) {
+    _runSubscriptions(node, registry._forMixinDeclaration);
+    super.visitMixinDeclaration(node);
+  }
+
+  @override
   void visitNamedExpression(NamedExpression node) {
     _runSubscriptions(node, registry._forNamedExpression);
     super.visitNamedExpression(node);
@@ -439,6 +445,12 @@
   }
 
   @override
+  void visitOnClause(OnClause node) {
+    _runSubscriptions(node, registry._forOnClause);
+    super.visitOnClause(node);
+  }
+
+  @override
   void visitParenthesizedExpression(ParenthesizedExpression node) {
     _runSubscriptions(node, registry._forParenthesizedExpression);
     super.visitParenthesizedExpression(node);
@@ -747,8 +759,10 @@
   final List<_Subscription<MapLiteralEntry>> _forMapLiteralEntry = [];
   final List<_Subscription<MethodDeclaration>> _forMethodDeclaration = [];
   final List<_Subscription<MethodInvocation>> _forMethodInvocation = [];
+  final List<_Subscription<MixinDeclaration>> _forMixinDeclaration = [];
   final List<_Subscription<NamedExpression>> _forNamedExpression = [];
   final List<_Subscription<NullLiteral>> _forNullLiteral = [];
+  final List<_Subscription<OnClause>> _forOnClause = [];
   final List<_Subscription<ParenthesizedExpression>>
       _forParenthesizedExpression = [];
   final List<_Subscription<PartDirective>> _forPartDirective = [];
@@ -1122,6 +1136,11 @@
         .add(new _Subscription(linter, visitor, _getTimer(linter)));
   }
 
+  void addMixinDeclaration(LintRule linter, AstVisitor visitor) {
+    _forMixinDeclaration
+        .add(new _Subscription(linter, visitor, _getTimer(linter)));
+  }
+
   void addNamedExpression(LintRule linter, AstVisitor visitor) {
     _forNamedExpression
         .add(new _Subscription(linter, visitor, _getTimer(linter)));
@@ -1131,6 +1150,10 @@
     _forNullLiteral.add(new _Subscription(linter, visitor, _getTimer(linter)));
   }
 
+  void addOnClause(LintRule linter, AstVisitor visitor) {
+    _forOnClause.add(new _Subscription(linter, visitor, _getTimer(linter)));
+  }
+
   void addParenthesizedExpression(LintRule linter, AstVisitor visitor) {
     _forParenthesizedExpression
         .add(new _Subscription(linter, visitor, _getTimer(linter)));
diff --git a/pkg/analyzer/lib/src/lint/pub.dart b/pkg/analyzer/lib/src/lint/pub.dart
index 8d12e13..1db39bf 100644
--- a/pkg/analyzer/lib/src/lint/pub.dart
+++ b/pkg/analyzer/lib/src/lint/pub.dart
@@ -122,6 +122,7 @@
   PSEntry get author;
   PSNodeList get authors;
   PSDependencyList get dependencies;
+  PSDependencyList get dependencyOverrides;
   PSEntry get description;
   PSDependencyList get devDependencies;
   PSEntry get documentation;
@@ -136,6 +137,8 @@
   T visitPackageAuthors(PSNodeList authors) => null;
   T visitPackageDependencies(PSDependencyList dependencies) => null;
   T visitPackageDependency(PSDependency dependency) => null;
+  T visitPackageDependencyOverrides(PSDependencyList dependencies) => null;
+  T visitPackageDependencyOverride(PSDependency dependency) => null;
   T visitPackageDescription(PSEntry description) => null;
   T visitPackageDevDependencies(PSDependencyList dependencies) => null;
   T visitPackageDevDependency(PSDependency dependency) => null;
@@ -318,6 +321,8 @@
   PSDependencyList dependencies;
   @override
   PSDependencyList devDependencies;
+  @override
+  PSDependencyList dependencyOverrides;
 
   _Pubspec(String src, {Uri sourceUrl}) {
     try {
@@ -352,11 +357,15 @@
     }
     if (dependencies != null) {
       visitor.visitPackageDependencies(dependencies);
-      dependencies.forEach((d) => visitor.visitPackageDependency(d));
+      dependencies.forEach(visitor.visitPackageDependency);
     }
     if (devDependencies != null) {
       visitor.visitPackageDevDependencies(devDependencies);
-      devDependencies.forEach((d) => visitor.visitPackageDevDependency(d));
+      devDependencies.forEach(visitor.visitPackageDevDependency);
+    }
+    if (dependencyOverrides != null) {
+      visitor.visitPackageDependencyOverrides(dependencyOverrides);
+      dependencyOverrides.forEach(visitor.visitPackageDependencyOverride);
     }
   }
 
@@ -371,6 +380,7 @@
     sb.writelin(homepage);
     sb.writelin(dependencies);
     sb.writelin(devDependencies);
+    sb.writelin(dependencyOverrides);
     return sb.toString();
   }
 
@@ -410,6 +420,9 @@
         case 'dev_dependencies':
           devDependencies = _processDependencies(key, v);
           break;
+        case 'dependency_overrides':
+          dependencyOverrides = _processDependencies(key, v);
+          break;
         case 'version':
           version = _processScalar(key, v);
           break;
diff --git a/pkg/analyzer/lib/src/summary/format.dart b/pkg/analyzer/lib/src/summary/format.dart
index 599f424..610ae0d 100644
--- a/pkg/analyzer/lib/src/summary/format.dart
+++ b/pkg/analyzer/lib/src/summary/format.dart
@@ -5446,6 +5446,7 @@
   String _name;
   int _nameOffset;
   List<EntityRefBuilder> _superclassConstraints;
+  List<String> _superInvokedNames;
   EntityRefBuilder _supertype;
   List<UnlinkedTypeParamBuilder> _typeParameters;
 
@@ -5590,6 +5591,18 @@
   }
 
   @override
+  List<String> get superInvokedNames => _superInvokedNames ??= <String>[];
+
+  /**
+   * Names of methods, getters, setters, and operators that this mixin
+   * declaration super-invokes.  For setters this includes the trailing "=".
+   * The list will be empty if this class is not a mixin declaration.
+   */
+  void set superInvokedNames(List<String> value) {
+    this._superInvokedNames = value;
+  }
+
+  @override
   EntityRefBuilder get supertype => _supertype;
 
   /**
@@ -5626,6 +5639,7 @@
       String name,
       int nameOffset,
       List<EntityRefBuilder> superclassConstraints,
+      List<String> superInvokedNames,
       EntityRefBuilder supertype,
       List<UnlinkedTypeParamBuilder> typeParameters})
       : _annotations = annotations,
@@ -5641,6 +5655,7 @@
         _name = name,
         _nameOffset = nameOffset,
         _superclassConstraints = superclassConstraints,
+        _superInvokedNames = superInvokedNames,
         _supertype = supertype,
         _typeParameters = typeParameters;
 
@@ -5727,6 +5742,14 @@
         x?.collectApiSignature(signature);
       }
     }
+    if (this._superInvokedNames == null) {
+      signature.addInt(0);
+    } else {
+      signature.addInt(this._superInvokedNames.length);
+      for (var x in this._superInvokedNames) {
+        signature.addString(x);
+      }
+    }
   }
 
   fb.Offset finish(fb.Builder fbBuilder) {
@@ -5739,6 +5762,7 @@
     fb.Offset offset_mixins;
     fb.Offset offset_name;
     fb.Offset offset_superclassConstraints;
+    fb.Offset offset_superInvokedNames;
     fb.Offset offset_supertype;
     fb.Offset offset_typeParameters;
     if (!(_annotations == null || _annotations.isEmpty)) {
@@ -5774,6 +5798,10 @@
       offset_superclassConstraints = fbBuilder.writeList(
           _superclassConstraints.map((b) => b.finish(fbBuilder)).toList());
     }
+    if (!(_superInvokedNames == null || _superInvokedNames.isEmpty)) {
+      offset_superInvokedNames = fbBuilder.writeList(
+          _superInvokedNames.map((b) => fbBuilder.writeString(b)).toList());
+    }
     if (_supertype != null) {
       offset_supertype = _supertype.finish(fbBuilder);
     }
@@ -5821,6 +5849,9 @@
     if (offset_superclassConstraints != null) {
       fbBuilder.addOffset(14, offset_superclassConstraints);
     }
+    if (offset_superInvokedNames != null) {
+      fbBuilder.addOffset(15, offset_superInvokedNames);
+    }
     if (offset_supertype != null) {
       fbBuilder.addOffset(3, offset_supertype);
     }
@@ -5860,6 +5891,7 @@
   String _name;
   int _nameOffset;
   List<idl.EntityRef> _superclassConstraints;
+  List<String> _superInvokedNames;
   idl.EntityRef _supertype;
   List<idl.UnlinkedTypeParam> _typeParameters;
 
@@ -5955,6 +5987,13 @@
   }
 
   @override
+  List<String> get superInvokedNames {
+    _superInvokedNames ??= const fb.ListReader<String>(const fb.StringReader())
+        .vTableGet(_bc, _bcOffset, 15, const <String>[]);
+    return _superInvokedNames;
+  }
+
+  @override
   idl.EntityRef get supertype {
     _supertype ??= const _EntityRefReader().vTableGet(_bc, _bcOffset, 3, null);
     return _supertype;
@@ -5998,6 +6037,8 @@
     if (superclassConstraints.isNotEmpty)
       _result["superclassConstraints"] =
           superclassConstraints.map((_value) => _value.toJson()).toList();
+    if (superInvokedNames.isNotEmpty)
+      _result["superInvokedNames"] = superInvokedNames;
     if (supertype != null) _result["supertype"] = supertype.toJson();
     if (typeParameters.isNotEmpty)
       _result["typeParameters"] =
@@ -6020,6 +6061,7 @@
         "name": name,
         "nameOffset": nameOffset,
         "superclassConstraints": superclassConstraints,
+        "superInvokedNames": superInvokedNames,
         "supertype": supertype,
         "typeParameters": typeParameters,
       };
diff --git a/pkg/analyzer/lib/src/summary/format.fbs b/pkg/analyzer/lib/src/summary/format.fbs
index 542ec79..a37da95 100644
--- a/pkg/analyzer/lib/src/summary/format.fbs
+++ b/pkg/analyzer/lib/src/summary/format.fbs
@@ -1884,6 +1884,13 @@
   superclassConstraints:[EntityRef] (id: 14);
 
   /**
+   * Names of methods, getters, setters, and operators that this mixin
+   * declaration super-invokes.  For setters this includes the trailing "=".
+   * The list will be empty if this class is not a mixin declaration.
+   */
+  superInvokedNames:[string] (id: 15);
+
+  /**
    * Supertype of the class, or `null` if either (a) the class doesn't
    * explicitly declare a supertype (and hence has supertype `Object`), or (b)
    * the class *is* `Object` (and hence has no supertype).
diff --git a/pkg/analyzer/lib/src/summary/idl.dart b/pkg/analyzer/lib/src/summary/idl.dart
index ee9df47..c9ca5fd 100644
--- a/pkg/analyzer/lib/src/summary/idl.dart
+++ b/pkg/analyzer/lib/src/summary/idl.dart
@@ -1452,6 +1452,14 @@
   List<EntityRef> get superclassConstraints;
 
   /**
+   * Names of methods, getters, setters, and operators that this mixin
+   * declaration super-invokes.  For setters this includes the trailing "=".
+   * The list will be empty if this class is not a mixin declaration.
+   */
+  @Id(15)
+  List<String> get superInvokedNames;
+
+  /**
    * Supertype of the class, or `null` if either (a) the class doesn't
    * explicitly declare a supertype (and hence has supertype `Object`), or (b)
    * the class *is* `Object` (and hence has no supertype).
diff --git a/pkg/analyzer/lib/src/summary/link.dart b/pkg/analyzer/lib/src/summary/link.dart
index 8bce0e0..2095404 100644
--- a/pkg/analyzer/lib/src/summary/link.dart
+++ b/pkg/analyzer/lib/src/summary/link.dart
@@ -2,71 +2,72 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-/**
- * This library is capable of producing linked summaries from unlinked
- * ones (or prelinked ones).  It functions by building a miniature
- * element model to represent the contents of the summaries, and then
- * scanning the element model to gather linked information and adding
- * it to the summary data structures.
- *
- * The reason we use a miniature element model to do the linking
- * (rather than resynthesizing the full element model from the
- * summaries) is that it is expected that we will only need to
- * traverse a small subset of the element properties in order to link.
- * Resynthesizing only those properties that we need should save
- * substantial CPU time.
- *
- * The element model implements the same interfaces as the full
- * element model, so we can re-use code elsewhere in the analysis
- * engine to do the linking.  However, only a small subset of the
- * methods and getters defined in the full element model are
- * implemented here.  To avoid static warnings, each element model
- * class contains an implementation of `noSuchMethod`.
- *
- * The miniature element model follows the following design
- * principles:
- *
- * - With few exceptions, resynthesis is done incrementally on demand,
- *   so that we don't pay the cost of resynthesizing elements (or
- *   properties of elements) that aren't referenced from a part of the
- *   element model that is relevant to linking.
- *
- * - Computation of values in the miniature element model is similar
- *   to the task model, but much lighter weight.  Instead of declaring
- *   tasks and their relationships using classes, each task is simply
- *   a method (frequently a getter) that computes a value.  Instead of
- *   using a general purpose cache, values are cached by the methods
- *   themselves in private fields (with `null` typically representing
- *   "not yet cached").
- *
- * - No attempt is made to detect cyclic dependencies due to bugs in
- *   the analyzer.  This saves time because dependency evaluation
- *   doesn't have to be a separate step from evaluating a value; we
- *   can simply call the getter.
- *
- * - However, for cases where cyclic dependencies may occur in the
- *   absence of analyzer bugs (e.g. because of errors in the code
- *   being analyzed, or cycles between top level and static variables
- *   undergoing type inference), we do precompute dependencies, and we
- *   use Tarjan's strongly connected components algorithm to detect
- *   cycles.
- *
- * - As much as possible, bookkeeping data is pointed to directly by
- *   the element objects, rather than being stored in maps.
- *
- * - Where possible, we favor method dispatch instead of "is" and "as"
- *   checks.  E.g. see [ReferenceableElementForLink.asConstructor].
- */
+/// This library is capable of producing linked summaries from unlinked
+/// ones (or prelinked ones).  It functions by building a miniature
+/// element model to represent the contents of the summaries, and then
+/// scanning the element model to gather linked information and adding
+/// it to the summary data structures.
+///
+/// The reason we use a miniature element model to do the linking
+/// (rather than resynthesizing the full element model from the
+/// summaries) is that it is expected that we will only need to
+/// traverse a small subset of the element properties in order to link.
+/// Resynthesizing only those properties that we need should save
+/// substantial CPU time.
+///
+/// The element model implements the same interfaces as the full
+/// element model, so we can re-use code elsewhere in the analysis
+/// engine to do the linking.  However, only a small subset of the
+/// methods and getters defined in the full element model are
+/// implemented here.  To avoid static warnings, each element model
+/// class contains an implementation of `noSuchMethod`.
+///
+/// The miniature element model follows the following design
+/// principles:
+///
+/// - With few exceptions, resynthesis is done incrementally on demand,
+///   so that we don't pay the cost of resynthesizing elements (or
+///   properties of elements) that aren't referenced from a part of the
+///   element model that is relevant to linking.
+///
+/// - Computation of values in the miniature element model is similar
+///   to the task model, but much lighter weight.  Instead of declaring
+///   tasks and their relationships using classes, each task is simply
+///   a method (frequently a getter) that computes a value.  Instead of
+///   using a general purpose cache, values are cached by the methods
+///   themselves in private fields (with `null` typically representing
+///   "not yet cached").
+///
+/// - No attempt is made to detect cyclic dependencies due to bugs in
+///   the analyzer.  This saves time because dependency evaluation
+///   doesn't have to be a separate step from evaluating a value; we
+///   can simply call the getter.
+///
+/// - However, for cases where cyclic dependencies may occur in the
+///   absence of analyzer bugs (e.g. because of errors in the code
+///   being analyzed, or cycles between top level and static variables
+///   undergoing type inference), we do precompute dependencies, and we
+///   use Tarjan's strongly connected components algorithm to detect
+///   cycles.
+///
+/// - As much as possible, bookkeeping data is pointed to directly by
+///   the element objects, rather than being stored in maps.
+///
+/// - Where possible, we favor method dispatch instead of "is" and "as"
+///   checks.  E.g. see [ReferenceableElementForLink.asConstructor].
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/ast/standard_ast_factory.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/error/listener.dart';
+import 'package:analyzer/src/dart/ast/utilities.dart';
 import 'package:analyzer/src/dart/constant/value.dart';
+import 'package:analyzer/src/dart/element/builder.dart';
 import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/dart/element/type.dart';
 import 'package:analyzer/src/dart/resolver/inheritance_manager.dart';
 import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/generated/java_engine.dart';
 import 'package:analyzer/src/generated/resolver.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/generated/utilities_dart.dart';
@@ -93,41 +94,41 @@
   }
 }
 
-/**
- * Link together the build unit consisting of [libraryUris], using
- * [getDependency] to fetch the [LinkedLibrary] objects from other
- * build units, and [getUnit] to fetch the [UnlinkedUnit] objects from
- * both this build unit and other build units.
- *
- * The [strong] flag controls whether type inference is performed in strong
- * mode or spec mode.  Note that in spec mode, the only types that are inferred
- * are the types of initializing formals, which are inferred from the types of
- * the corresponding fields.
- *
- * A map is returned whose keys are the URIs of the libraries in this
- * build unit, and whose values are the corresponding
- * [LinkedLibraryBuilder]s.
- */
+/// Link together the build unit consisting of [libraryUris], using
+/// [getDependency] to fetch the [LinkedLibrary] objects from other
+/// build units, and [getUnit] to fetch the [UnlinkedUnit] objects from
+/// both this build unit and other build units.
+///
+/// The [strong] flag controls whether type inference is performed in strong
+/// mode or spec mode.  Note that in spec mode, the only types that are inferred
+/// are the types of initializing formals, which are inferred from the types of
+/// the corresponding fields.
+///
+/// If [getAst] is provided, it is used to obtain ASTs of source files in this
+/// build unit, and these ASTs are used for type inference.
+///
+/// A map is returned whose keys are the URIs of the libraries in this
+/// build unit, and whose values are the corresponding
+/// [LinkedLibraryBuilder]s.
 Map<String, LinkedLibraryBuilder> link(
     Set<String> libraryUris,
     GetDependencyCallback getDependency,
     GetUnitCallback getUnit,
-    GetDeclaredVariable getDeclaredVariable) {
+    GetDeclaredVariable getDeclaredVariable,
+    [GetAstCallback getAst]) {
   Map<String, LinkedLibraryBuilder> linkedLibraries =
       setupForLink(libraryUris, getUnit, getDeclaredVariable);
-  _relink(linkedLibraries, getDependency, getUnit);
+  _relink(linkedLibraries, getDependency, getUnit, getAst);
   return linkedLibraries;
 }
 
-/**
- * Prepare to link together the build unit consisting of [libraryUris], using
- * [getUnit] to fetch the [UnlinkedUnit] objects from both this build unit and
- * other build units.
- *
- * The libraries are prelinked, and a map is returned whose keys are the URIs of
- * the libraries in this build unit, and whose values are the corresponding
- * [LinkedLibraryBuilder]s.
- */
+/// Prepare to link together the build unit consisting of [libraryUris], using
+/// [getUnit] to fetch the [UnlinkedUnit] objects from both this build unit and
+/// other build units.
+///
+/// The libraries are prelinked, and a map is returned whose keys are the URIs
+/// of the libraries in this build unit, and whose values are the corresponding
+/// [LinkedLibraryBuilder]s.
 Map<String, LinkedLibraryBuilder> setupForLink(Set<String> libraryUris,
     GetUnitCallback getUnit, GetDeclaredVariable getDeclaredVariable) {
   Map<String, LinkedLibraryBuilder> linkedLibraries =
@@ -143,12 +144,10 @@
   return linkedLibraries;
 }
 
-/**
- * Create an [EntityRefBuilder] representing the given [type], in a form
- * suitable for inclusion in [LinkedUnit.types].  [compilationUnit] is the
- * compilation unit in which the type will be used.  If [slot] is provided, it
- * is stored in [EntityRefBuilder.slot].
- */
+/// Create an [EntityRefBuilder] representing the given [type], in a form
+/// suitable for inclusion in [LinkedUnit.types].  [compilationUnit] is the
+/// compilation unit in which the type will be used.  If [slot] is provided, it
+/// is stored in [EntityRefBuilder.slot].
 EntityRefBuilder _createLinkedType(
     DartType type,
     CompilationUnitElementInBuildUnit compilationUnit,
@@ -161,7 +160,7 @@
     _storeTypeArguments(
         type.typeArguments, result, compilationUnit, typeParameterContext);
     return result;
-  } else if (type is DynamicTypeImpl) {
+  } else if (type.isDynamic) {
     result.reference = compilationUnit.addRawReference('dynamic');
     return result;
   } else if (type is VoidTypeImpl) {
@@ -172,15 +171,9 @@
     return result;
   } else if (type is TypeParameterType) {
     TypeParameterElementImpl element = type.element;
-    if (typeParameterContext != null &&
-        typeParameterContext.isTypeParameterInScope(element)) {
-      var nestingLevel = element.nestingLevel;
-      if (nestingLevel < 0) {
-        result.paramReference = -nestingLevel;
-      } else {
-        result.paramReference =
-            typeParameterContext.typeParameterNestingLevel - nestingLevel;
-      }
+    var deBruijnIndex = typeParameterContext?.computeDeBruijnIndex(element);
+    if (deBruijnIndex != null) {
+      result.paramReference = deBruijnIndex;
     } else {
       throw new StateError('The type parameter $type (in ${element?.location}) '
           'is out of scope on ${typeParameterContext?.location}.');
@@ -257,30 +250,32 @@
   return type;
 }
 
-/**
- * Given [libraries] (a map from URI to [LinkedLibraryBuilder]
- * containing correct prelinked information), rebuild linked
- * information, using [getDependency] to fetch the [LinkedLibrary]
- * objects from other build units, and [getUnit] to fetch the
- * [UnlinkedUnit] objects from both this build unit and other build
- * units.
- *
- * The [strong] flag controls whether type inference is performed in strong
- * mode or spec mode.  Note that in spec mode, the only types that are inferred
- * are the types of initializing formals, which are inferred from the types of
- * the corresponding fields.
- */
-void _relink(Map<String, LinkedLibraryBuilder> libraries,
-    GetDependencyCallback getDependency, GetUnitCallback getUnit) {
-  new Linker(libraries, getDependency, getUnit).link();
+/// Given [libraries] (a map from URI to [LinkedLibraryBuilder]
+/// containing correct prelinked information), rebuild linked
+/// information, using [getDependency] to fetch the [LinkedLibrary]
+/// objects from other build units, and [getUnit] to fetch the
+/// [UnlinkedUnit] objects from both this build unit and other build
+/// units.
+///
+/// If a non-null [getAst] is provided, it is used to obtain ASTs of source
+/// files in this build unit, and these ASTs are used for type inference.
+///
+/// The [strong] flag controls whether type inference is performed in strong
+/// mode or spec mode.  Note that in spec mode, the only types that are inferred
+/// are the types of initializing formals, which are inferred from the types of
+/// the corresponding fields.
+void _relink(
+    Map<String, LinkedLibraryBuilder> libraries,
+    GetDependencyCallback getDependency,
+    GetUnitCallback getUnit,
+    GetAstCallback getAst) {
+  new Linker(libraries, getDependency, getUnit, getAst).link();
 }
 
-/**
- * Create an [UnlinkedParam] representing the given [parameter], which should be
- * a parameter of a synthetic function type (e.g. one produced during type
- * inference as a result of computing the least upper bound of two function
- * types).
- */
+/// Create an [UnlinkedParam] representing the given [parameter], which should
+/// be a parameter of a synthetic function type (e.g. one produced during type
+/// inference as a result of computing the least upper bound of two function
+/// types).
 UnlinkedParamBuilder _serializeSyntheticParam(
     ParameterElement parameter,
     CompilationUnitElementInBuildUnit compilationUnit,
@@ -311,12 +306,10 @@
   return b;
 }
 
-/**
- * Create an [UnlinkedTypeParamBuilder] representing the given [typeParameter],
- * which should be a type parameter of a synthetic function type (e.g. one
- * produced during type inference as a result of computing the least upper
- * bound of two function types).
- */
+/// Create an [UnlinkedTypeParamBuilder] representing the given [typeParameter],
+/// which should be a type parameter of a synthetic function type (e.g. one
+/// produced during type inference as a result of computing the least upper
+/// bound of two function types).
 UnlinkedTypeParamBuilder _serializeSyntheticTypeParameter(
     TypeParameterElement typeParameter,
     CompilationUnitElementInBuildUnit compilationUnit,
@@ -335,9 +328,7 @@
       codeRange: codeRangeBuilder);
 }
 
-/**
- * Store the given function [element] into the [entity] by value.
- */
+/// Store the given function [element] into the [entity] by value.
 void _storeFunctionElementByValue(
     EntityRefBuilder entity,
     FunctionElement element,
@@ -360,10 +351,8 @@
   }
 }
 
-/**
- * Store the given [typeArguments] in [encodedType], using [compilationUnit] and
- * [typeParameterContext] to serialize them.
- */
+/// Store the given [typeArguments] in [encodedType], using [compilationUnit]
+/// and [typeParameterContext] to serialize them.
 void _storeTypeArguments(
     List<DartType> typeArguments,
     EntityRefBuilder encodedType,
@@ -379,43 +368,50 @@
   encodedType.typeArguments = encodedTypeArguments;
 }
 
-/**
- * Type of the callback used by [link] and [relink] to request
- * [LinkedLibrary] objects from other build units.
- */
+/// Type of the callback used by [link] to request [CompilationUnit] objects.
+typedef CompilationUnit GetAstCallback(String absoluteUri);
+
+/// Type of the callback used by [link] and [relink] to request
+/// [LinkedLibrary] objects from other build units.
 typedef LinkedLibrary GetDependencyCallback(String absoluteUri);
 
-/**
- * Type of the callback used by [link] and [relink] to request
- * [UnlinkedUnit] objects.
- */
+/// Type of the callback used by [link] and [relink] to request
+/// [UnlinkedUnit] objects.
 typedef UnlinkedUnit GetUnitCallback(String absoluteUri);
 
-/**
- * Stub implementation of [AnalysisOptions] used during linking.
- */
-class AnalysisOptionsForLink implements AnalysisOptions {
+/// Stub implementation of [AnalysisOptions] used during linking.
+class AnalysisOptionsForLink implements AnalysisOptionsImpl {
   final Linker _linker;
 
   AnalysisOptionsForLink(this._linker);
 
   @override
+  bool get declarationCasts => true;
+
+  @override
   bool get hint => false;
 
   @override
+  bool get implicitCasts => true;
+
+  @override
+  List<String> get nonnullableTypes => AnalysisOptionsImpl.NONNULLABLE_TYPES;
+
+  @override
   bool get previewDart2 => true;
 
   @override
   bool get strongMode => true;
 
   @override
+  bool get strongModeHints => false;
+
+  @override
   noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
 }
 
-/**
- * Element representing a class or enum resynthesized from a summary
- * during linking.
- */
+/// Element representing a class or enum resynthesized from a summary
+/// during linking.
 abstract class ClassElementForLink extends Object
     with ReferenceableElementForLink
     implements AbstractClassElementImpl {
@@ -455,9 +451,7 @@
   @override
   List<FieldElementForLink> get fields;
 
-  /**
-   * Indicates whether this is the core class `Object`.
-   */
+  /// Indicates whether this is the core class `Object`.
   bool get isObject;
 
   @override
@@ -524,10 +518,8 @@
     return null;
   }
 
-  /**
-   * Perform type inference and cycle detection on this class and
-   * store the resulting information in [compilationUnit].
-   */
+  /// Perform type inference and cycle detection on this class and
+  /// store the resulting information in [compilationUnit].
   void link(CompilationUnitElementInBuildUnit compilationUnit);
 
   @override
@@ -540,21 +532,21 @@
   noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
 }
 
-/**
- * Element representing a class resynthesized from a summary during
- * linking.
- */
+/// Element representing a class resynthesized from a summary during
+/// linking.
 class ClassElementForLink_Class extends ClassElementForLink
     with TypeParameterizedElementMixin
     implements ClassElementImpl {
-  /**
-   * The unlinked representation of the class in the summary.
-   */
+  /// The unlinked representation of the class in the summary.
   final UnlinkedClass _unlinkedClass;
 
   @override
   final bool isMixin;
 
+  /// If non-null, the AST for the class or mixin declaration; this is used to
+  /// obtain initializer expressions for type inference.
+  final ClassOrMixinDeclaration _astForInference;
+
   List<ConstructorElementForLink> _constructors;
   ConstructorElementForLink _unnamedConstructor;
   bool _unnamedConstructorComputed = false;
@@ -564,10 +556,11 @@
   List<MethodElementForLink> _methods;
   List<InterfaceType> _mixins;
   List<InterfaceType> _interfaces;
+  List<InterfaceType> _superclassConstraints;
   List<PropertyAccessorElementForLink> _accessors;
 
   ClassElementForLink_Class(CompilationUnitElementForLink enclosingElement,
-      this._unlinkedClass, this.isMixin)
+      this._unlinkedClass, this.isMixin, this._astForInference)
       : super(enclosingElement);
 
   @override
@@ -641,8 +634,27 @@
   List<FieldElementForLink_ClassField> get fields {
     if (_fields == null) {
       _fields = <FieldElementForLink_ClassField>[];
-      for (UnlinkedVariable field in _unlinkedClass.fields) {
-        _fields.add(new FieldElementForLink_ClassField(this, field));
+      List<Expression> initializerExpressionsForInference;
+      if (_astForInference != null) {
+        initializerExpressionsForInference = [];
+        for (var member in _astForInference.members) {
+          if (member is FieldDeclaration) {
+            for (var variable in member.fields.variables) {
+              initializerExpressionsForInference.add(variable.initializer);
+            }
+          }
+        }
+        assert(initializerExpressionsForInference.length ==
+            _unlinkedClass.fields.length);
+      }
+      for (int i = 0; i < _unlinkedClass.fields.length; i++) {
+        var field = _unlinkedClass.fields[i];
+        _fields.add(new FieldElementForLink_ClassField(
+            this,
+            field,
+            initializerExpressionsForInference == null
+                ? null
+                : initializerExpressionsForInference[i]));
       }
     }
     return _fields;
@@ -756,6 +768,10 @@
   String get name => _unlinkedClass.name;
 
   @override
+  List<InterfaceType> get superclassConstraints => _superclassConstraints ??=
+      _unlinkedClass.superclassConstraints.map(_computeInterfaceType).toList();
+
+  @override
   InterfaceType get supertype {
     if (isObject) {
       return null;
@@ -838,9 +854,7 @@
   @override
   String toString() => '$enclosingElement.$name';
 
-  /**
-   * Convert [typeRef] into an [InterfaceType].
-   */
+  /// Convert [typeRef] into an [InterfaceType].
   InterfaceType _computeInterfaceType(EntityRef typeRef) {
     if (typeRef != null) {
       DartType type = enclosingElement.resolveTypeRef(this, typeRef);
@@ -878,15 +892,11 @@
   }
 }
 
-/**
- * Element representing an enum resynthesized from a summary during
- * linking.
- */
+/// Element representing an enum resynthesized from a summary during
+/// linking.
 class ClassElementForLink_Enum extends ClassElementForLink
     implements EnumElementImpl {
-  /**
-   * The unlinked representation of the enum in the summary.
-   */
+  /// The unlinked representation of the enum in the summary.
   final UnlinkedEnum _unlinkedEnum;
 
   InterfaceType _type;
@@ -935,6 +945,9 @@
   bool get isEnum => true;
 
   @override
+  bool get isMixin => false;
+
+  @override
   bool get isObject => false;
 
   @override
@@ -947,6 +960,9 @@
   String get name => _unlinkedEnum.name;
 
   @override
+  List<InterfaceType> get superclassConstraints => const [];
+
+  @override
   InterfaceType get supertype => library._linker.typeProvider.objectType;
 
   @override
@@ -958,9 +974,7 @@
   @override
   ConstructorElementForLink get unnamedConstructor => null;
 
-  /**
-   * Get the type of the enum's static member `values`.
-   */
+  /// Get the type of the enum's static member `values`.
   DartType get valuesType =>
       _valuesType ??= library._linker.typeProvider.listType.instantiate([type]);
 
@@ -979,29 +993,21 @@
   String toString() => '$enclosingElement.$name';
 }
 
-/**
- * Element representing a compilation unit resynthesized from a
- * summary during linking.
- */
+/// Element representing a compilation unit resynthesized from a
+/// summary during linking.
 abstract class CompilationUnitElementForLink
     implements CompilationUnitElementImpl, ResynthesizerContext {
   final _UnitResynthesizer _unitResynthesizer;
 
-  /**
-   * The unlinked representation of the compilation unit in the
-   * summary.
-   */
+  /// The unlinked representation of the compilation unit in the
+  /// summary.
   final UnlinkedUnit _unlinkedUnit;
 
-  /**
-   * For each entry in [UnlinkedUnit.references], the element referred
-   * to by the reference, or `null` if it hasn't been located yet.
-   */
+  /// For each entry in [UnlinkedUnit.references], the element referred
+  /// to by the reference, or `null` if it hasn't been located yet.
   final List<_ReferenceInfo> _references;
 
-  /**
-   * The absolute URI of this compilation unit.
-   */
+  /// The absolute URI of this compilation unit.
   final String _absoluteUri;
 
   List<ClassElementForLink_Class> _mixins;
@@ -1013,16 +1019,18 @@
   List<PropertyAccessorElementForLink> _accessors;
   List<FunctionTypeAliasElementForLink> _functionTypeAliases;
 
-  /**
-   * Index of this unit in the list of units in the enclosing library.
-   */
+  /// Index of this unit in the list of units in the enclosing library.
   final int unitNum;
 
   @override
   final Source source;
 
+  /// If non-null, the AST for the compilation unit; this is used to obtain
+  /// initializer expressions for type inference.
+  final CompilationUnit _astForInference;
+
   CompilationUnitElementForLink(UnlinkedUnit unlinkedUnit, this.unitNum,
-      int numReferences, this._absoluteUri)
+      int numReferences, this._absoluteUri, this._astForInference)
       : _references = new List<_ReferenceInfo>(numReferences),
         _unlinkedUnit = unlinkedUnit,
         source = new InSummarySource(Uri.parse(_absoluteUri), null),
@@ -1112,15 +1120,11 @@
   @override
   String get identifier => _absoluteUri;
 
-  /**
-   * Indicates whether this compilation element is part of the build unit
-   * currently being linked.
-   */
+  /// Indicates whether this compilation element is part of the build unit
+  /// currently being linked.
   bool get isInBuildUnit;
 
-  /**
-   * Determine whether type inference is complete in this compilation unit.
-   */
+  /// Determine whether type inference is complete in this compilation unit.
   bool get isTypeInferenceComplete {
     LibraryCycleForLink libraryCycleForLink = library.libraryCycleForLink;
     if (libraryCycleForLink == null) {
@@ -1136,9 +1140,26 @@
   @override
   List<ClassElementForLink_Class> get mixins {
     if (_mixins == null) {
+      List<MixinDeclaration> declarationsForInference;
+      if (_astForInference != null) {
+        declarationsForInference = [];
+        for (var declaration in _astForInference.declarations) {
+          if (declaration is MixinDeclaration) {
+            declarationsForInference.add(declaration);
+          }
+        }
+        assert(declarationsForInference.length == _unlinkedUnit.mixins.length);
+      }
       _mixins = <ClassElementForLink_Class>[];
-      for (UnlinkedClass unlinkedClass in _unlinkedUnit.mixins) {
-        _mixins.add(new ClassElementForLink_Class(this, unlinkedClass, true));
+      for (int i = 0; i < _unlinkedUnit.mixins.length; i++) {
+        var unlinkedClass = _unlinkedUnit.mixins[i];
+        _mixins.add(new ClassElementForLink_Class(
+            this,
+            unlinkedClass,
+            true,
+            declarationsForInference == null
+                ? null
+                : declarationsForInference[i]));
       }
     }
     return _mixins;
@@ -1150,10 +1171,28 @@
   @override
   List<TopLevelVariableElementForLink> get topLevelVariables {
     if (_topLevelVariables == null) {
+      List<Expression> initializerExpressionsForInference;
+      if (_astForInference != null) {
+        initializerExpressionsForInference = [];
+        for (var declaration in _astForInference.declarations) {
+          if (declaration is TopLevelVariableDeclaration) {
+            for (var variable in declaration.variables.variables) {
+              initializerExpressionsForInference.add(variable.initializer);
+            }
+          }
+        }
+        assert(initializerExpressionsForInference.length ==
+            _unlinkedUnit.variables.length);
+      }
       _topLevelVariables = <TopLevelVariableElementForLink>[];
-      for (UnlinkedVariable unlinkedVariable in _unlinkedUnit.variables) {
-        _topLevelVariables
-            .add(new TopLevelVariableElementForLink(this, unlinkedVariable));
+      for (int i = 0; i < _unlinkedUnit.variables.length; i++) {
+        var unlinkedVariable = _unlinkedUnit.variables[i];
+        _topLevelVariables.add(new TopLevelVariableElementForLink(
+            this,
+            unlinkedVariable,
+            initializerExpressionsForInference == null
+                ? null
+                : initializerExpressionsForInference[i]));
       }
     }
     return _topLevelVariables;
@@ -1162,24 +1201,39 @@
   @override
   List<ClassElementForLink_Class> get types {
     if (_types == null) {
+      List<ClassDeclaration> declarationsForInference;
+      if (_astForInference != null) {
+        declarationsForInference = [];
+        for (var declaration in _astForInference.declarations) {
+          if (declaration is ClassDeclaration) {
+            declarationsForInference.add(declaration);
+          } else if (declaration is ClassTypeAlias) {
+            declarationsForInference.add(null);
+          }
+        }
+        assert(declarationsForInference.length == _unlinkedUnit.classes.length);
+      }
       _types = <ClassElementForLink_Class>[];
-      for (UnlinkedClass unlinkedClass in _unlinkedUnit.classes) {
-        _types.add(new ClassElementForLink_Class(this, unlinkedClass, false));
+      for (int i = 0; i < _unlinkedUnit.classes.length; i++) {
+        var unlinkedClass = _unlinkedUnit.classes[i];
+        _types.add(new ClassElementForLink_Class(
+            this,
+            unlinkedClass,
+            false,
+            declarationsForInference == null
+                ? null
+                : declarationsForInference[i]));
       }
     }
     return _types;
   }
 
-  /**
-   * The linked representation of the compilation unit in the summary.
-   */
+  /// The linked representation of the compilation unit in the summary.
   LinkedUnit get _linkedUnit;
 
-  /**
-   * Search the unit for a top level element with the given [name].
-   * If no name is found, return the singleton instance of
-   * [UndefinedElementForLink].
-   */
+  /// Search the unit for a top level element with the given [name].
+  /// If no name is found, return the singleton instance of
+  /// [UndefinedElementForLink].
   ReferenceableElementForLink getContainedName(name) {
     if (_containedNames == null) {
       _containedNames = <String, ReferenceableElementForLink>{};
@@ -1207,11 +1261,9 @@
         name, () => UndefinedElementForLink.instance);
   }
 
-  /**
-   * Compute the type referred to by the given linked type [slot] (interpreted
-   * in [context]).  If there is no inferred type in the
-   * given slot, `dynamic` is returned.
-   */
+  /// Compute the type referred to by the given linked type [slot] (interpreted
+  /// in [context]).  If there is no inferred type in the
+  /// given slot, `dynamic` is returned.
   DartType getLinkedType(ElementImpl context, int slot);
 
   @override
@@ -1221,11 +1273,9 @@
   @override
   noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
 
-  /**
-   * Return the class element for the constructor referred to by the given
-   * [index] in [UnlinkedUnit.references].  If the reference is unresolved,
-   * return [UndefinedElementForLink.instance].
-   */
+  /// Return the class element for the constructor referred to by the given
+  /// [index] in [UnlinkedUnit.references].  If the reference is unresolved,
+  /// return [UndefinedElementForLink.instance].
   ReferenceableElementForLink resolveConstructorClassRef(int index) {
     LinkedReference linkedReference = _linkedUnit.references[index];
     if (linkedReference.kind == ReferenceKind.classOrEnum) {
@@ -1238,11 +1288,9 @@
     return UndefinedElementForLink.instance;
   }
 
-  /**
-   * Return the element referred to by the given [index] in
-   * [UnlinkedUnit.references].  If the reference is unresolved,
-   * return [UndefinedElementForLink.instance].
-   */
+  /// Return the element referred to by the given [index] in
+  /// [UnlinkedUnit.references].  If the reference is unresolved,
+  /// return [UndefinedElementForLink.instance].
   ReferenceableElementForLink resolveRef(int index) =>
       resolveRefToInfo(index).element;
 
@@ -1348,10 +1396,8 @@
   String toString() => enclosingElement.toString();
 }
 
-/**
- * Element representing a compilation unit which is part of the build
- * unit being linked.
- */
+/// Element representing a compilation unit which is part of the build
+/// unit being linked.
 class CompilationUnitElementInBuildUnit extends CompilationUnitElementForLink {
   @override
   final LinkedUnitBuilder _linkedUnit;
@@ -1364,9 +1410,10 @@
       UnlinkedUnit unlinkedUnit,
       this._linkedUnit,
       int unitNum,
-      String absoluteUri)
-      : super(
-            unlinkedUnit, unitNum, unlinkedUnit.references.length, absoluteUri);
+      String absoluteUri,
+      CompilationUnit astForInference)
+      : super(unlinkedUnit, unitNum, unlinkedUnit.references.length,
+            absoluteUri, astForInference);
 
   @override
   bool get isInBuildUnit => true;
@@ -1374,12 +1421,10 @@
   @override
   LibraryElementInBuildUnit get library => enclosingElement;
 
-  /**
-   * If this compilation unit already has a reference in its references table
-   * matching [dependency], [name], [numTypeParameters], [unitNum],
-   * [containingReference], and [kind], return its index.  Otherwise add a new reference to
-   * the table and return its index.
-   */
+  /// If this compilation unit already has a reference in its references table
+  /// matching [dependency], [name], [numTypeParameters], [unitNum],
+  /// [containingReference], and [kind], return its index.  Otherwise add a new
+  /// reference to the table and return its index.
   int addRawReference(String name,
       {int dependency: 0,
       int numTypeParameters: 0,
@@ -1423,11 +1468,9 @@
     return result;
   }
 
-  /**
-   * If this compilation unit already has a reference in its references table
-   * to [element], return its index.  Otherwise add a new reference to the table
-   * and return its index.
-   */
+  /// If this compilation unit already has a reference in its references table
+  /// to [element], return its index.  Otherwise add a new reference to the
+  /// table and return its index.
   int addReference(Element element) {
     if (element is ClassElementForLink) {
       return addRawReference(element.name,
@@ -1501,10 +1544,8 @@
         'Linker tried to access linked type from current build unit');
   }
 
-  /**
-   * Perform type inference and const cycle detection on this
-   * compilation unit.
-   */
+  /// Perform type inference and const cycle detection on this
+  /// compilation unit.
   void link() {
     new InstanceMemberInferrer(
             enclosingElement._linker.typeProvider,
@@ -1517,12 +1558,13 @@
     for (ClassElementForLink classElement in types) {
       classElement.link(this);
     }
+    for (ClassElementForLink classElement in mixins) {
+      classElement.link(this);
+    }
   }
 
-  /**
-   * Throw away any information stored in the summary by a previous call to
-   * [link].
-   */
+  /// Throw away any information stored in the summary by a previous call to
+  /// [link].
   void unlink() {
     _linkedUnit.constCycles.clear();
     _linkedUnit.parametersInheritingCovariant.clear();
@@ -1530,26 +1572,20 @@
     _linkedUnit.types.clear();
   }
 
-  /**
-   * Store the fact that the given [slot] represents a constant constructor
-   * that is part of a cycle.
-   */
+  /// Store the fact that the given [slot] represents a constant constructor
+  /// that is part of a cycle.
   void _storeConstCycle(int slot) {
     _linkedUnit.constCycles.add(slot);
   }
 
-  /**
-   * Store the fact that the given [slot] represents a parameter that inherits
-   * `@covariant` behavior.
-   */
+  /// Store the fact that the given [slot] represents a parameter that inherits
+  /// `@covariant` behavior.
   void _storeInheritsCovariant(int slot) {
     _linkedUnit.parametersInheritingCovariant.add(slot);
   }
 
-  /**
-   * Store the given [linkedType] in the given [slot] of the this compilation
-   * unit's linked type list.
-   */
+  /// Store the given [linkedType] in the given [slot] of the this compilation
+  /// unit's linked type list.
   void _storeLinkedType(int slot, DartType linkedType,
       TypeParameterizedElementMixin typeParameterContext) {
     if (slot != 0) {
@@ -1561,9 +1597,7 @@
     }
   }
 
-  /**
-   * Store the given error [error] in the given [slot].
-   */
+  /// Store the given error [error] in the given [slot].
   void _storeLinkedTypeError(int slot, TopLevelInferenceErrorBuilder error) {
     if (slot != 0) {
       if (error != null) {
@@ -1574,20 +1608,16 @@
   }
 }
 
-/**
- * Element representing a compilation unit which is depended upon
- * (either directly or indirectly) by the build unit being linked.
- *
- * TODO(paulberry): ensure that inferred types in dependencies are properly
- * resynthesized.
- */
+/// Element representing a compilation unit which is depended upon
+/// (either directly or indirectly) by the build unit being linked.
+///
+/// TODO(paulberry): ensure that inferred types in dependencies are properly
+/// resynthesized.
 class CompilationUnitElementInDependency extends CompilationUnitElementForLink {
   @override
   final LinkedUnit _linkedUnit;
 
-  /**
-   * Set of slot ids corresponding to parameters that inherit `covariant`.
-   */
+  /// Set of slot ids corresponding to parameters that inherit `covariant`.
   Set<int> parametersInheritingCovariant;
 
   List<EntityRef> _linkedTypeRefs;
@@ -1602,8 +1632,8 @@
       int unitNum,
       String absoluteUri)
       : _linkedUnit = linkedUnit,
-        super(
-            unlinkedUnit, unitNum, linkedUnit.references.length, absoluteUri) {
+        super(unlinkedUnit, unitNum, linkedUnit.references.length, absoluteUri,
+            null) {
     parametersInheritingCovariant =
         _linkedUnit.parametersInheritingCovariant.toSet();
     // Make one pass through the linked types to determine the lengths for
@@ -1635,19 +1665,13 @@
   }
 }
 
-/**
- * Instance of [ConstNode] representing a constant constructor.
- */
+/// Instance of [ConstNode] representing a constant constructor.
 class ConstConstructorNode extends ConstNode {
-  /**
-   * The [ConstructorElement] to which this node refers.
-   */
+  /// The [ConstructorElement] to which this node refers.
   final ConstructorElementForLink constructorElement;
 
-  /**
-   * Once this node has been evaluated, indicates whether the
-   * constructor is free of constant evaluation cycles.
-   */
+  /// Once this node has been evaluated, indicates whether the
+  /// constructor is free of constant evaluation cycles.
   bool isCycleFree = false;
 
   ConstConstructorNode(this.constructorElement);
@@ -1735,10 +1759,8 @@
     return dependencies;
   }
 
-  /**
-   * If [constructorElement] redirects to another constructor via a factory
-   * redirect, return the constructor it redirects to.
-   */
+  /// If [constructorElement] redirects to another constructor via a factory
+  /// redirect, return the constructor it redirects to.
   ConstructorElementForLink _getFactoryRedirectedConstructor() {
     EntityRef redirectedConstructor =
         constructorElement.serializedExecutable.redirectedConstructor;
@@ -1752,10 +1774,8 @@
   }
 }
 
-/**
- * Specialization of [DependencyWalker] for detecting constant
- * evaluation cycles.
- */
+/// Specialization of [DependencyWalker] for detecting constant
+/// evaluation cycles.
 class ConstDependencyWalker extends DependencyWalker<ConstNode> {
   @override
   void evaluate(ConstNode v) {
@@ -1776,19 +1796,15 @@
   }
 }
 
-/**
- * Specialization of [Node] used to construct the constant evaluation
- * dependency graph.
- */
+/// Specialization of [Node] used to construct the constant evaluation
+/// dependency graph.
 abstract class ConstNode extends Node<ConstNode> {
   @override
   bool isEvaluated = false;
 
-  /**
-   * Collect the dependencies in [unlinkedConst] (which should be
-   * interpreted relative to [compilationUnit]) and store them in
-   * [dependencies].
-   */
+  /// Collect the dependencies in [unlinkedConst] (which should be
+  /// interpreted relative to [compilationUnit]) and store them in
+  /// [dependencies].
   void collectDependencies(
       List<ConstNode> dependencies,
       UnlinkedExpr unlinkedConst,
@@ -1874,14 +1890,10 @@
   }
 }
 
-/**
- * Instance of [ConstNode] representing a parameter with a default
- * value.
- */
+/// Instance of [ConstNode] representing a parameter with a default
+/// value.
 class ConstParameterNode extends ConstNode {
-  /**
-   * The [ParameterElement] to which this node refers.
-   */
+  /// The [ParameterElement] to which this node refers.
   final ParameterElementForLink parameterElement;
 
   ConstParameterNode(this.parameterElement);
@@ -1897,18 +1909,14 @@
   }
 }
 
-/**
- * Element representing a constructor resynthesized from a summary
- * during linking.
- */
+/// Element representing a constructor resynthesized from a summary
+/// during linking.
 class ConstructorElementForLink extends ExecutableElementForLink_NonLocal
     with ReferenceableElementForLink
     implements ConstructorElementImpl {
-  /**
-   * If this is a `const` constructor and the enclosing library is
-   * part of the build unit being linked, the constructor's node in
-   * the constant evaluation dependency graph.  Otherwise `null`.
-   */
+  /// If this is a `const` constructor and the enclosing library is
+  /// part of the build unit being linked, the constructor's node in
+  /// the constant evaluation dependency graph.  Otherwise `null`.
   ConstConstructorNode _constNode;
 
   ConstructorElementForLink(ClassElementForLink_Class enclosingClass,
@@ -1948,9 +1956,7 @@
   @override
   List<TypeParameterElement> get typeParameters => const [];
 
-  /**
-   * Perform const cycle detection on this constructor.
-   */
+  /// Perform const cycle detection on this constructor.
   void link(CompilationUnitElementInBuildUnit compilationUnit) {
     if (_constNode != null && !isCycleFree) {
       compilationUnit._storeConstCycle(serializedExecutable.constCycleSlot);
@@ -1962,9 +1968,7 @@
   noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
 }
 
-/**
- * A synthetic constructor.
- */
+/// A synthetic constructor.
 class ConstructorElementForLink_Synthetic extends ConstructorElementForLink {
   ConstructorElementForLink_Synthetic(
       ClassElementForLink_Class enclosingElement)
@@ -1977,15 +1981,11 @@
   List<ParameterElement> get parameters => const <ParameterElement>[];
 }
 
-/**
- * Instance of [ConstNode] representing a constant field or constant
- * top level variable.
- */
+/// Instance of [ConstNode] representing a constant field or constant
+/// top level variable.
 class ConstVariableNode extends ConstNode {
-  /**
-   * The [FieldElement] or [TopLevelVariableElement] to which this
-   * node refers.
-   */
+  /// The [FieldElement] or [TopLevelVariableElement] to which this
+  /// node refers.
   final VariableElementForLink variableElement;
 
   ConstVariableNode(this.variableElement);
@@ -2001,10 +2001,8 @@
   }
 }
 
-/**
- * Stub implementation of [AnalysisContext] which provides just those methods
- * needed during linking.
- */
+/// Stub implementation of [AnalysisContext] which provides just those methods
+/// needed during linking.
 class ContextForLink implements AnalysisContext {
   final Linker _linker;
 
@@ -2014,22 +2012,21 @@
   AnalysisOptionsForLink get analysisOptions => _linker.analysisOptions;
 
   @override
+  TypeProvider get typeProvider => _linker.typeProvider;
+
+  @override
   TypeSystem get typeSystem => _linker.typeSystem;
 
   @override
   noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
 }
 
-/**
- * Base class for executable elements resynthesized from a summary during
- * linking.
- */
+/// Base class for executable elements resynthesized from a summary during
+/// linking.
 abstract class ExecutableElementForLink extends Object
     with TypeParameterizedElementMixin, ParameterParentElementForLink
     implements ExecutableElementImpl {
-  /**
-   * The unlinked representation of the method in the summary.
-   */
+  /// The unlinked representation of the method in the summary.
   final UnlinkedExecutable serializedExecutable;
 
   DartType _declaredReturnType;
@@ -2045,10 +2042,8 @@
   @override
   ContextForLink get context => compilationUnit.context;
 
-  /**
-   * If the executable element had an explicitly declared return type, return
-   * it.  Otherwise return `null`.
-   */
+  /// If the executable element had an explicitly declared return type, return
+  /// it.  Otherwise return `null`.
   DartType get declaredReturnType {
     if (serializedExecutable.returnType == null) {
       return null;
@@ -2072,10 +2067,8 @@
   @override
   CompilationUnitElementImpl get enclosingUnit => compilationUnit;
 
-  /**
-   * Return a list containing all of the functions defined within this
-   * executable element.
-   */
+  /// Return a list containing all of the functions defined within this
+  /// executable element.
   List<FunctionElement> get functions {
     return [];
   }
@@ -2086,10 +2079,8 @@
   @override
   List<int> get implicitFunctionTypeIndices => const <int>[];
 
-  /**
-   * Return the inferred return type of the executable element.  Should only be
-   * called if no return type was explicitly declared.
-   */
+  /// Return the inferred return type of the executable element.  Should only be
+  /// called if no return type was explicitly declared.
   DartType get inferredReturnType {
     // We should only try to infer a return type when none is explicitly
     // declared.
@@ -2163,11 +2154,9 @@
   bool isAccessibleIn(LibraryElement library) =>
       !Identifier.isPrivateName(name) || identical(this.library, library);
 
-  /**
-   * Compute the default return type for this type of executable element (if no
-   * return type is declared and strong mode type inference cannot infer a
-   * better return type).
-   */
+  /// Compute the default return type for this type of executable element (if no
+  /// return type is declared and strong mode type inference cannot infer a
+  /// better return type).
   DartType _computeDefaultReturnType() {
     var kind = serializedExecutable.kind;
     var isMethod = kind == UnlinkedExecutableKind.functionOrMethod;
@@ -2182,16 +2171,12 @@
   }
 }
 
-/**
- * Base class for executable elements that are resynthesized from a summary
- * during linking and are not local functions.
- */
+/// Base class for executable elements that are resynthesized from a summary
+/// during linking and are not local functions.
 abstract class ExecutableElementForLink_NonLocal
     extends ExecutableElementForLink {
-  /**
-   * Return the class in which this executable appears, maybe `null` for a
-   * top-level function.
-   */
+  /// Return the class in which this executable appears, maybe `null` for a
+  /// top-level function.
   final ClassElementForLink_Class enclosingClass;
 
   ExecutableElementForLink_NonLocal(
@@ -2207,9 +2192,7 @@
   TypeParameterizedElementMixin get enclosingTypeParameterContext =>
       enclosingClass;
 
-  /**
-   * Store the results of type inference for this method in [compilationUnit].
-   */
+  /// Store the results of type inference for this method in [compilationUnit].
   void link(CompilationUnitElementInBuildUnit compilationUnit) {
     if (serializedExecutable.returnType == null) {
       compilationUnit._storeLinkedType(
@@ -2230,7 +2213,19 @@
 
   final ResolverVisitor _resolverVisitor;
 
+  final TypeResolverVisitor _typeResolverVisitor;
+
+  final VariableResolverVisitor _variableResolverVisitor;
+
+  final PartialResolverVisitor _partialResolverVisitor;
+
+  final Linker _linker;
+
+  FunctionElementForLink_Local _functionElement;
+
   factory ExprTypeComputer(FunctionElementForLink_Local functionElement) {
+    ClassElement enclosingClass =
+        functionElement.getAncestor((e) => e is ClassElement);
     CompilationUnitElementForLink unit = functionElement.compilationUnit;
     LibraryElementForLink library = unit.enclosingElement;
     Linker linker = library._linker;
@@ -2238,17 +2233,36 @@
     var unlinkedExecutable = functionElement.serializedExecutable;
     UnlinkedExpr unlinkedConst = unlinkedExecutable.bodyExpr;
     var errorListener = AnalysisErrorListener.NULL_LISTENER;
+    var source = unit.source;
     var astRewriteVisitor = new AstRewriteVisitor(
-        linker.typeSystem, library, unit.source, typeProvider, errorListener);
-    // TODO(paulberry): Do we need to pass a nameScope to
-    // resolverVisitor to get type variables to resolve properly?
+        linker.typeSystem, library, source, typeProvider, errorListener);
+    EnclosedScope nameScope = new LibraryScope(library);
+    if (enclosingClass != null) {
+      nameScope = new ClassScope(
+          new TypeParameterScope(nameScope, enclosingClass), enclosingClass);
+    }
     var resolverVisitor = new ResolverVisitor(
-        library, unit.source, typeProvider, errorListener,
-        propagateTypes: false, reportConstEvaluationErrors: false);
+        library, source, typeProvider, errorListener,
+        nameScope: nameScope,
+        propagateTypes: false,
+        reportConstEvaluationErrors: false);
+    var typeResolverVisitor = new TypeResolverVisitor(
+        library, source, typeProvider, errorListener,
+        nameScope: nameScope);
+    var variableResolverVisitor = new VariableResolverVisitor(
+        library, source, typeProvider, errorListener,
+        nameScope: nameScope);
+    var partialResolverVisitor = new PartialResolverVisitor(
+        library, source, typeProvider, errorListener,
+        nameScope: nameScope);
     return new ExprTypeComputer._(
         unit._unitResynthesizer,
         astRewriteVisitor,
         resolverVisitor,
+        typeResolverVisitor,
+        variableResolverVisitor,
+        partialResolverVisitor,
+        linker,
         errorListener,
         functionElement,
         unlinkedConst,
@@ -2259,11 +2273,16 @@
       UnitResynthesizer unitResynthesizer,
       this._astRewriteVisitor,
       this._resolverVisitor,
+      this._typeResolverVisitor,
+      this._variableResolverVisitor,
+      this._partialResolverVisitor,
+      this._linker,
       AnalysisErrorListener _errorListener,
-      ElementImpl context,
+      this._functionElement,
       UnlinkedExpr unlinkedConst,
       List<UnlinkedExecutable> localFunctions)
-      : _builder = new ExprBuilder(unitResynthesizer, context, unlinkedConst,
+      : _builder = new ExprBuilder(
+            unitResynthesizer, _functionElement, unlinkedConst,
             requireValidConst: false, localFunctions: localFunctions);
 
   TopLevelInferenceErrorKind get errorKind {
@@ -2273,29 +2292,37 @@
   }
 
   DartType compute() {
-    if (_builder.uc == null) {
+    Expression expression;
+    if (_linker.getAst != null) {
+      var expressionForInference = _functionElement._expressionForInference;
+      if (expressionForInference != null) {
+        expression = AstCloner().cloneNode(expressionForInference);
+        expression.accept(LocalElementBuilder(ElementHolder(), null));
+      }
+    } else if (_builder.uc != null && _builder.uc.operations.isNotEmpty) {
+      expression = _builder.build();
+    }
+    if (expression == null) {
       // No function body was stored for this function, so we can't infer its
       // return type.  Assume `dynamic`.
       return DynamicTypeImpl.instance;
     }
-    // If no operations, we cannot compute the type.  Assume `dynamic`.
-    if (_builder.uc.operations.isEmpty) {
-      return DynamicTypeImpl.instance;
-    }
-    var expression = _builder.build();
     var container =
         astFactory.expressionFunctionBody(null, null, expression, null);
     expression.accept(_astRewriteVisitor);
     expression = container.expression;
+    if (_linker.getAst != null) {
+      expression.accept(_typeResolverVisitor);
+      expression.accept(_variableResolverVisitor);
+      expression.accept(_partialResolverVisitor);
+    }
     expression.accept(_resolverVisitor);
     return expression.staticType;
   }
 }
 
-/**
- * Element representing a field resynthesized from a summary during
- * linking.
- */
+/// Element representing a field resynthesized from a summary during
+/// linking.
 abstract class FieldElementForLink implements FieldElement {
   @override
   PropertyAccessorElementForLink get getter;
@@ -2304,26 +2331,23 @@
   PropertyAccessorElementForLink get setter;
 }
 
-/**
- * Specialization of [FieldElementForLink] for class fields.
- */
+/// Specialization of [FieldElementForLink] for class fields.
 class FieldElementForLink_ClassField extends VariableElementForLink
     implements FieldElementForLink {
   @override
   final ClassElementForLink_Class enclosingElement;
 
-  /**
-   * If this is an instance field, the type that was computed by
-   * [InstanceMemberInferrer] (if any).  Otherwise `null`.
-   */
+  /// If this is an instance field, the type that was computed by
+  /// [InstanceMemberInferrer] (if any).  Otherwise `null`.
   DartType _inferredInstanceType;
 
   TopLevelInferenceErrorBuilder _inferenceError;
 
   FieldElementForLink_ClassField(ClassElementForLink_Class enclosingElement,
-      UnlinkedVariable unlinkedVariable)
+      UnlinkedVariable unlinkedVariable, Expression initializerForInference)
       : enclosingElement = enclosingElement,
-        super(unlinkedVariable, enclosingElement.enclosingElement);
+        super(unlinkedVariable, enclosingElement.enclosingElement,
+            initializerForInference);
 
   @override
   bool get isStatic => unlinkedVariable.isStatic;
@@ -2338,10 +2362,8 @@
   @override
   TypeParameterizedElementMixin get _typeParameterContext => enclosingElement;
 
-  /**
-   * Store the results of type inference for this field in
-   * [compilationUnit].
-   */
+  /// Store the results of type inference for this field in
+  /// [compilationUnit].
   void link(CompilationUnitElementInBuildUnit compilationUnit) {
     if (hasImplicitType) {
       compilationUnit._storeLinkedType(
@@ -2367,9 +2389,7 @@
   String toString() => '$enclosingElement.$name';
 }
 
-/**
- * Specialization of [FieldElementForLink] for enum fields.
- */
+/// Specialization of [FieldElementForLink] for enum fields.
 class FieldElementForLink_EnumField extends FieldElementForLink
     implements FieldElement {
   PropertyAccessorElementForLink_EnumField _getter;
@@ -2393,9 +2413,7 @@
   String toString() => '$enclosingElement.$name';
 }
 
-/**
- * Specialization of [FieldElementForLink] for the 'index' enum field.
- */
+/// Specialization of [FieldElementForLink] for the 'index' enum field.
 class FieldElementForLink_EnumField_index
     extends FieldElementForLink_EnumField {
   FieldElementForLink_EnumField_index(ClassElementForLink_Enum enclosingElement)
@@ -2412,14 +2430,10 @@
       enclosingElement.enclosingElement.library._linker.typeProvider.intType;
 }
 
-/**
- * Specialization of [FieldElementForLink] for enum fields.
- */
+/// Specialization of [FieldElementForLink] for enum fields.
 class FieldElementForLink_EnumField_value
     extends FieldElementForLink_EnumField {
-  /**
-   * The unlinked representation of the field in the summary.
-   */
+  /// The unlinked representation of the field in the summary.
   final UnlinkedEnumValue unlinkedEnumValue;
 
   FieldElementForLink_EnumField_value(
@@ -2436,9 +2450,7 @@
   DartType get type => enclosingElement.type;
 }
 
-/**
- * Specialization of [FieldElementForLink] for the 'values' enum field.
- */
+/// Specialization of [FieldElementForLink] for the 'values' enum field.
 class FieldElementForLink_EnumField_values
     extends FieldElementForLink_EnumField {
   FieldElementForLink_EnumField_values(
@@ -2495,10 +2507,8 @@
   }
 }
 
-/**
- * Element representing a function-typed parameter resynthesied from a summary
- * during linking.
- */
+/// Element representing a function-typed parameter resynthesied from a summary
+/// during linking.
 class FunctionElementForLink_FunctionTypedParam extends Object
     with ParameterParentElementForLink
     implements FunctionElement {
@@ -2551,28 +2561,26 @@
   noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
 }
 
-/**
- * Element representing the initializer expression of a variable.
- */
+/// Element representing the initializer expression of a variable.
 class FunctionElementForLink_Initializer extends Object
     with ReferenceableElementForLink, TypeParameterizedElementMixin
     implements FunctionElementForLink_Local {
-  /**
-   * The variable for which this element is the initializer.
-   */
+  /// The variable for which this element is the initializer.
   final VariableElementForLink _variable;
 
-  /**
-   * The type inference node for this function, or `null` if it hasn't been
-   * computed yet.
-   */
+  @override
+  final Expression _expressionForInference;
+
+  /// The type inference node for this function, or `null` if it hasn't been
+  /// computed yet.
   TypeInferenceNode _typeInferenceNode;
 
   List<FunctionElementForLink_Local_NonSynthetic> _functions;
   DartType _inferredReturnType;
   TopLevelInferenceErrorBuilder _inferenceError;
 
-  FunctionElementForLink_Initializer(this._variable);
+  FunctionElementForLink_Initializer(
+      this._variable, this._expressionForInference);
 
   @override
   TypeInferenceNode get asTypeInferenceNode =>
@@ -2595,11 +2603,7 @@
 
   @override
   List<FunctionElementForLink_Local_NonSynthetic> get functions =>
-      _functions ??= _variable.unlinkedVariable.initializer.localFunctions
-          .map((UnlinkedExecutable ex) =>
-              new FunctionElementForLink_Local_NonSynthetic(
-                  _variable.compilationUnit, this, ex))
-          .toList();
+      _functions ??= _computeFunctions();
 
   @override
   String get identifier => '';
@@ -2642,15 +2646,18 @@
   bool get _hasTypeBeenInferred => _inferredReturnType != null;
 
   @override
+  E getAncestor<E extends Element>(Predicate<Element> predicate) {
+    return ElementImpl.getAncestorStatic(enclosingElement, predicate);
+  }
+
+  @override
   FunctionElementForLink_Local getLocalFunction(int index) {
     List<FunctionElementForLink_Local_NonSynthetic> functions = this.functions;
     return index < functions.length ? functions[index] : null;
   }
 
-  /**
-   * Store the results of type inference for this initializer in
-   * [compilationUnit].
-   */
+  /// Store the results of type inference for this initializer in
+  /// [compilationUnit].
   void link(CompilationUnitElementInBuildUnit compilationUnit) {
     compilationUnit._storeLinkedType(
         serializedExecutable.inferredReturnTypeSlot,
@@ -2667,6 +2674,21 @@
   @override
   String toString() => _variable.toString();
 
+  List<FunctionElementForLink_Local_NonSynthetic> _computeFunctions() {
+    var localFunctionsFromSummary =
+        _variable.unlinkedVariable.initializer.localFunctions;
+    var count = localFunctionsFromSummary.length;
+    var result = List<FunctionElementForLink_Local_NonSynthetic>(count);
+    for (int i = 0; i < count; i++) {
+      result[i] = FunctionElementForLink_Local_NonSynthetic(
+          _variable.compilationUnit,
+          this,
+          localFunctionsFromSummary[i],
+          i == 0 ? _expressionForInference : null);
+    }
+    return result;
+  }
+
   @override
   void _setInferenceError(TopLevelInferenceErrorBuilder error) {
     assert(!_hasTypeBeenInferred);
@@ -2681,54 +2703,51 @@
   }
 }
 
-/**
- * Element representing a local function (possibly a closure).
- */
+/// Element representing a local function (possibly a closure).
 abstract class FunctionElementForLink_Local
     implements
         ExecutableElementForLink,
         FunctionElementImpl,
         ReferenceableElementForLink {
-  /**
-   * Indicates whether type inference has completed for this function.
-   */
+  /// If this function element represents the initializer of a field or a
+  /// top-level variable, returns the AST for the initializer expression; this
+  /// is used for inferring the expression type.
+  Expression get _expressionForInference;
+
+  /// Indicates whether type inference has completed for this function.
   bool get _hasTypeBeenInferred;
 
-  /**
-   * Stores the given [error] as the type inference error for this function.
-   * Should only be called if [_hasTypeBeenInferred] is `false`.
-   */
+  /// Stores the given [error] as the type inference error for this function.
+  /// Should only be called if [_hasTypeBeenInferred] is `false`.
   void _setInferenceError(TopLevelInferenceErrorBuilder error);
 
-  /**
-   * Stores the given [type] as the inferred return type for this function.
-   * Should only be called if [_hasTypeBeenInferred] is `false`.
-   */
+  /// Stores the given [type] as the inferred return type for this function.
+  /// Should only be called if [_hasTypeBeenInferred] is `false`.
   void _setInferredType(DartType type);
 }
 
-/**
- * Element representing a local function (possibly a closure) inside another
- * executable.
- */
+/// Element representing a local function (possibly a closure) inside another
+/// executable.
 class FunctionElementForLink_Local_NonSynthetic extends ExecutableElementForLink
     with ReferenceableElementForLink
     implements FunctionElementForLink_Local {
   @override
   final ExecutableElementForLink enclosingElement;
 
+  @override
+  final Expression _expressionForInference;
+
   List<FunctionElementForLink_Local_NonSynthetic> _functions;
 
-  /**
-   * The type inference node for this function, or `null` if it hasn't been
-   * computed yet.
-   */
+  /// The type inference node for this function, or `null` if it hasn't been
+  /// computed yet.
   TypeInferenceNode _typeInferenceNode;
 
   FunctionElementForLink_Local_NonSynthetic(
       CompilationUnitElementForLink compilationUnit,
       this.enclosingElement,
-      UnlinkedExecutable unlinkedExecutable)
+      UnlinkedExecutable unlinkedExecutable,
+      this._expressionForInference)
       : super(compilationUnit, unlinkedExecutable);
 
   @override
@@ -2744,7 +2763,7 @@
       _functions ??= serializedExecutable.localFunctions
           .map((UnlinkedExecutable ex) =>
               new FunctionElementForLink_Local_NonSynthetic(
-                  compilationUnit, this, ex))
+                  compilationUnit, this, ex, null))
           .toList();
 
   @override
@@ -2773,14 +2792,18 @@
   }
 
   @override
+  E getAncestor<E extends Element>(Predicate<Element> predicate) {
+    return ElementImpl.getAncestorStatic(enclosingElement, predicate);
+  }
+
+  @override
   FunctionElementForLink_Local getLocalFunction(int index) {
     List<FunctionElementForLink_Local_NonSynthetic> functions = this.functions;
     return index < functions.length ? functions[index] : null;
   }
 
-  /**
-   * Store the results of type inference for this function in [compilationUnit].
-   */
+  /// Store the results of type inference for this function in
+  /// [compilationUnit].
   void link(CompilationUnitElementInBuildUnit compilationUnit) {
     if (serializedExecutable.returnType == null) {
       compilationUnit._storeLinkedType(
@@ -2810,9 +2833,7 @@
   }
 }
 
-/**
-  * Synthetic function element which is created for local functions.
-  */
+/// Synthetic function element which is created for local functions.
 class FunctionElementForLink_Synthetic extends ExecutableElementForLink
     with ReferenceableElementForLink
     implements FunctionElementForLink_Local {
@@ -2851,9 +2872,7 @@
   noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
 }
 
-/**
- * Element representing a typedef resynthesized from a summary during linking.
- */
+/// Element representing a typedef resynthesized from a summary during linking.
 class FunctionTypeAliasElementForLink extends Object
     with
         TypeParameterizedElementMixin,
@@ -2863,9 +2882,7 @@
   @override
   final CompilationUnitElementForLink enclosingElement;
 
-  /**
-   * The unlinked representation of the typedef in the summary.
-   */
+  /// The unlinked representation of the typedef in the summary.
   final UnlinkedTypedef _unlinkedTypedef;
 
   FunctionTypeImpl _type;
@@ -2942,10 +2959,8 @@
   String toString() => '$enclosingElement.$name';
 }
 
-/**
- * Element representing a generic function resynthesized from a summary during
- * linking.
- */
+/// Element representing a generic function resynthesized from a summary during
+/// linking.
 class GenericFunctionTypeElementForLink extends Object
     with
         TypeParameterizedElementMixin,
@@ -2958,9 +2973,7 @@
   @override
   final ElementImpl enclosingElement;
 
-  /**
-   * The linked representation of the generic function in the summary.
-   */
+  /// The linked representation of the generic function in the summary.
   final EntityRef _entity;
 
   DartType _returnType;
@@ -3022,10 +3035,8 @@
   String toString() => '$enclosingElement.$name';
 }
 
-/**
- * Element representing a generic typedef resynthesized from a summary during
- * linking.
- */
+/// Element representing a generic typedef resynthesized from a summary during
+/// linking.
 class GenericTypeAliasElementForLink extends Object
     with
         TypeParameterizedElementMixin,
@@ -3035,9 +3046,7 @@
   @override
   final CompilationUnitElementForLink enclosingElement;
 
-  /**
-   * The unlinked representation of the typedef in the summary.
-   */
+  /// The unlinked representation of the typedef in the summary.
   final UnlinkedTypedef _unlinkedTypedef;
 
   GenericTypeAliasElementForLink(this.enclosingElement, this._unlinkedTypedef);
@@ -3115,9 +3124,7 @@
   String toString() => '$enclosingElement.$name';
 }
 
-/**
- * Specialization of [DependencyWalker] for linking library cycles.
- */
+/// Specialization of [DependencyWalker] for linking library cycles.
 class LibraryCycleDependencyWalker extends DependencyWalker<LibraryCycleNode> {
   @override
   void evaluate(LibraryCycleNode v) {
@@ -3131,25 +3138,17 @@
   }
 }
 
-/**
- * An instance of [LibraryCycleForLink] represents a single library cycle
- * discovered during linking; it consists of one or more libraries in the build
- * unit being linked.
- */
+/// An instance of [LibraryCycleForLink] represents a single library cycle
+/// discovered during linking; it consists of one or more libraries in the build
+/// unit being linked.
 class LibraryCycleForLink {
-  /**
-   * The libraries in the cycle.
-   */
+  /// The libraries in the cycle.
   final List<LibraryElementInBuildUnit> libraries;
 
-  /**
-   * The library cycles which this library depends on.
-   */
+  /// The library cycles which this library depends on.
   final List<LibraryCycleForLink> dependencies;
 
-  /**
-   * The [LibraryCycleNode] for this library cycle.
-   */
+  /// The [LibraryCycleNode] for this library cycle.
   LibraryCycleNode _node;
 
   LibraryCycleForLink(this.libraries, this.dependencies) {
@@ -3158,10 +3157,8 @@
 
   LibraryCycleNode get node => _node;
 
-  /**
-   * Link this library cycle and any library cycles it depends on.  Does
-   * nothing if this library cycle has already been linked.
-   */
+  /// Link this library cycle and any library cycles it depends on.  Does
+  /// nothing if this library cycle has already been linked.
   void ensureLinked() {
     if (!node.isEvaluated) {
       new LibraryCycleDependencyWalker().walk(node);
@@ -3169,19 +3166,13 @@
   }
 }
 
-/**
- * Specialization of [Node] used to link library cycles in proper dependency
- * order.
- */
+/// Specialization of [Node] used to link library cycles in proper dependency
+/// order.
 class LibraryCycleNode extends Node<LibraryCycleNode> {
-  /**
-   * The library cycle this [Node] represents.
-   */
+  /// The library cycle this [Node] represents.
   final LibraryCycleForLink libraryCycle;
 
-  /**
-   * Indicates whether this library cycle has been linked yet.
-   */
+  /// Indicates whether this library cycle has been linked yet.
   bool _isLinked = false;
 
   LibraryCycleNode(this.libraryCycle);
@@ -3194,9 +3185,7 @@
       .map((LibraryCycleForLink cycle) => cycle.node)
       .toList();
 
-  /**
-   * Link this library cycle.
-   */
+  /// Link this library cycle.
   void link() {
     for (LibraryElementInBuildUnit library in libraryCycle.libraries) {
       library.link();
@@ -3205,9 +3194,7 @@
   }
 }
 
-/**
- * Specialization of [DependencyWalker] for computing library cycles.
- */
+/// Specialization of [DependencyWalker] for computing library cycles.
 class LibraryDependencyWalker extends DependencyWalker<LibraryNode> {
   @override
   void evaluate(LibraryNode v) => evaluateScc(<LibraryNode>[v]);
@@ -3231,24 +3218,18 @@
   }
 }
 
-/**
- * Element representing a library resynthesied from a summary during
- * linking.  The type parameter, [UnitElement], represents the type
- * that will be used for the compilation unit elements.
- */
+/// Element representing a library resynthesied from a summary during
+/// linking.  The type parameter, [UnitElement], represents the type
+/// that will be used for the compilation unit elements.
 abstract class LibraryElementForLink<
         UnitElement extends CompilationUnitElementForLink>
     extends LibraryResynthesizerContextMixin implements LibraryElementImpl {
   final _LibraryResynthesizer resynthesizer;
 
-  /**
-   * Pointer back to the linker.
-   */
+  /// Pointer back to the linker.
   final Linker _linker;
 
-  /**
-   * The absolute URI of this library.
-   */
+  /// The absolute URI of this library.
   final Uri _absoluteUri;
 
   List<UnitElement> _units;
@@ -3313,10 +3294,8 @@
   @override
   bool get isSynthetic => _linkedLibrary == null;
 
-  /**
-   * If this library is part of the build unit being linked, return the library
-   * cycle it is part of.  Otherwise return `null`.
-   */
+  /// If this library is part of the build unit being linked, return the library
+  /// cycle it is part of.  Otherwise return `null`.
   LibraryCycleForLink get libraryCycleForLink;
 
   @override
@@ -3380,14 +3359,10 @@
   List<LinkedExportName> get _linkedExportNames =>
       _linkedLibrary == null ? [] : _linkedLibrary.exportNames;
 
-  /**
-   * The linked representation of the library in the summary.
-   */
+  /// The linked representation of the library in the summary.
   LinkedLibrary get _linkedLibrary;
 
-  /**
-   * Return the [LibraryElement] corresponding to the given dependency [index].
-   */
+  /// Return the [LibraryElement] corresponding to the given dependency [index].
   LibraryElementForLink buildImportedLibrary(int index) {
     LibraryElementForLink result = _dependencies[index];
     if (result == null) {
@@ -3409,11 +3384,9 @@
     return result;
   }
 
-  /**
-   * Search all the units for a top level element with the given
-   * [name].  If no name is found, return the singleton instance of
-   * [UndefinedElementForLink].
-   */
+  /// Search all the units for a top level element with the given
+  /// [name].  If no name is found, return the singleton instance of
+  /// [UndefinedElementForLink].
   ReferenceableElementForLink getContainedName(String name) =>
       _containedNames.putIfAbsent(name, () {
         for (UnitElement unit in units) {
@@ -3440,27 +3413,21 @@
   @override
   String toString() => _absoluteUri.toString();
 
-  /**
-   * Create a [UnitElement] for one of the library's compilation
-   * units.
-   */
+  /// Create a [UnitElement] for one of the library's compilation
+  /// units.
   UnitElement _makeUnitElement(
       UnlinkedUnit unlinkedUnit, int i, String absoluteUri);
 }
 
-/**
- * Element representing a library which is part of the build unit
- * being linked.
- */
+/// Element representing a library which is part of the build unit
+/// being linked.
 class LibraryElementInBuildUnit
     extends LibraryElementForLink<CompilationUnitElementInBuildUnit> {
   @override
   final LinkedLibraryBuilder _linkedLibrary;
 
-  /**
-   * The [LibraryNode] representing this library in the library dependency
-   * graph.
-   */
+  /// The [LibraryNode] representing this library in the library dependency
+  /// graph.
   LibraryNode _libraryNode;
 
   InheritanceManager _inheritanceManager;
@@ -3479,9 +3446,7 @@
       _imports ??= LibraryElementImpl.buildImportsFromSummary(this,
           _unlinkedDefiningUnit.imports, _linkedLibrary.importDependencies);
 
-  /**
-   * Get the inheritance manager for this library (creating it if necessary).
-   */
+  /// Get the inheritance manager for this library (creating it if necessary).
   InheritanceManager get inheritanceManager =>
       _inheritanceManager ??= new InheritanceManager(this, ignoreErrors: true);
 
@@ -3497,11 +3462,9 @@
   List<PrefixElement> get prefixes =>
       _prefixes ??= LibraryElementImpl.buildPrefixesFromImports(imports);
 
-  /**
-   * If this library already has a dependency in its dependencies table matching
-   * [library], return its index.  Otherwise add a new dependency to table and
-   * return its index.
-   */
+  /// If this library already has a dependency in its dependencies table
+  /// matching [library], return its index.  Otherwise add a new dependency to
+  /// table and return its index.
   int addDependency(LibraryElementForLink library) {
     for (int i = 0; i < _linkedLibrary.dependencies.length; i++) {
       if (identical(buildImportedLibrary(i), library)) {
@@ -3522,19 +3485,15 @@
     return result;
   }
 
-  /**
-   * Perform type inference and const cycle detection on this library.
-   */
+  /// Perform type inference and const cycle detection on this library.
   void link() {
     for (CompilationUnitElementInBuildUnit unit in units) {
       unit.link();
     }
   }
 
-  /**
-   * Throw away any information stored in the summary by a previous call to
-   * [link].
-   */
+  /// Throw away any information stored in the summary by a previous call to
+  /// [link].
   void unlink() {
     _linkedLibrary.dependencies.length =
         _linkedLibrary.numPrelinkedDependencies;
@@ -3545,15 +3504,16 @@
 
   @override
   CompilationUnitElementInBuildUnit _makeUnitElement(
-          UnlinkedUnit unlinkedUnit, int i, String absoluteUri) =>
-      new CompilationUnitElementInBuildUnit(
-          this, unlinkedUnit, _linkedLibrary.units[i], i, absoluteUri);
+      UnlinkedUnit unlinkedUnit, int i, String absoluteUri) {
+    var astNodeForInference =
+        _linker.getAst == null ? null : _linker.getAst(absoluteUri);
+    return new CompilationUnitElementInBuildUnit(this, unlinkedUnit,
+        _linkedLibrary.units[i], i, absoluteUri, astNodeForInference);
+  }
 }
 
-/**
- * Element representing a library which is depended upon (either
- * directly or indirectly) by the build unit being linked.
- */
+/// Element representing a library which is depended upon (either
+/// directly or indirectly) by the build unit being linked.
 class LibraryElementInDependency
     extends LibraryElementForLink<CompilationUnitElementInDependency> {
   @override
@@ -3579,19 +3539,13 @@
           absoluteUri);
 }
 
-/**
- * Specialization of [Node] used to construct the library dependency graph.
- */
+/// Specialization of [Node] used to construct the library dependency graph.
 class LibraryNode extends Node<LibraryNode> {
-  /**
-   * The library this [Node] represents.
-   */
+  /// The library this [Node] represents.
   final LibraryElementInBuildUnit library;
 
-  /**
-   * The library cycle to which [library] belongs, if it has been computed.
-   * Otherwise `null`.
-   */
+  /// The library cycle to which [library] belongs, if it has been computed.
+  /// Otherwise `null`.
   LibraryCycleForLink _libraryCycle;
 
   LibraryNode(this.library);
@@ -3619,45 +3573,36 @@
   }
 }
 
-/**
- * Instances of [Linker] contain the necessary information to link
- * together a single build unit.
- */
+/// Instances of [Linker] contain the necessary information to link
+/// together a single build unit.
 class Linker {
-  /**
-   * During linking, if type inference is currently being performed on the
-   * initializer of a static or instance variable, the library cycle in
-   * which inference is being performed.  Otherwise, `null`.
-   *
-   * This allows us to suppress instance member type inference results from a
-   * library cycle while doing inference on the right hand sides of static and
-   * instance variables in that same cycle.
-   */
+  /// During linking, if type inference is currently being performed on the
+  /// initializer of a static or instance variable, the library cycle in
+  /// which inference is being performed.  Otherwise, `null`.
+  ///
+  /// This allows us to suppress instance member type inference results from a
+  /// library cycle while doing inference on the right hand sides of static and
+  /// instance variables in that same cycle.
   static LibraryCycleForLink _initializerTypeInferenceCycle;
 
-  /**
-   * Callback to ask the client for a [LinkedLibrary] for a
-   * dependency.
-   */
+  /// Callback to ask the client for a [LinkedLibrary] for a
+  /// dependency.
   final GetDependencyCallback getDependency;
 
-  /**
-   * Callback to ask the client for an [UnlinkedUnit].
-   */
+  /// Callback to ask the client for an [UnlinkedUnit].
   final GetUnitCallback getUnit;
 
-  /**
-   * Map containing all library elements accessed during linking,
-   * whether they are part of the build unit being linked or whether
-   * they are dependencies.
-   */
+  /// Callback to ask the client for a [CompilationUnit].
+  final GetAstCallback getAst;
+
+  /// Map containing all library elements accessed during linking,
+  /// whether they are part of the build unit being linked or whether
+  /// they are dependencies.
   final Map<Uri, LibraryElementForLink> _libraries =
       <Uri, LibraryElementForLink>{};
 
-  /**
-   * List of library elements for the libraries in the build unit
-   * being linked.
-   */
+  /// List of library elements for the libraries in the build unit
+  /// being linked.
   final List<LibraryElementInBuildUnit> _librariesInBuildUnit =
       <LibraryElementInBuildUnit>[];
 
@@ -3672,7 +3617,7 @@
   ContextForLink _context;
   AnalysisOptionsForLink _analysisOptions;
   Linker(Map<String, LinkedLibraryBuilder> linkedLibraries, this.getDependency,
-      this.getUnit) {
+      this.getUnit, this.getAst) {
     // Create elements for the libraries to be linked.  The rest of
     // the element model will be created on demand.
     linkedLibraries
@@ -3683,78 +3628,54 @@
     });
   }
 
-  /**
-   * Get an instance of [AnalysisOptions] for use during linking.
-   */
+  /// Get an instance of [AnalysisOptions] for use during linking.
   AnalysisOptionsForLink get analysisOptions =>
       _analysisOptions ??= new AnalysisOptionsForLink(this);
 
-  /**
-   * Get the library element for `dart:async`.
-   */
+  /// Get the library element for `dart:async`.
   LibraryElementForLink get asyncLibrary =>
       _asyncLibrary ??= getLibrary(Uri.parse('dart:async'));
 
-  /**
-   * Get the element representing the "bottom" type.
-   */
+  /// Get the element representing the "bottom" type.
   SpecialTypeElementForLink get bottomElement => _bottomElement ??=
       new SpecialTypeElementForLink(this, BottomTypeImpl.instance);
 
-  /**
-   * Get a stub implementation of [AnalysisContext] which can be used during
-   * linking.
-   */
+  /// Get a stub implementation of [AnalysisContext] which can be used during
+  /// linking.
   get context => _context ??= new ContextForLink(this);
 
-  /**
-   * Get the library element for `dart:core`.
-   */
+  /// Get the library element for `dart:core`.
   LibraryElementForLink get coreLibrary =>
       _coreLibrary ??= getLibrary(Uri.parse('dart:core'));
 
-  /**
-   * Get the element representing `dynamic`.
-   */
+  /// Get the element representing `dynamic`.
   SpecialTypeElementForLink get dynamicElement => _dynamicElement ??=
       new SpecialTypeElementForLink(this, DynamicTypeImpl.instance);
 
-  /**
-   * Indicates whether type inference should use strong mode rules.
-   */
+  /// Indicates whether type inference should use strong mode rules.
   @deprecated
   bool get strongMode => true;
 
-  /**
-   * Get an instance of [TypeProvider] for use during linking.
-   */
+  /// Get an instance of [TypeProvider] for use during linking.
   TypeProviderForLink get typeProvider =>
       _typeProvider ??= new TypeProviderForLink(this);
 
-  /**
-   * Get an instance of [TypeSystem] for use during linking.
-   */
+  /// Get an instance of [TypeSystem] for use during linking.
   TypeSystem get typeSystem =>
       _typeSystem ??= new StrongTypeSystemImpl(typeProvider);
 
-  /**
-   * Get the element representing `void`.
-   */
+  /// Get the element representing `void`.
   SpecialTypeElementForLink get voidElement => _voidElement ??=
       new SpecialTypeElementForLink(this, VoidTypeImpl.instance);
 
-  /**
-   * Get the library element for the library having the given [uri].
-   */
+  /// Get the library element for the library having the given [uri].
   LibraryElementForLink getLibrary(Uri uri) => _libraries.putIfAbsent(
       uri,
       () => new LibraryElementInDependency(
           this, uri, getDependency(uri.toString())));
 
-  /**
-   * Perform type inference and const cycle detection on all libraries
-   * in the build unit being linked.
-   */
+  /// Perform type inference and const cycle detection on all libraries
+  /// in the build unit being linked.
   void link() {
     // Link library cycles in appropriate dependency order.
     for (LibraryElementInBuildUnit library in _librariesInBuildUnit) {
@@ -3763,10 +3684,8 @@
     // TODO(paulberry): set dependencies.
   }
 
-  /**
-   * Throw away any information stored in the summary by a previous call to
-   * [link].
-   */
+  /// Throw away any information stored in the summary by a previous call to
+  /// [link].
   void unlink() {
     for (LibraryElementInBuildUnit library in _librariesInBuildUnit) {
       library.unlink();
@@ -3774,9 +3693,7 @@
   }
 }
 
-/**
- * Element representing a method resynthesized from a summary during linking.
- */
+/// Element representing a method resynthesized from a summary during linking.
 class MethodElementForLink extends ExecutableElementForLink_NonLocal
     with ReferenceableElementForLink
     implements MethodElementImpl {
@@ -3810,42 +3727,30 @@
   String toString() => '$enclosingElement.$name';
 }
 
-/**
- * Element used for references that result from trying to access a non-static
- * member of an element that is not a container (e.g. accessing the "length"
- * property of a constant).
- *
- * Accesses to a chain of non-static members separated by '.' are handled by
- * creating a [NonstaticMemberElementForLink] that points to another
- * [NonstaticMemberElementForLink], to whatever nesting level is necessary.
- */
+/// Element used for references that result from trying to access a non-static
+/// member of an element that is not a container (e.g. accessing the "length"
+/// property of a constant).
+///
+/// Accesses to a chain of non-static members separated by '.' are handled by
+/// creating a [NonstaticMemberElementForLink] that points to another
+/// [NonstaticMemberElementForLink], to whatever nesting level is necessary.
 class NonstaticMemberElementForLink extends Object
     with ReferenceableElementForLink {
-  /**
-   * The [ReferenceableElementForLink] which is the target of the non-static
-   * reference.
-   */
+  /// The [ReferenceableElementForLink] which is the target of the non-static
+  /// reference.
   final ReferenceableElementForLink _target;
 
-  /**
-   * The name of the non-static members that is being accessed.
-   */
+  /// The name of the non-static members that is being accessed.
   final String _name;
 
-  /**
-   * The library in which the access occurs.  This determines whether private
-   * names are accessible.
-   */
+  /// The library in which the access occurs.  This determines whether private
+  /// names are accessible.
   final LibraryElementForLink _library;
 
-  /**
-   * Whether the [_element] was computed (even if to `null`).
-   */
+  /// Whether the [_element] was computed (even if to `null`).
   bool _elementReady = false;
 
-  /**
-   * The cached [ExecutableElement] represented by this element.
-   */
+  /// The cached [ExecutableElement] represented by this element.
   ExecutableElement _element;
 
   NonstaticMemberElementForLink(this._library, this._target, this._name);
@@ -3853,9 +3758,7 @@
   @override
   ConstVariableNode get asConstVariable => _target.asConstVariable;
 
-  /**
-   * Return the [ExecutableElement] represented by this element.
-   */
+  /// Return the [ExecutableElement] represented by this element.
   ExecutableElement get asExecutableElement {
     if (!_elementReady) {
       _elementReady = true;
@@ -3902,36 +3805,24 @@
   String toString() => '$_target.(dynamic)$_name';
 }
 
-/**
- * Element representing a function or method parameter resynthesized
- * from a summary during linking.
- */
+/// Element representing a function or method parameter resynthesized
+/// from a summary during linking.
 class ParameterElementForLink implements ParameterElementImpl {
-  /**
-   * The unlinked representation of the parameter in the summary.
-   */
+  /// The unlinked representation of the parameter in the summary.
   final UnlinkedParam unlinkedParam;
 
-  /**
-   * The innermost enclosing element that can declare type parameters.
-   */
+  /// The innermost enclosing element that can declare type parameters.
   final TypeParameterizedElementMixin _typeParameterContext;
 
-  /**
-   * If this parameter has a default value and the enclosing library
-   * is part of the build unit being linked, the parameter's node in
-   * the constant evaluation dependency graph.  Otherwise `null`.
-   */
+  /// If this parameter has a default value and the enclosing library
+  /// is part of the build unit being linked, the parameter's node in
+  /// the constant evaluation dependency graph.  Otherwise `null`.
   ConstNode _constNode;
 
-  /**
-   * The compilation unit in which this parameter appears.
-   */
+  /// The compilation unit in which this parameter appears.
   final CompilationUnitElementForLink compilationUnit;
 
-  /**
-   * The index of this parameter within [enclosingElement]'s parameter list.
-   */
+  /// The index of this parameter within [enclosingElement]'s parameter list.
   final int _parameterIndex;
 
   @override
@@ -4098,10 +3989,8 @@
     return _typeParameterContext;
   }
 
-  /**
-   * Store the results of type inference for this parameter in
-   * [compilationUnit].
-   */
+  /// Store the results of type inference for this parameter in
+  /// [compilationUnit].
   void link(CompilationUnitElementInBuildUnit compilationUnit) {
     compilationUnit._storeLinkedType(
         unlinkedParam.inferredTypeSlot, _inferredType, _typeParameterContext);
@@ -4122,10 +4011,8 @@
   }
 }
 
-/**
- * Element representing the parameter of a synthetic setter for a variable
- * resynthesized during linking.
- */
+/// Element representing the parameter of a synthetic setter for a variable
+/// resynthesized during linking.
 class ParameterElementForLink_VariableSetter implements ParameterElementImpl {
   @override
   final PropertyAccessorElementForLink_Variable enclosingElement;
@@ -4178,24 +4065,18 @@
   noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
 }
 
-/**
- * Mixin used by elements that can have parameters.
- */
+/// Mixin used by elements that can have parameters.
 abstract class ParameterParentElementForLink implements Element {
   List<ParameterElement> _parameters;
 
-  /**
-   * Get the appropriate integer list to store in
-   * [EntityRef.implicitFunctionTypeIndices] to refer to this element.  For an
-   * element representing a function-typed parameter, this should return a
-   * non-empty list.  For an element representing an executable, this should
-   * return the empty list.
-   */
+  /// Get the appropriate integer list to store in
+  /// [EntityRef.implicitFunctionTypeIndices] to refer to this element.  For an
+  /// element representing a function-typed parameter, this should return a
+  /// non-empty list.  For an element representing an executable, this should
+  /// return the empty list.
   List<int> get implicitFunctionTypeIndices;
 
-  /**
-   * Get all the parameters of this element.
-   */
+  /// Get all the parameters of this element.
   List<ParameterElement> get parameters {
     if (_parameters == null) {
       List<UnlinkedParam> unlinkedParameters = this.unlinkedParameters;
@@ -4215,32 +4096,24 @@
     return _parameters;
   }
 
-  /**
-   * Get the innermost enclosing element that can declare type parameters (which
-   * may be [this], or may be a parent when there are function-typed
-   * parameters).
-   */
+  /// Get the innermost enclosing element that can declare type parameters
+  /// (which may be [this], or may be a parent when there are function-typed
+  /// parameters).
   TypeParameterizedElementMixin get typeParameterContext;
 
-  /**
-   * Get the list of unlinked parameters of this element.
-   */
+  /// Get the list of unlinked parameters of this element.
   List<UnlinkedParam> get unlinkedParameters;
 }
 
-/**
- * Element representing a getter or setter resynthesized from a summary during
- * linking.
- */
+/// Element representing a getter or setter resynthesized from a summary during
+/// linking.
 abstract class PropertyAccessorElementForLink
     implements PropertyAccessorElementImpl, ReferenceableElementForLink {
   void link(CompilationUnitElementInBuildUnit compilationUnit);
 }
 
-/**
- * Specialization of [PropertyAccessorElementForLink] for synthetic accessors
- * implied by the synthetic fields of an enum declaration.
- */
+/// Specialization of [PropertyAccessorElementForLink] for synthetic accessors
+/// implied by the synthetic fields of an enum declaration.
 class PropertyAccessorElementForLink_EnumField extends Object
     with ReferenceableElementForLink
     implements PropertyAccessorElementForLink {
@@ -4317,10 +4190,8 @@
   String toString() => '$enclosingElement.$name';
 }
 
-/**
- * Specialization of [PropertyAccessorElementForLink] for non-synthetic
- * accessors explicitly declared in the source code.
- */
+/// Specialization of [PropertyAccessorElementForLink] for non-synthetic
+/// accessors explicitly declared in the source code.
 class PropertyAccessorElementForLink_Executable
     extends ExecutableElementForLink_NonLocal
     with ReferenceableElementForLink
@@ -4378,10 +4249,8 @@
   String toString() => '$enclosingElement.$name';
 }
 
-/**
- * Specialization of [PropertyAccessorElementForLink] for synthetic accessors
- * implied by a field or variable declaration.
- */
+/// Specialization of [PropertyAccessorElementForLink] for synthetic accessors
+/// implied by a field or variable declaration.
 class PropertyAccessorElementForLink_Variable extends Object
     with ReferenceableElementForLink
     implements PropertyAccessorElementForLink {
@@ -4494,83 +4363,63 @@
   String toString() => '$enclosingElement.$name';
 }
 
-/**
- * Base class representing an element which can be the target of a reference.
- * When used as a mixin, implements the default behavior shared by most
- * elements.
- */
+/// Base class representing an element which can be the target of a reference.
+/// When used as a mixin, implements the default behavior shared by most
+/// elements.
 abstract class ReferenceableElementForLink implements Element {
-  /**
-   * If this element is a class reference, return it. Otherwise return `null`.
-   */
+  /// If this element is a class reference, return it. Otherwise return `null`.
   ClassElementForLink get asClass => null;
 
-  /**
-   * If this element can be used in a constructor invocation context,
-   * return the associated constructor (which may be `this` or some
-   * other element).  Otherwise return `null`.
-   */
+  /// If this element can be used in a constructor invocation context,
+  /// return the associated constructor (which may be `this` or some
+  /// other element).  Otherwise return `null`.
   ConstructorElementForLink get asConstructor => null;
 
-  /**
-   * If this element can be used in a getter context to refer to a
-   * constant variable, return the [ConstVariableNode] for the
-   * constant value.  Otherwise return `null`.
-   */
+  /// If this element can be used in a getter context to refer to a
+  /// constant variable, return the [ConstVariableNode] for the
+  /// constant value.  Otherwise return `null`.
   ConstVariableNode get asConstVariable => null;
 
-  /**
-   * Return the static type (possibly inferred) of the entity referred to by
-   * this element.
-   */
+  /// Return the static type (possibly inferred) of the entity referred to by
+  /// this element.
   DartType get asStaticType => DynamicTypeImpl.instance;
 
-  /**
-   * If this element can be used in a getter context as a type inference
-   * dependency, return the [TypeInferenceNode] for the inferred type.
-   * Otherwise return `null`.
-   */
+  /// If this element can be used in a getter context as a type inference
+  /// dependency, return the [TypeInferenceNode] for the inferred type.
+  /// Otherwise return `null`.
   TypeInferenceNode get asTypeInferenceNode => null;
 
   @override
   ElementLocation get location => new ElementLocationImpl.con1(this);
 
-  /**
-   * Return the type indicated by this element when it is used in a
-   * type instantiation context.  If this element can't legally be
-   * instantiated as a type, return the dynamic type.
-   *
-   * If the type is parameterized, [getTypeArgument] will be called to retrieve
-   * the type parameters.  It should return `null` for unspecified type
-   * parameters.
-   */
+  /// Return the type indicated by this element when it is used in a
+  /// type instantiation context.  If this element can't legally be
+  /// instantiated as a type, return the dynamic type.
+  ///
+  /// If the type is parameterized, [getTypeArgument] will be called to retrieve
+  /// the type parameters.  It should return `null` for unspecified type
+  /// parameters.
   DartType buildType(DartType getTypeArgument(int i),
           List<int> implicitFunctionTypeIndices) =>
       DynamicTypeImpl.instance;
 
-  /**
-   * If this element contains other named elements, return the
-   * contained element having the given [name].  If this element can't
-   * contain other named elements, or it doesn't contain an element
-   * with the given name, return the singleton of
-   * [UndefinedElementForLink].
-   */
+  /// If this element contains other named elements, return the
+  /// contained element having the given [name].  If this element can't
+  /// contain other named elements, or it doesn't contain an element
+  /// with the given name, return the singleton of
+  /// [UndefinedElementForLink].
   ReferenceableElementForLink getContainedName(String name) {
     // TODO(paulberry): handle references to `call` for function types.
     return UndefinedElementForLink.instance;
   }
 
-  /**
-   * If this element contains local functions, return the contained local
-   * function having the given [index].  If this element doesn't contain local
-   * functions, or the index is out of range, return `null`.
-   */
+  /// If this element contains local functions, return the contained local
+  /// function having the given [index].  If this element doesn't contain local
+  /// functions, or the index is out of range, return `null`.
   FunctionElementForLink_Local getLocalFunction(int index) => null;
 }
 
-/**
- * Element used for references to special types such as `void`.
- */
+/// Element used for references to special types such as `void`.
 class SpecialTypeElementForLink extends Object
     with ReferenceableElementForLink {
   final Linker linker;
@@ -4594,10 +4443,8 @@
   String toString() => type.toString();
 }
 
-/**
- * Element representing a synthetic variable resynthesized from a summary during
- * linking.
- */
+/// Element representing a synthetic variable resynthesized from a summary
+/// during linking.
 class SyntheticVariableElementForLink implements PropertyInducingElementImpl {
   PropertyAccessorElementForLink_Executable _getter;
   PropertyAccessorElementForLink_Executable _setter;
@@ -4621,9 +4468,7 @@
   noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
 }
 
-/**
- * Element representing a top-level function.
- */
+/// Element representing a top-level function.
 class TopLevelFunctionElementForLink extends ExecutableElementForLink_NonLocal
     with ReferenceableElementForLink
     implements FunctionElementImpl {
@@ -4658,15 +4503,13 @@
   String toString() => '$enclosingElement.$name';
 }
 
-/**
- * Element representing a top level variable resynthesized from a
- * summary during linking.
- */
+/// Element representing a top level variable resynthesized from a
+/// summary during linking.
 class TopLevelVariableElementForLink extends VariableElementForLink
     implements TopLevelVariableElement {
   TopLevelVariableElementForLink(CompilationUnitElementForLink enclosingElement,
-      UnlinkedVariable unlinkedVariable)
-      : super(unlinkedVariable, enclosingElement);
+      UnlinkedVariable unlinkedVariable, Expression initializerForInference)
+      : super(unlinkedVariable, enclosingElement, initializerForInference);
 
   @override
   CompilationUnitElementForLink get enclosingElement => compilationUnit;
@@ -4680,10 +4523,8 @@
   @override
   TypeParameterizedElementMixin get _typeParameterContext => null;
 
-  /**
-   * Store the results of type inference for this variable in
-   * [compilationUnit].
-   */
+  /// Store the results of type inference for this variable in
+  /// [compilationUnit].
   void link(CompilationUnitElementInBuildUnit compilationUnit) {
     if (hasImplicitType) {
       TypeInferenceNode typeInferenceNode = this._typeInferenceNode;
@@ -4698,10 +4539,8 @@
   }
 }
 
-/**
- * Specialization of [DependencyWalker] for performing type inference on static
- * and top level variables.
- */
+/// Specialization of [DependencyWalker] for performing type inference on static
+/// and top level variables.
 class TypeInferenceDependencyWalker
     extends DependencyWalker<TypeInferenceNode> {
   @override
@@ -4717,14 +4556,10 @@
   }
 }
 
-/**
- * Specialization of [Node] used to construct the type inference dependency
- * graph.
- */
+/// Specialization of [Node] used to construct the type inference dependency
+/// graph.
 class TypeInferenceNode extends Node<TypeInferenceNode> {
-  /**
-   * The [FunctionElementForLink_Local] to which this node refers.
-   */
+  /// The [FunctionElementForLink_Local] to which this node refers.
   final FunctionElementForLink_Local functionElement;
 
   TypeInferenceNode(this.functionElement);
@@ -4732,11 +4567,9 @@
   @override
   bool get isEvaluated => functionElement._hasTypeBeenInferred;
 
-  /**
-   * Collect the type inference dependencies in [unlinkedExecutable] (which
-   * should be interpreted relative to [compilationUnit]) and store them in
-   * [dependencies].
-   */
+  /// Collect the type inference dependencies in [unlinkedExecutable] (which
+  /// should be interpreted relative to [compilationUnit]) and store them in
+  /// [dependencies].
   void collectDependencies(
       List<TypeInferenceNode> dependencies,
       UnlinkedExecutable unlinkedExecutable,
@@ -5031,9 +4864,7 @@
   }
 }
 
-/**
- * Singleton element used for unresolved references.
- */
+/// Singleton element used for unresolved references.
 class UndefinedElementForLink extends Object with ReferenceableElementForLink {
   static final UndefinedElementForLink instance =
       new UndefinedElementForLink._();
@@ -5044,29 +4875,25 @@
   noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
 }
 
-/**
- * Element representing a top level variable resynthesized from a
- * summary during linking.
- */
+/// Element representing a top level variable resynthesized from a
+/// summary during linking.
 abstract class VariableElementForLink
     implements NonParameterVariableElementImpl, PropertyInducingElement {
-  /**
-   * The unlinked representation of the variable in the summary.
-   */
+  /// The unlinked representation of the variable in the summary.
   final UnlinkedVariable unlinkedVariable;
 
-  /**
-   * If this variable is declared `const` and the enclosing library is
-   * part of the build unit being linked, the variable's node in the
-   * constant evaluation dependency graph.  Otherwise `null`.
-   */
+  /// If non-null, the AST for the initializer expression; this is used for
+  /// inferring the expression type.
+  final Expression _initializerForInference;
+
+  /// If this variable is declared `const` and the enclosing library is
+  /// part of the build unit being linked, the variable's node in the
+  /// constant evaluation dependency graph.  Otherwise `null`.
   ConstNode _constNode;
 
-  /**
-   * If this variable has an initializer and an implicit type, and the enclosing
-   * library is part of the build unit being linked, the variable's node in the
-   * type inference dependency graph.  Otherwise `null`.
-   */
+  /// If this variable has an initializer and an implicit type, and the
+  /// enclosing library is part of the build unit being linked, the variable's
+  /// node in the type inference dependency graph.  Otherwise `null`.
   TypeInferenceNode _typeInferenceNode;
 
   FunctionElementForLink_Initializer _initializer;
@@ -5075,25 +4902,24 @@
   PropertyAccessorElementForLink_Variable _getter;
   PropertyAccessorElementForLink_Variable _setter;
 
-  /**
-   * The compilation unit in which this variable appears.
-   */
+  /// The compilation unit in which this variable appears.
   final CompilationUnitElementForLink compilationUnit;
 
-  VariableElementForLink(this.unlinkedVariable, this.compilationUnit) {
-    if (compilationUnit.isInBuildUnit &&
-        unlinkedVariable.initializer?.bodyExpr != null) {
+  VariableElementForLink(this.unlinkedVariable, this.compilationUnit,
+      this._initializerForInference) {
+    if (!compilationUnit.isInBuildUnit) return;
+    if (unlinkedVariable.initializer?.bodyExpr == null) {
+      if (_initializerForInference == null) return;
+    } else {
       _constNode = new ConstVariableNode(this);
-      if (unlinkedVariable.type == null) {
-        _typeInferenceNode = initializer.asTypeInferenceNode;
-      }
+    }
+    if (unlinkedVariable.type == null) {
+      _typeInferenceNode = initializer.asTypeInferenceNode;
     }
   }
 
-  /**
-   * If the variable has an explicitly declared return type, return it.
-   * Otherwise return `null`.
-   */
+  /// If the variable has an explicitly declared return type, return it.
+  /// Otherwise return `null`.
   DartType get declaredType {
     if (unlinkedVariable.type == null) {
       return null;
@@ -5116,10 +4942,8 @@
   @override
   String get identifier => unlinkedVariable.name;
 
-  /**
-   * Return the inferred type of the variable element.  Should only be called if
-   * no type was explicitly declared.
-   */
+  /// Return the inferred type of the variable element.  Should only be called
+  /// if no type was explicitly declared.
   DartType get inferredType {
     // We should only try to infer a type when none is explicitly declared.
     assert(unlinkedVariable.type == null);
@@ -5149,17 +4973,16 @@
     if (unlinkedVariable.initializer == null) {
       return null;
     } else {
-      return _initializer ??= new FunctionElementForLink_Initializer(this);
+      return _initializer ??= new FunctionElementForLink_Initializer(
+          this, _initializerForInference);
     }
   }
 
   @override
   bool get isConst => unlinkedVariable.isConst;
 
-  /**
-   * Return `true` if this variable is a field that was explicitly marked as
-   * being covariant (in the setter's parameter).
-   */
+  /// Return `true` if this variable is a field that was explicitly marked as
+  /// being covariant (in the setter's parameter).
   bool get isCovariant => unlinkedVariable.isCovariant;
 
   @override
@@ -5202,10 +5025,8 @@
     return _typeParameterContext;
   }
 
-  /**
-   * The context in which type parameters should be interpreted, or `null` if
-   * there are no type parameters in scope.
-   */
+  /// The context in which type parameters should be interpreted, or `null` if
+  /// there are no type parameters in scope.
   TypeParameterizedElementMixin get _typeParameterContext;
 
   @override
diff --git a/pkg/analyzer/lib/src/summary/one_phase.dart b/pkg/analyzer/lib/src/summary/one_phase.dart
index 0775161..3ce0c90 100644
--- a/pkg/analyzer/lib/src/summary/one_phase.dart
+++ b/pkg/analyzer/lib/src/summary/one_phase.dart
@@ -30,7 +30,8 @@
     bool allowMissingFiles) {
   var uriToUnlinked = <String, UnlinkedUnitBuilder>{};
   uriToUnit.forEach((uri, compilationUnit) {
-    var unlinkedUnit = serializeAstUnlinked(compilationUnit);
+    var unlinkedUnit =
+        serializeAstUnlinked(compilationUnit, serializeInferrableFields: false);
     uriToUnlinked[uri] = unlinkedUnit;
     assembler.addUnlinkedUnitViaUri(uri, unlinkedUnit);
   });
@@ -55,10 +56,21 @@
     return unlinkedUnit;
   }
 
+  CompilationUnit getAst(String absoluteUri) {
+    if (absoluteUri == null) {
+      return null;
+    }
+    var compilationUnit = uriToUnit[absoluteUri];
+    if (compilationUnit == null && !allowMissingFiles) {
+      throw new StateError('Missing unit $absoluteUri');
+    }
+    return compilationUnit;
+  }
+
   // TODO(paulberry): is this bad?  Are we passing parts to link that we
   // shouldn't?
-  var linkedLibraries = link(
-      uriToUnlinked.keys.toSet(), getDependency, getUnit, getDeclaredVariable);
+  var linkedLibraries = link(uriToUnlinked.keys.toSet(), getDependency, getUnit,
+      getDeclaredVariable, getAst);
 
   linkedLibraries.forEach(assembler.addLinkedLibrary);
 }
diff --git a/pkg/analyzer/lib/src/summary/summarize_ast.dart b/pkg/analyzer/lib/src/summary/summarize_ast.dart
index 32809c8..90c0d12 100644
--- a/pkg/analyzer/lib/src/summary/summarize_ast.dart
+++ b/pkg/analyzer/lib/src/summary/summarize_ast.dart
@@ -7,39 +7,36 @@
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/ast/token.dart';
 import 'package:analyzer/dart/ast/visitor.dart';
-import 'package:analyzer/dart/element/type.dart' show DartType;
+import 'package:analyzer/src/dart/ast/mixin_super_invoked_names.dart';
 import 'package:analyzer/src/summary/format.dart';
 import 'package:analyzer/src/summary/idl.dart';
 import 'package:analyzer/src/summary/public_namespace_computer.dart';
 import 'package:analyzer/src/summary/summarize_const_expr.dart';
 import 'package:front_end/src/base/api_signature.dart';
 
-/**
- * Serialize all the declarations in [compilationUnit] to an unlinked summary.
- */
-UnlinkedUnitBuilder serializeAstUnlinked(CompilationUnit compilationUnit) {
-  return new _SummarizeAstVisitor().serializeCompilationUnit(compilationUnit);
+/// Serialize all the declarations in [compilationUnit] to an unlinked summary.
+///
+/// [serializeInferrableFields] indicates whether field initializers and closure
+/// bodies should be serialized to facilitate type inference.
+UnlinkedUnitBuilder serializeAstUnlinked(CompilationUnit compilationUnit,
+    {bool serializeInferrableFields: true}) {
+  return new _SummarizeAstVisitor(serializeInferrableFields)
+      .serializeCompilationUnit(compilationUnit);
 }
 
-/**
- * Instances of this class keep track of intermediate state during
- * serialization of a single constant [Expression].
- */
+/// Instances of this class keep track of intermediate state during
+/// serialization of a single constant [Expression].
 class _ConstExprSerializer extends AbstractConstExprSerializer {
   final _SummarizeAstVisitor visitor;
 
-  /**
-   * If the expression being serialized can contain closures, map whose
-   * keys are the offsets of local function nodes representing those closures,
-   * and whose values are indices of those local functions relative to their
-   * siblings.
-   */
+  /// If the expression being serialized can contain closures, map whose
+  /// keys are the offsets of local function nodes representing those closures,
+  /// and whose values are indices of those local functions relative to their
+  /// siblings.
   final Map<int, int> localClosureIndexMap;
 
-  /**
-   * If the expression being serialized appears inside a function body, the names
-   * of parameters that are in scope.  Otherwise `null`.
-   */
+  /// If the expression being serialized appears inside a function body, the
+  /// names of parameters that are in scope.  Otherwise `null`.
   final Set<String> parameterNames;
 
   _ConstExprSerializer(bool forConst, this.visitor, this.localClosureIndexMap,
@@ -56,11 +53,10 @@
     Identifier name = annotation.name;
     EntityRefBuilder constructor;
     if (name is PrefixedIdentifier && annotation.constructorName == null) {
-      constructor =
-          serializeConstructorRef(null, name.prefix, null, name.identifier);
+      constructor = serializeConstructorRef(name.prefix, null, name.identifier);
     } else {
       constructor = serializeConstructorRef(
-          null, annotation.name, null, annotation.constructorName);
+          annotation.name, null, annotation.constructorName);
     }
     if (annotation.arguments == null) {
       references.add(constructor);
@@ -71,10 +67,9 @@
   }
 
   @override
-  EntityRefBuilder serializeConstructorRef(DartType type, Identifier typeName,
+  EntityRefBuilder serializeConstructorRef(Identifier typeName,
       TypeArgumentList typeArguments, SimpleIdentifier name) {
-    EntityRefBuilder typeBuilder =
-        serializeTypeName(type, typeName, typeArguments);
+    EntityRefBuilder typeBuilder = serializeTypeName(typeName, typeArguments);
     if (name == null) {
       return typeBuilder;
     } else {
@@ -148,238 +143,176 @@
 
   @override
   EntityRefBuilder serializeTypeName(
-      DartType type, Identifier name, TypeArgumentList arguments) {
+      Identifier name, TypeArgumentList arguments) {
     return visitor.serializeTypeName(name, arguments);
   }
 }
 
-/**
- * A [_Scope] represents a set of name/value pairs defined locally within a
- * limited span of a compilation unit.  (Note that the spec also uses the term
- * "scope" to refer to the set of names defined at top level within a
- * compilation unit, but we do not use [_Scope] for that purpose).
- */
+/// A [_Scope] represents a set of name/value pairs defined locally within a
+/// limited span of a compilation unit.  (Note that the spec also uses the term
+/// "scope" to refer to the set of names defined at top level within a
+/// compilation unit, but we do not use [_Scope] for that purpose).
 class _Scope {
-  /**
-   * Names defined in this scope, and their meanings.
-   */
+  /// Names defined in this scope, and their meanings.
   Map<String, _ScopedEntity> _definedNames = <String, _ScopedEntity>{};
 
-  /**
-   * Look up the meaning associated with the given [name], and return it.  If
-   * [name] is not defined in this scope, return `null`.
-   */
+  /// Look up the meaning associated with the given [name], and return it.  If
+  /// [name] is not defined in this scope, return `null`.
   _ScopedEntity operator [](String name) => _definedNames[name];
 
-  /**
-   * Let the given [name] refer to [entity] within this scope.
-   */
+  /// Let the given [name] refer to [entity] within this scope.
   void operator []=(String name, _ScopedEntity entity) {
     _definedNames[name] = entity;
   }
 }
 
-/**
- * A [_ScopedClassMember] is a [_ScopedEntity] refers to a member of a class.
- */
+/// A [_ScopedClassMember] is a [_ScopedEntity] refers to a member of a class.
 class _ScopedClassMember extends _ScopedEntity {
-  /**
-   * The name of the class.
-   */
+  /// The name of the class.
   final String className;
 
   _ScopedClassMember(this.className);
 }
 
-/**
- * Base class for entities that can live inside a scope.
- */
+/// Base class for entities that can live inside a scope.
 abstract class _ScopedEntity {}
 
-/**
- * A [_ScopedTypeParameter] is a [_ScopedEntity] that refers to a type
- * parameter of a class, typedef, or executable.
- */
+/// A [_ScopedTypeParameter] is a [_ScopedEntity] that refers to a type
+/// parameter of a class, typedef, or executable.
 class _ScopedTypeParameter extends _ScopedEntity {
-  /**
-   * Index of the type parameter within this scope.  Since summaries use De
-   * Bruijn indices to refer to type parameters, which count upwards from the
-   * innermost bound name, the last type parameter in the scope has an index of
-   * 1, and each preceding type parameter has the next higher index.
-   */
+  /// Index of the type parameter within this scope.  Since summaries use De
+  /// Bruijn indices to refer to type parameters, which count upwards from the
+  /// innermost bound name, the last type parameter in the scope has an index of
+  /// 1, and each preceding type parameter has the next higher index.
   final int index;
 
   _ScopedTypeParameter(this.index);
 }
 
-/**
- * Visitor used to create a summary from an AST.
- */
+/// Visitor used to create a summary from an AST.
 class _SummarizeAstVisitor extends RecursiveAstVisitor {
-  /**
-   * List of objects which should be written to [UnlinkedUnit.classes].
-   */
+  /// Indicates whether non-const field initializers and closure bodies should
+  /// be serialized to facilitate type inference.
+  ///
+  /// For one-phase summary generation, the only field initializers that need to
+  /// be serialized are those involved in constants, since type inference is
+  /// performed using the AST representation.
+  final bool _serializeInferrableFields;
+
+  /// List of objects which should be written to [UnlinkedUnit.classes].
   final List<UnlinkedClassBuilder> classes = <UnlinkedClassBuilder>[];
 
-  /**
-   * List of objects which should be written to [UnlinkedUnit.enums].
-   */
+  /// List of objects which should be written to [UnlinkedUnit.enums].
   final List<UnlinkedEnumBuilder> enums = <UnlinkedEnumBuilder>[];
 
-  /**
-   * List of objects which should be written to [UnlinkedUnit.executables],
-   * [UnlinkedClass.executables] or [UnlinkedExecutable.localFunctions].
-   */
+  /// List of objects which should be written to [UnlinkedUnit.executables],
+  /// [UnlinkedClass.executables] or [UnlinkedExecutable.localFunctions].
   List<UnlinkedExecutableBuilder> executables = <UnlinkedExecutableBuilder>[];
 
-  /**
-   * List of objects which should be written to [UnlinkedUnit.exports].
-   */
+  /// List of objects which should be written to [UnlinkedUnit.exports].
   final List<UnlinkedExportNonPublicBuilder> exports =
       <UnlinkedExportNonPublicBuilder>[];
 
-  /**
-   * List of objects which should be written to [UnlinkedUnit.mixins].
-   */
+  /// List of objects which should be written to [UnlinkedUnit.mixins].
   final List<UnlinkedClassBuilder> mixins = <UnlinkedClassBuilder>[];
 
-  /**
-   * List of objects which should be written to [UnlinkedUnit.parts].
-   */
+  /// List of names of methods, getters, setters, and operators that are
+  /// super-invoked in the current mixin declaration.
+  Set<String> mixinSuperInvokedNames;
+
+  /// List of objects which should be written to [UnlinkedUnit.parts].
   final List<UnlinkedPartBuilder> parts = <UnlinkedPartBuilder>[];
 
-  /**
-   * List of objects which should be written to [UnlinkedUnit.typedefs].
-   */
+  /// List of objects which should be written to [UnlinkedUnit.typedefs].
   final List<UnlinkedTypedefBuilder> typedefs = <UnlinkedTypedefBuilder>[];
 
-  /**
-   * List of objects which should be written to [UnlinkedUnit.variables] or
-   * [UnlinkedClass.fields].
-   */
+  /// List of objects which should be written to [UnlinkedUnit.variables] or
+  /// [UnlinkedClass.fields].
   List<UnlinkedVariableBuilder> variables = <UnlinkedVariableBuilder>[];
 
-  /**
-   * The unlinked portion of the "imports table".  This is the list of objects
-   * which should be written to [UnlinkedUnit.imports].
-   */
+  /// The unlinked portion of the "imports table".  This is the list of objects
+  /// which should be written to [UnlinkedUnit.imports].
   final List<UnlinkedImportBuilder> unlinkedImports = <UnlinkedImportBuilder>[];
 
-  /**
-   * The unlinked portion of the "references table".  This is the list of
-   * objects which should be written to [UnlinkedUnit.references].
-   */
+  /// The unlinked portion of the "references table".  This is the list of
+  /// objects which should be written to [UnlinkedUnit.references].
   final List<UnlinkedReferenceBuilder> unlinkedReferences =
       <UnlinkedReferenceBuilder>[new UnlinkedReferenceBuilder()];
 
-  /**
-   * List of [_Scope]s currently in effect.  This is used to resolve type names
-   * to type parameters within classes, typedefs, and executables, as well as
-   * references to class members.
-   */
+  /// List of [_Scope]s currently in effect.  This is used to resolve type names
+  /// to type parameters within classes, typedefs, and executables, as well as
+  /// references to class members.
   final List<_Scope> scopes = <_Scope>[];
 
-  /**
-   * True if 'dart:core' has been explicitly imported.
-   */
+  /// True if 'dart:core' has been explicitly imported.
   bool hasCoreBeenImported = false;
 
-  /**
-   * Names referenced by this compilation unit.  Structured as a map from
-   * prefix index to (map from name to reference table index), where "prefix
-   * index" means the index into [UnlinkedUnit.references] of the prefix (or
-   * `null` if there is no prefix), and "reference table index" means the index
-   * into [UnlinkedUnit.references] for the name itself.
-   */
+  /// Names referenced by this compilation unit.  Structured as a map from
+  /// prefix index to (map from name to reference table index), where "prefix
+  /// index" means the index into [UnlinkedUnit.references] of the prefix (or
+  /// `null` if there is no prefix), and "reference table index" means the index
+  /// into [UnlinkedUnit.references] for the name itself.
   final Map<int, Map<String, int>> nameToReference = <int, Map<String, int>>{};
 
-  /**
-   * True if the 'dart:core' library is been summarized.
-   */
+  /// True if the 'dart:core' library is been summarized.
   bool isCoreLibrary = false;
 
-  /**
-   * True is a [PartOfDirective] was found, so the unit is a part.
-   */
+  /// True is a [PartOfDirective] was found, so the unit is a part.
   bool isPartOf = false;
 
-  /**
-   * If the library has a library directive, the library name derived from it.
-   * Otherwise `null`.
-   */
+  /// If the library has a library directive, the library name derived from it.
+  /// Otherwise `null`.
   String libraryName;
 
-  /**
-   * If the library has a library directive, the offset of the library name.
-   * Otherwise `null`.
-   */
+  /// If the library has a library directive, the offset of the library name.
+  /// Otherwise `null`.
   int libraryNameOffset;
 
-  /**
-   * If the library has a library directive, the length of the library name, as
-   * it appears in the source file.  Otherwise `null`.
-   */
+  /// If the library has a library directive, the length of the library name, as
+  /// it appears in the source file.  Otherwise `null`.
   int libraryNameLength;
 
-  /**
-   * If the library has a library directive, the documentation comment for it
-   * (if any).  Otherwise `null`.
-   */
+  /// If the library has a library directive, the documentation comment for it
+  /// (if any).  Otherwise `null`.
   UnlinkedDocumentationCommentBuilder libraryDocumentationComment;
 
-  /**
-   * If the library has a library directive, the annotations for it (if any).
-   * Otherwise `null`.
-   */
+  /// If the library has a library directive, the annotations for it (if any).
+  /// Otherwise `null`.
   List<UnlinkedExpr> libraryAnnotations = const <UnlinkedExprBuilder>[];
 
-  /**
-   * The number of slot ids which have been assigned to this compilation unit.
-   */
+  /// The number of slot ids which have been assigned to this compilation unit.
   int numSlots = 0;
 
-  /**
-   * The [Block] that is being visited now, or `null` for non-local contexts.
-   */
+  /// The [Block] that is being visited now, or `null` for non-local contexts.
   Block enclosingBlock = null;
 
-  /**
-   * If an expression is being serialized which can contain closures, map whose
-   * keys are the offsets of local function nodes representing those closures,
-   * and whose values are indices of those local functions relative to their
-   * siblings.
-   */
+  /// If an expression is being serialized which can contain closures, map whose
+  /// keys are the offsets of local function nodes representing those closures,
+  /// and whose values are indices of those local functions relative to their
+  /// siblings.
   Map<int, int> _localClosureIndexMap;
 
-  /**
-   * Indicates whether closure function bodies should be serialized.  This flag
-   * is set while visiting the bodies of initializer expressions that will be
-   * needed by type inference.
-   */
+  /// Indicates whether closure function bodies should be serialized.  This flag
+  /// is set while visiting the bodies of initializer expressions that will be
+  /// needed by type inference.
   bool _serializeClosureBodyExprs = false;
 
-  /**
-   * If a closure function body is being serialized, the set of closure
-   * parameter names which are currently in scope.  Otherwise `null`.
-   */
+  /// If a closure function body is being serialized, the set of closure
+  /// parameter names which are currently in scope.  Otherwise `null`.
   Set<String> _parameterNames;
 
-  /**
-   * Indicates whether parameters found during visitors might inherit
-   * covariance.
-   */
+  /// Indicates whether parameters found during visitors might inherit
+  /// covariance.
   bool _parametersMayInheritCovariance = false;
 
-  /**
-   * Create a slot id for storing a propagated or inferred type or const cycle
-   * info.
-   */
+  _SummarizeAstVisitor(this._serializeInferrableFields);
+
+  /// Create a slot id for storing a propagated or inferred type or const cycle
+  /// info.
   int assignSlot() => ++numSlots;
 
-  /**
-   * Build a [_Scope] object containing the names defined within the body of a
-   * class declaration.
-   */
+  /// Build a [_Scope] object containing the names defined within the body of a
+  /// class declaration.
   _Scope buildClassMemberScope(
       String className, NodeList<ClassMember> members) {
     _Scope scope = new _Scope();
@@ -403,10 +336,8 @@
     return scope;
   }
 
-  /**
-   * Serialize the given list of [annotations].  If there are no annotations,
-   * the empty list is returned.
-   */
+  /// Serialize the given list of [annotations].  If there are no annotations,
+  /// the empty list is returned.
   List<UnlinkedExprBuilder> serializeAnnotations(
       NodeList<Annotation> annotations) {
     if (annotations == null || annotations.isEmpty) {
@@ -427,10 +358,8 @@
     }).toList();
   }
 
-  /**
-   * Serialize a [ClassDeclaration] or [ClassTypeAlias] into an [UnlinkedClass]
-   * and store the result in [classes].
-   */
+  /// Serialize a [ClassDeclaration] or [ClassTypeAlias] into an [UnlinkedClass]
+  /// and store the result in [classes].
   void serializeClass(
       AstNode node,
       Token abstractKeyword,
@@ -488,16 +417,12 @@
     variables = oldVariables;
   }
 
-  /**
-   * Create a [CodeRangeBuilder] for the given [node].
-   */
+  /// Create a [CodeRangeBuilder] for the given [node].
   CodeRangeBuilder serializeCodeRange(AstNode node) {
     return new CodeRangeBuilder(offset: node.offset, length: node.length);
   }
 
-  /**
-   * Serialize a [Combinator] into an [UnlinkedCombinator].
-   */
+  /// Serialize a [Combinator] into an [UnlinkedCombinator].
   UnlinkedCombinatorBuilder serializeCombinator(Combinator combinator) {
     UnlinkedCombinatorBuilder b = new UnlinkedCombinatorBuilder();
     if (combinator is ShowCombinator) {
@@ -515,9 +440,7 @@
     return b;
   }
 
-  /**
-   * Main entry point for serializing an AST.
-   */
+  /// Main entry point for serializing an AST.
   UnlinkedUnitBuilder serializeCompilationUnit(
       CompilationUnit compilationUnit) {
     compilationUnit.directives.accept(this);
@@ -549,9 +472,7 @@
     return b;
   }
 
-  /**
-   * Serialize the given [expression], creating an [UnlinkedExprBuilder].
-   */
+  /// Serialize the given [expression], creating an [UnlinkedExprBuilder].
   UnlinkedExprBuilder serializeConstExpr(
       bool forConst, Map<int, int> localClosureIndexMap, Expression expression,
       [Set<String> parameterNames]) {
@@ -561,9 +482,7 @@
     return serializer.toBuilder();
   }
 
-  /**
-   * Serialize a [Comment] node into an [UnlinkedDocumentationComment] object.
-   */
+  /// Serialize a [Comment] node into an [UnlinkedDocumentationComment] object.
   UnlinkedDocumentationCommentBuilder serializeDocumentation(
       Comment documentationComment) {
     if (documentationComment == null) {
@@ -576,18 +495,14 @@
     return new UnlinkedDocumentationCommentBuilder(text: text);
   }
 
-  /**
-   * Return an entity reference builder representing the type 'dynamic'.
-   */
+  /// Return an entity reference builder representing the type 'dynamic'.
   EntityRefBuilder serializeDynamic() {
     EntityRefBuilder builder = new EntityRefBuilder();
     builder.reference = serializeReference(null, 'dynamic');
     return builder;
   }
 
-  /**
-   * Serialize an [EnumConstantDeclaration] into an [UnlinkedEnumValue].
-   */
+  /// Serialize an [EnumConstantDeclaration] into an [UnlinkedEnumValue].
   UnlinkedEnumValueBuilder serializeEnumConstantDeclaration(
       EnumConstantDeclaration node) {
     return new UnlinkedEnumValueBuilder(
@@ -597,13 +512,11 @@
         nameOffset: node.name.offset);
   }
 
-  /**
-   * Serialize a [FunctionDeclaration] or [MethodDeclaration] into an
-   * [UnlinkedExecutable].
-   *
-   * If [serializeBodyExpr] is `true`, then the function definition is stored
-   * in [UnlinkedExecutableBuilder.bodyExpr].
-   */
+  /// Serialize a [FunctionDeclaration] or [MethodDeclaration] into an
+  /// [UnlinkedExecutable].
+  ///
+  /// If [serializeBodyExpr] is `true`, then the function definition is stored
+  /// in [UnlinkedExecutableBuilder.bodyExpr].
   UnlinkedExecutableBuilder serializeExecutable(
       AstNode node,
       String name,
@@ -680,28 +593,32 @@
     }
     serializeFunctionBody(
         b, null, body, serializeBodyExpr, serializeBody, false);
+
+    if (mixinSuperInvokedNames != null) {
+      body?.accept(new MixinSuperInvokedNamesCollector(mixinSuperInvokedNames));
+    }
+
     _parameterNames = oldParameterNames;
     scopes.removeLast();
     assert(scopes.length == oldScopesLength);
     return b;
   }
 
-  /**
-   * Record local functions and variables into the given executable. The given
-   * [body] is usually an actual [FunctionBody], but may be an [Expression]
-   * when we process a synthetic variable initializer function.
-   *
-   * If [initializers] is non-`null`, closures occurring inside the initializers
-   * are serialized first.
-   *
-   * If [serializeBodyExpr] is `true`, then the function definition is stored
-   * in [UnlinkedExecutableBuilder.bodyExpr], and closures occurring inside
-   * [initializers] and [body] have their function bodies serialized as well.
-   *
-   * The return value is a map whose keys are the offsets of local function
-   * nodes representing closures inside [initializers] and [body], and whose
-   * values are the indices of those local functions relative to their siblings.
-   */
+  /// Record local functions and variables into the given executable. The given
+  /// [body] is usually an actual [FunctionBody], but may be an [Expression]
+  /// when we process a synthetic variable initializer function.
+  ///
+  /// If [initializers] is non-`null`, closures occurring inside the
+  /// initializers are serialized first.
+  ///
+  /// If [serializeBodyExpr] is `true`, then the function definition is stored
+  /// in [UnlinkedExecutableBuilder.bodyExpr], and closures occurring inside
+  /// [initializers] and [body] have their function bodies serialized as well.
+  ///
+  /// The return value is a map whose keys are the offsets of local function
+  /// nodes representing closures inside [initializers] and [body], and whose
+  /// values are the indices of those local functions relative to their
+  /// siblings.
   Map<int, int> serializeFunctionBody(
       UnlinkedExecutableBuilder b,
       List<ConstructorInitializer> initializers,
@@ -722,7 +639,8 @@
     bool oldSerializeClosureBodyExprs = _serializeClosureBodyExprs;
     executables = <UnlinkedExecutableBuilder>[];
     _localClosureIndexMap = <int, int>{};
-    _serializeClosureBodyExprs = serializeBodyExpr;
+    _serializeClosureBodyExprs =
+        serializeBodyExpr && _serializeInferrableFields;
     if (initializers != null) {
       for (ConstructorInitializer initializer in initializers) {
         initializer.accept(this);
@@ -750,10 +668,8 @@
     return localClosureIndexMap;
   }
 
-  /**
-   * Serialize the return type and parameters of a function-typed formal
-   * parameter and store them in [b].
-   */
+  /// Serialize the return type and parameters of a function-typed formal
+  /// parameter and store them in [b].
   void serializeFunctionTypedParameterDetails(UnlinkedParamBuilder b,
       TypeAnnotation returnType, FormalParameterList parameters) {
     EntityRefBuilder serializedReturnType = serializeType(returnType);
@@ -768,9 +684,7 @@
     _parametersMayInheritCovariance = oldMayInheritCovariance;
   }
 
-  /**
-   * Serialize a generic function type.
-   */
+  /// Serialize a generic function type.
   EntityRefBuilder serializeGenericFunctionType(GenericFunctionType node) {
     _TypeParameterScope typeParameterScope = new _TypeParameterScope();
     scopes.add(typeParameterScope);
@@ -788,13 +702,11 @@
     return b;
   }
 
-  /**
-   * If the given [expression] is not `null`, serialize it as an
-   * [UnlinkedExecutableBuilder], otherwise return `null`.
-   *
-   * If [serializeBodyExpr] is `true`, then the initializer expression is stored
-   * in [UnlinkedExecutableBuilder.bodyExpr].
-   */
+  /// If the given [expression] is not `null`, serialize it as an
+  /// [UnlinkedExecutableBuilder], otherwise return `null`.
+  ///
+  /// If [serializeBodyExpr] is `true`, then the initializer expression is
+  /// stored in [UnlinkedExecutableBuilder.bodyExpr].
   UnlinkedExecutableBuilder serializeInitializerFunction(
       Expression expression, bool serializeBodyExpr, bool forConst) {
     if (expression == null) {
@@ -808,9 +720,7 @@
     return initializer;
   }
 
-  /**
-   * Serialize a type name that appears in a "with" clause to an [EntityRef].
-   */
+  /// Serialize a type name that appears in a "with" clause to an [EntityRef].
   EntityRefBuilder serializeMixedInType(TypeAnnotation node) {
     var builder = serializeType(node);
     if (builder != null && builder.typeArguments.isEmpty) {
@@ -821,10 +731,8 @@
     return builder;
   }
 
-  /**
-   * Serialize a [MixinDeclaration] into an [UnlinkedClass]
-   * and store the result in [mixins].
-   */
+  /// Serialize a [MixinDeclaration] into an [UnlinkedClass]
+  /// and store the result in [mixins].
   void serializeMixin(
       AstNode node,
       String name,
@@ -835,13 +743,18 @@
       NodeList<ClassMember> members,
       Comment documentationComment,
       NodeList<Annotation> annotations) {
-    int oldScopesLength = scopes.length;
     List<UnlinkedExecutableBuilder> oldExecutables = executables;
     executables = <UnlinkedExecutableBuilder>[];
+
+    mixinSuperInvokedNames = new Set<String>();
+
     List<UnlinkedVariableBuilder> oldVariables = variables;
     variables = <UnlinkedVariableBuilder>[];
+
+    int oldScopesLength = scopes.length;
     _TypeParameterScope typeParameterScope = new _TypeParameterScope();
     scopes.add(typeParameterScope);
+
     UnlinkedClassBuilder b = new UnlinkedClassBuilder();
     b.name = name;
     b.nameOffset = nameOffset;
@@ -863,20 +776,22 @@
     }
     b.executables = executables;
     b.fields = variables;
+    b.superInvokedNames = mixinSuperInvokedNames.toList();
     b.documentationComment = serializeDocumentation(documentationComment);
     b.annotations = serializeAnnotations(annotations);
     b.codeRange = serializeCodeRange(node);
     mixins.add(b);
+
     scopes.removeLast();
     assert(scopes.length == oldScopesLength);
+
     executables = oldExecutables;
+    mixinSuperInvokedNames = null;
     variables = oldVariables;
   }
 
-  /**
-   * Serialize a [FieldFormalParameter], [FunctionTypedFormalParameter], or
-   * [SimpleFormalParameter] into an [UnlinkedParam].
-   */
+  /// Serialize a [FieldFormalParameter], [FunctionTypedFormalParameter], or
+  /// [SimpleFormalParameter] into an [UnlinkedParam].
   UnlinkedParamBuilder serializeParameter(NormalFormalParameter node) {
     UnlinkedParamBuilder b = new UnlinkedParamBuilder();
     b.name = node.identifier?.name;
@@ -901,12 +816,10 @@
     return b;
   }
 
-  /**
-   * Serialize a reference to a top level name declared elsewhere, by adding an
-   * entry to the references table if necessary.  If [prefixIndex] is not null,
-   * the reference is associated with the prefix having the given index in the
-   * references table.
-   */
+  /// Serialize a reference to a top level name declared elsewhere, by adding an
+  /// entry to the references table if necessary.  If [prefixIndex] is not null,
+  /// the reference is associated with the prefix having the given index in the
+  /// references table.
   int serializeReference(int prefixIndex, String name) => nameToReference
           .putIfAbsent(prefixIndex, () => <String, int>{})
           .putIfAbsent(name, () {
@@ -916,12 +829,10 @@
         return index;
       });
 
-  /**
-   * Serialize a reference to a name declared either at top level or in a
-   * nested scope.
-   *
-   * References to type parameters are returned as negative numbers.
-   */
+  /// Serialize a reference to a name declared either at top level or in a
+  /// nested scope.
+  ///
+  /// References to type parameters are returned as negative numbers.
   int serializeSimpleReference(String name) {
     int indexOffset = 0;
     for (int i = scopes.length - 1; i >= 0; i--) {
@@ -943,12 +854,10 @@
     return serializeReference(null, name);
   }
 
-  /**
-   * Serialize a type name (which might be defined in a nested scope, at top
-   * level within this library, or at top level within an imported library) to
-   * a [EntityRef].  Note that this method does the right thing if the
-   * name doesn't refer to an entity other than a type (e.g. a class member).
-   */
+  /// Serialize a type name (which might be defined in a nested scope, at top
+  /// level within this library, or at top level within an imported library) to
+  /// a [EntityRef].  Note that this method does the right thing if the
+  /// name doesn't refer to an entity other than a type (e.g. a class member).
   EntityRefBuilder serializeType(TypeAnnotation node) {
     if (node is TypeName) {
       return serializeTypeName(node?.name, node?.typeArguments);
@@ -960,12 +869,10 @@
     return null;
   }
 
-  /**
-   * Serialize a type name (which might be defined in a nested scope, at top
-   * level within this library, or at top level within an imported library) to
-   * a [EntityRef].  Note that this method does the right thing if the
-   * name doesn't refer to an entity other than a type (e.g. a class member).
-   */
+  /// Serialize a type name (which might be defined in a nested scope, at top
+  /// level within this library, or at top level within an imported library) to
+  /// a [EntityRef].  Note that this method does the right thing if the
+  /// name doesn't refer to an entity other than a type (e.g. a class member).
   EntityRefBuilder serializeTypeName(
       Identifier identifier, TypeArgumentList typeArguments) {
     if (identifier == null) {
@@ -1017,10 +924,8 @@
     }
   }
 
-  /**
-   * Serialize the given [typeParameters] into a list of [UnlinkedTypeParam]s,
-   * and also store them in [typeParameterScope].
-   */
+  /// Serialize the given [typeParameters] into a list of [UnlinkedTypeParam]s,
+  /// and also store them in [typeParameterScope].
   List<UnlinkedTypeParamBuilder> serializeTypeParameters(
       TypeParameterList typeParameters,
       _TypeParameterScope typeParameterScope) {
@@ -1035,10 +940,8 @@
     return const <UnlinkedTypeParamBuilder>[];
   }
 
-  /**
-   * Serialize the given [variables] into [UnlinkedVariable]s, and store them
-   * in [this.variables].
-   */
+  /// Serialize the given [variables] into [UnlinkedVariable]s, and store them
+  /// in [this.variables].
   void serializeVariables(
       VariableDeclarationList variables,
       bool isDeclaredStatic,
@@ -1069,7 +972,7 @@
 
       bool serializeBodyExpr = variable.isConst ||
           variable.isFinal && isField && !isDeclaredStatic ||
-          variables.type == null;
+          _serializeInferrableFields && variables.type == null;
       b.initializer = serializeInitializerFunction(
           variable.initializer, serializeBodyExpr, b.isConst);
       if (isField && !isDeclaredStatic && !variables.isFinal) {
@@ -1157,8 +1060,8 @@
         Map<int, int> localClosureIndexMap = null;
         b.redirectedConstructor =
             new _ConstExprSerializer(true, this, localClosureIndexMap, null)
-                .serializeConstructorRef(null, typeName.name,
-                    typeName.typeArguments, node.redirectedConstructor.name);
+                .serializeConstructorRef(typeName.name, typeName.typeArguments,
+                    node.redirectedConstructor.name);
       }
     } else {
       for (ConstructorInitializer initializer in node.initializers) {
@@ -1470,9 +1373,7 @@
     // TODO(scheglov) Remove when we stop serializing local functions.
   }
 
-  /**
-   * Compute the API signature of the unit and record it.
-   */
+  /// Compute the API signature of the unit and record it.
   static void _computeApiSignature(UnlinkedUnitBuilder b) {
     ApiSignature apiSignature = new ApiSignature();
     b.collectApiSignature(apiSignature);
@@ -1480,13 +1381,9 @@
   }
 }
 
-/**
- * A [_TypeParameterScope] is a [_Scope] which defines [_ScopedTypeParameter]s.
- */
+/// A [_TypeParameterScope] is a [_Scope] which defines [_ScopedTypeParameter]s.
 class _TypeParameterScope extends _Scope {
-  /**
-   * Get the number of [_ScopedTypeParameter]s defined in this
-   * [_TypeParameterScope].
-   */
+  /// Get the number of [_ScopedTypeParameter]s defined in this
+  /// [_TypeParameterScope].
   int get length => _definedNames.length;
 }
diff --git a/pkg/analyzer/lib/src/summary/summarize_const_expr.dart b/pkg/analyzer/lib/src/summary/summarize_const_expr.dart
index 8ac5f4f..40b9f9c 100644
--- a/pkg/analyzer/lib/src/summary/summarize_const_expr.dart
+++ b/pkg/analyzer/lib/src/summary/summarize_const_expr.dart
@@ -4,13 +4,10 @@
 
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/ast/token.dart';
-import 'package:analyzer/dart/element/type.dart' show DartType;
 import 'package:analyzer/src/summary/format.dart';
 import 'package:analyzer/src/summary/idl.dart';
 
-/**
- * Serialize the given constructor initializer [node].
- */
+/// Serialize the given constructor initializer [node].
 UnlinkedConstructorInitializerBuilder serializeConstructorInitializer(
     ConstructorInitializer node,
     UnlinkedExprBuilder serializeConstExpr(Expression expr)) {
@@ -61,72 +58,48 @@
   throw new StateError('Unexpected initializer type ${node.runtimeType}');
 }
 
-/**
- * Instances of this class keep track of intermediate state during
- * serialization of a single constant [Expression].
- */
+/// Instances of this class keep track of intermediate state during
+/// serialization of a single constant [Expression].
 abstract class AbstractConstExprSerializer {
-  /**
-   * Whether an expression that should be a constant is being serialized.
-   *
-   * For constants we need to store more than we need just for type inference,
-   * because we need to be able to restore these AST to evaluate actual values
-   * of constants. So, we need to store constructor arguments, elements for
-   * list and map literals even if these literals are typed.
-   */
+  /// Whether an expression that should be a constant is being serialized.
+  ///
+  /// For constants we need to store more than we need just for type inference,
+  /// because we need to be able to restore these AST to evaluate actual values
+  /// of constants. So, we need to store constructor arguments, elements for
+  /// list and map literals even if these literals are typed.
   final bool forConst;
 
-  /**
-   * See [UnlinkedExprBuilder.isValidConst].
-   */
+  /// See [UnlinkedExprBuilder.isValidConst].
   bool isValidConst = true;
 
-  /**
-   * See [UnlinkedExprBuilder.name].
-   */
+  /// See [UnlinkedExprBuilder.name].
   String name = null;
 
-  /**
-   * See [UnlinkedExprBuilder.operations].
-   */
+  /// See [UnlinkedExprBuilder.operations].
   final List<UnlinkedExprOperation> operations = <UnlinkedExprOperation>[];
 
-  /**
-   * See [UnlinkedExprBuilder.assignmentOperators].
-   */
+  /// See [UnlinkedExprBuilder.assignmentOperators].
   final List<UnlinkedExprAssignOperator> assignmentOperators =
       <UnlinkedExprAssignOperator>[];
 
-  /**
-   * See [UnlinkedExprBuilder.ints].
-   */
+  /// See [UnlinkedExprBuilder.ints].
   final List<int> ints = <int>[];
 
-  /**
-   * See [UnlinkedExprBuilder.doubles].
-   */
+  /// See [UnlinkedExprBuilder.doubles].
   final List<double> doubles = <double>[];
 
-  /**
-   * See [UnlinkedExprBuilder.strings].
-   */
+  /// See [UnlinkedExprBuilder.strings].
   final List<String> strings = <String>[];
 
-  /**
-   * See [UnlinkedExprBuilder.references].
-   */
+  /// See [UnlinkedExprBuilder.references].
   final List<EntityRefBuilder> references = <EntityRefBuilder>[];
 
   AbstractConstExprSerializer(this.forConst);
 
-  /**
-   * Return `true` if the given [name] is a parameter reference.
-   */
+  /// Return `true` if the given [name] is a parameter reference.
   bool isParameterName(String name);
 
-  /**
-   * Serialize the given [expr] expression into this serializer state.
-   */
+  /// Serialize the given [expr] expression into this serializer state.
   void serialize(Expression expr) {
     try {
       if (expr is NamedExpression) {
@@ -146,48 +119,34 @@
     }
   }
 
-  /**
-   * Serialize the given [annotation] into this serializer state.
-   */
+  /// Serialize the given [annotation] into this serializer state.
   void serializeAnnotation(Annotation annotation);
 
-  /**
-   * Return [EntityRefBuilder] that corresponds to the constructor having name
-   * [name] in the class identified by [typeName].  It is expected that [type]
-   * corresponds to the given [typeName] and [typeArguments].  The parameter
-   * [type] might be `null` if the type is not resolved.
-   */
-  EntityRefBuilder serializeConstructorRef(DartType type, Identifier typeName,
+  /// Return [EntityRefBuilder] that corresponds to the constructor having name
+  /// [name] in the class identified by [typeName].
+  EntityRefBuilder serializeConstructorRef(Identifier typeName,
       TypeArgumentList typeArguments, SimpleIdentifier name);
 
-  /**
-   * Return a pair of ints showing how the given [functionExpression] is nested
-   * within the constant currently being serialized.  The first int indicates
-   * how many levels of function nesting must be popped in order to reach the
-   * parent of the [functionExpression].  The second int is the index of the
-   * [functionExpression] within its parent element.
-   *
-   * If the constant being summarized is in a context where local function
-   * references are not allowed, return `null`.
-   */
+  /// Return a pair of ints showing how the given [functionExpression] is nested
+  /// within the constant currently being serialized.  The first int indicates
+  /// how many levels of function nesting must be popped in order to reach the
+  /// parent of the [functionExpression].  The second int is the index of the
+  /// [functionExpression] within its parent element.
+  ///
+  /// If the constant being summarized is in a context where local function
+  /// references are not allowed, return `null`.
   List<int> serializeFunctionExpression(FunctionExpression functionExpression);
 
-  /**
-   * Return [EntityRefBuilder] that corresponds to the [type], which is defined
-   * using generic function type syntax. These may appear as the type arguments
-   * of a const list, etc.
-   */
+  /// Return [EntityRefBuilder] that corresponds to the [type], which is defined
+  /// using generic function type syntax. These may appear as the type arguments
+  /// of a const list, etc.
   EntityRefBuilder serializeGenericFunctionType(GenericFunctionType type);
 
-  /**
-   * Return [EntityRefBuilder] that corresponds to the given [identifier].
-   */
+  /// Return [EntityRefBuilder] that corresponds to the given [identifier].
   EntityRefBuilder serializeIdentifier(Identifier identifier);
 
-  /**
-   * Return [EntityRefBuilder] that corresponds to the given [expr], which
-   * must be a sequence of identifiers.
-   */
+  /// Return [EntityRefBuilder] that corresponds to the given [expr], which
+  /// must be a sequence of identifiers.
   EntityRefBuilder serializeIdentifierSequence(Expression expr);
 
   void serializeInstanceCreation(EntityRefBuilder constructor,
@@ -197,12 +156,10 @@
     operations.add(UnlinkedExprOperation.invokeConstructor);
   }
 
-  /**
-   * Return [EntityRefBuilder] that corresponds to the given [type].
-   */
+  /// Return [EntityRefBuilder] that corresponds to the given [type].
   EntityRefBuilder serializeType(TypeAnnotation type) {
     if (type is TypeName) {
-      return serializeTypeName(type?.type, type?.name, type?.typeArguments);
+      return serializeTypeName(type?.name, type?.typeArguments);
     }
     if (type is GenericFunctionType) {
       return serializeGenericFunctionType(type);
@@ -211,19 +168,13 @@
         'Cannot serialize an instance of ${type.runtimeType}');
   }
 
-  /**
-   * Return [EntityRefBuilder] that corresponds to the [type] with the given
-   * [name] and [arguments].  It is expected that [type] corresponds to the
-   * given [name] and [arguments].  The parameter [type] might be `null` if the
-   * type is not resolved.
-   */
+  /// Return [EntityRefBuilder] that corresponds to the type with the given
+  /// [name] and [arguments].
   EntityRefBuilder serializeTypeName(
-      DartType type, Identifier name, TypeArgumentList arguments);
+      Identifier name, TypeArgumentList arguments);
 
-  /**
-   * Return the [UnlinkedExprBuilder] that corresponds to the state of this
-   * serializer.
-   */
+  /// Return the [UnlinkedExprBuilder] that corresponds to the state of this
+  /// serializer.
   UnlinkedExprBuilder toBuilder() {
     return new UnlinkedExprBuilder(
         isValidConst: isValidConst,
@@ -235,9 +186,7 @@
         references: references);
   }
 
-  /**
-   * Return `true` if the given [expr] is a sequence of identifiers.
-   */
+  /// Return `true` if the given [expr] is a sequence of identifiers.
   bool _isIdentifierSequence(Expression expr) {
     while (expr != null) {
       if (expr is SimpleIdentifier) {
@@ -263,9 +212,7 @@
     return false;
   }
 
-  /**
-   * Push the operation for the given assignable [expr].
-   */
+  /// Push the operation for the given assignable [expr].
   void _pushAssignable(Expression expr) {
     if (_isIdentifierSequence(expr)) {
       EntityRefBuilder ref = serializeIdentifierSequence(expr);
@@ -316,9 +263,7 @@
     }
   }
 
-  /**
-   * Serialize the given [expr] expression into this serializer state.
-   */
+  /// Serialize the given [expr] expression into this serializer state.
   void _serialize(Expression expr) {
     if (expr is IntegerLiteral) {
       int value = expr.value ?? 0;
@@ -364,8 +309,8 @@
       }
       TypeName typeName = expr.constructorName.type;
       serializeInstanceCreation(
-          serializeConstructorRef(typeName.type, typeName.name,
-              typeName.typeArguments, expr.constructorName.name),
+          serializeConstructorRef(
+              typeName.name, typeName.typeArguments, expr.constructorName.name),
           expr.argumentList,
           typeName.typeArguments != null);
     } else if (expr is ListLiteral) {
diff --git a/pkg/analyzer/lib/src/task/dart.dart b/pkg/analyzer/lib/src/task/dart.dart
index ee2ccc0..ec06d19 100644
--- a/pkg/analyzer/lib/src/task/dart.dart
+++ b/pkg/analyzer/lib/src/task/dart.dart
@@ -5109,12 +5109,8 @@
     //
     // Re-write the AST to handle the optional new and const feature.
     //
-    unit.accept(new AstRewriteVisitor(
-        context.typeSystem,
-        library,
-        unit.declaredElement.source,
-        typeProvider,
-        AnalysisErrorListener.NULL_LISTENER));
+    unit.accept(new AstRewriteVisitor(context.typeSystem, library,
+        unit.declaredElement.source, typeProvider, errorListener));
     //
     // Record outputs.
     //
diff --git a/pkg/analyzer/lib/src/task/strong/checker.dart b/pkg/analyzer/lib/src/task/strong/checker.dart
index 64f7067..74f65da 100644
--- a/pkg/analyzer/lib/src/task/strong/checker.dart
+++ b/pkg/analyzer/lib/src/task/strong/checker.dart
@@ -1935,7 +1935,18 @@
   final CodeChecker _codeChecker;
   final String _name;
 
-  _TopLevelInitializerValidator(this._codeChecker, this._name);
+  /// A flag indicating whether certain diagnostics related to top-level
+  /// elements should be produced. The diagnostics are the ones introduced by
+  /// the analyzer to signal to users when the version of type inference
+  /// performed by the analyzer was unable to accurately infer type information.
+  /// The implementation of type inference used by the task model still has
+  /// these deficiencies, but the implementation used by the driver does not.
+  // TODO(brianwilkerson) Remove this field when the task model has been
+  // removed.
+  final bool flagTopLevel;
+
+  _TopLevelInitializerValidator(this._codeChecker, this._name,
+      {this.flagTopLevel = true});
 
   void validateHasType(AstNode n, PropertyAccessorElement e) {
     if (e.hasImplicitReturnType) {
@@ -1968,7 +1979,7 @@
       if (e is PropertyAccessorElement) {
         if (e.isStatic) {
           validateHasType(n, e);
-        } else if (e.hasImplicitReturnType) {
+        } else if (e.hasImplicitReturnType && flagTopLevel) {
           _codeChecker._recordMessage(
               n, StrongModeCode.TOP_LEVEL_INSTANCE_GETTER, [_name, e.name]);
         }
@@ -1976,7 +1987,7 @@
           e is ExecutableElement &&
           e.kind == ElementKind.METHOD &&
           !e.isStatic) {
-        if (_hasAnyImplicitType(e)) {
+        if (_hasAnyImplicitType(e) && flagTopLevel) {
           _codeChecker._recordMessage(
               n, StrongModeCode.TOP_LEVEL_INSTANCE_METHOD, [_name, e.name]);
         }
@@ -2080,14 +2091,16 @@
     if (method is ExecutableElement) {
       if (method.kind == ElementKind.METHOD &&
           !method.isStatic &&
-          method.hasImplicitReturnType) {
+          method.hasImplicitReturnType &&
+          flagTopLevel) {
         _codeChecker._recordMessage(node,
             StrongModeCode.TOP_LEVEL_INSTANCE_METHOD, [_name, method.name]);
       }
       if (node.typeArguments == null && method.typeParameters.isNotEmpty) {
         if (method.kind == ElementKind.METHOD &&
             !method.isStatic &&
-            _anyParameterHasImplicitType(method)) {
+            _anyParameterHasImplicitType(method) &&
+            flagTopLevel) {
           _codeChecker._recordMessage(node,
               StrongModeCode.TOP_LEVEL_INSTANCE_METHOD, [_name, method.name]);
         }
diff --git a/pkg/analyzer/lib/src/task/strong_mode.dart b/pkg/analyzer/lib/src/task/strong_mode.dart
index f3fffb3..a0b6100 100644
--- a/pkg/analyzer/lib/src/task/strong_mode.dart
+++ b/pkg/analyzer/lib/src/task/strong_mode.dart
@@ -78,14 +78,8 @@
    * compilation [unit].
    */
   void inferCompilationUnit(CompilationUnitElement unit) {
-    for (ClassElement classElement in unit.types) {
-      try {
-        _inferClass(classElement);
-      } on _CycleException {
-        // This is a short circuit return to prevent types that inherit from
-        // types containing a circular reference from being inferred.
-      }
-    }
+    _inferClasses(unit.mixins);
+    _inferClasses(unit.types);
   }
 
   /**
@@ -306,6 +300,7 @@
         _inferType(classElement.supertype);
         classElement.mixins.forEach(_inferType);
         classElement.interfaces.forEach(_inferType);
+        classElement.superclassConstraints.forEach(_inferType);
         //
         // Then infer the types for the members.
         //
@@ -330,6 +325,17 @@
     }
   }
 
+  void _inferClasses(List<ClassElement> elements) {
+    for (ClassElement element in elements) {
+      try {
+        _inferClass(element);
+      } on _CycleException {
+        // This is a short circuit return to prevent types that inherit from
+        // types containing a circular reference from being inferred.
+      }
+    }
+  }
+
   void _inferConstructorFieldFormals(ConstructorElement constructor) {
     for (ParameterElement parameter in constructor.parameters) {
       if (parameter.hasImplicitType &&
diff --git a/pkg/analyzer/pubspec.yaml b/pkg/analyzer/pubspec.yaml
index 7b5c8ef..da282cc 100644
--- a/pkg/analyzer/pubspec.yaml
+++ b/pkg/analyzer/pubspec.yaml
@@ -1,5 +1,5 @@
 name: analyzer
-version: 0.33.0-alpha
+version: 0.33.0-alpha.0
 author: Dart Team <misc@dartlang.org>
 description: Static analyzer for Dart.
 homepage: https://github.com/dart-lang/sdk/tree/master/pkg/analyzer
@@ -11,10 +11,10 @@
   collection: ^1.10.1
   convert: ^2.0.0
   crypto: '>=1.1.1 <3.0.0'
-  front_end: 0.1.4
+  front_end: 0.1.5
   glob: ^1.0.3
   html: '>=0.12.0 <1.14.0'
-  kernel: 0.3.4
+  kernel: 0.3.5
   meta: ^1.0.2
   package_config: '>=0.1.5 <2.0.0'
   path: '>=0.9.0 <2.0.0'
diff --git a/pkg/analyzer/test/generated/checked_mode_compile_time_error_code_test.dart b/pkg/analyzer/test/generated/checked_mode_compile_time_error_code_test.dart
index 0a5de28..1d53be6 100644
--- a/pkg/analyzer/test/generated/checked_mode_compile_time_error_code_test.dart
+++ b/pkg/analyzer/test/generated/checked_mode_compile_time_error_code_test.dart
@@ -650,7 +650,7 @@
 class D extends C {
   const D(d) : super(d);
 }
-const f = const D(0);
+const f = const D('0.0');
 ''');
     await computeAnalysisResult(source);
     assertErrors(
diff --git a/pkg/analyzer/test/generated/compile_time_error_code_driver_test.dart b/pkg/analyzer/test/generated/compile_time_error_code_driver_test.dart
index fdda0cd..4e73768 100644
--- a/pkg/analyzer/test/generated/compile_time_error_code_driver_test.dart
+++ b/pkg/analyzer/test/generated/compile_time_error_code_driver_test.dart
@@ -18,31 +18,6 @@
   bool get enableNewAnalysisDriver => true;
 
   @override // Passes with driver
-  test_conflictingGenericInterfaces_simple() =>
-      super.test_conflictingGenericInterfaces_simple();
-
-  @override // Passes with driver
-  test_conflictingGenericInterfaces_viaMixin() =>
-      super.test_conflictingGenericInterfaces_viaMixin();
-
-  @override // Passes with driver
-  test_mixinInference_conflictingSubstitution() =>
-      super.test_mixinInference_conflictingSubstitution();
-
-  @override // Passes with driver
-  test_mixinInference_doNotIgnorePreviousExplicitMixins() =>
-      super.test_mixinInference_doNotIgnorePreviousExplicitMixins();
-
-  @override // Passes with driver
-  test_mixinInference_impossibleSubstitution() =>
-      super.test_mixinInference_impossibleSubstitution();
-
-  @override // Passes with driver
-  test_mixinInference_noMatchingClass_constraintSatisfiedByImplementsClause() =>
-      super
-          .test_mixinInference_noMatchingClass_constraintSatisfiedByImplementsClause();
-
-  @override // Passes with driver
   test_mixinInference_recursiveSubtypeCheck() =>
       super.test_mixinInference_recursiveSubtypeCheck();
 }
diff --git a/pkg/analyzer/test/generated/compile_time_error_code_test.dart b/pkg/analyzer/test/generated/compile_time_error_code_test.dart
index 0463112..1955f4a 100644
--- a/pkg/analyzer/test/generated/compile_time_error_code_test.dart
+++ b/pkg/analyzer/test/generated/compile_time_error_code_test.dart
@@ -704,42 +704,6 @@
     verify([source]);
   }
 
-  @failingTest // See an update on override checks in issue #33235.
-  test_conflictingConstructorNameAndMember_field() async {
-    Source source = addSource(r'''
-class A {
-  int x;
-  A.x() {}
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  @failingTest // See an update on override checks in issue #33235.
-  test_conflictingConstructorNameAndMember_getter() async {
-    Source source = addSource(r'''
-class A {
-  int get x => 42;
-  A.x() {}
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  @failingTest // See an update on override checks in issue #33235.
-  test_conflictingConstructorNameAndMember_method() async {
-    Source source = addSource(r'''
-class A {
-  const A.x();
-  void x() {}
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
   test_conflictingGenericInterfaces_hierarchyLoop() async {
     // There is no interface conflict here, but there is a loop in the class
     // hierarchy leading to a finite set of implemented types; this loop
@@ -766,82 +730,6 @@
     assertNoErrors(source);
   }
 
-  @failingTest // Does not work with old task model
-  test_conflictingGenericInterfaces_simple() async {
-    Source source = addSource('''
-class I<T> {}
-class A implements I<int> {}
-class B implements I<String> {}
-class C extends A implements B {}
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.CONFLICTING_GENERIC_INTERFACES]);
-  }
-
-  @failingTest // Does not work with old task model
-  test_conflictingGenericInterfaces_viaMixin() async {
-    Source source = addSource('''
-class I<T> {}
-class A implements I<int> {}
-class B implements I<String> {}
-class C extends A with B {}
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.CONFLICTING_GENERIC_INTERFACES]);
-  }
-
-  test_conflictingGetterAndMethod_field_method() async {
-    Source source = addSource(r'''
-class A {
-  final int m = 0;
-}
-class B extends A {
-  m() {}
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.CONFLICTING_GETTER_AND_METHOD]);
-    verify([source]);
-  }
-
-  test_conflictingGetterAndMethod_getter_method() async {
-    Source source = addSource(r'''
-class A {
-  get m => 0;
-}
-class B extends A {
-  m() {}
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.CONFLICTING_GETTER_AND_METHOD]);
-    verify([source]);
-  }
-
-  test_conflictingGetterAndMethod_method_field() async {
-    Source source = addSource(r'''
-class A {
-  m() {}
-}
-class B extends A {
-  int m;
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.CONFLICTING_METHOD_AND_GETTER]);
-    verify([source]);
-  }
-
-  test_conflictingGetterAndMethod_method_getter() async {
-    Source source = addSource(r'''
-class A {
-  m() {}
-}
-class B extends A {
-  get m => 0;
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.CONFLICTING_METHOD_AND_GETTER]);
-    verify([source]);
-  }
-
   test_conflictingTypeVariableAndClass() async {
     Source source = addSource(r'''
 class T<T> {
@@ -1828,34 +1716,6 @@
     assertErrors(source, [CompileTimeErrorCode.URI_DOES_NOT_EXIST]);
   }
 
-  test_duplicateConstructorName_named() async {
-    Source source = addSource(r'''
-class A {
-  A.a() {}
-  A.a() {}
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [
-      CompileTimeErrorCode.DUPLICATE_CONSTRUCTOR_NAME,
-      CompileTimeErrorCode.DUPLICATE_CONSTRUCTOR_NAME
-    ]);
-    verify([source]);
-  }
-
-  test_duplicateConstructorName_unnamed() async {
-    Source source = addSource(r'''
-class A {
-  A() {}
-  A() {}
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [
-      CompileTimeErrorCode.DUPLICATE_CONSTRUCTOR_DEFAULT,
-      CompileTimeErrorCode.DUPLICATE_CONSTRUCTOR_DEFAULT
-    ]);
-    verify([source]);
-  }
-
   test_duplicateDefinition_acrossLibraries() async {
     Source librarySource = addNamedSource("/lib.dart", r'''
 library lib;
@@ -1888,39 +1748,6 @@
     verify([source]);
   }
 
-  test_duplicateDefinition_classMembers_fields() async {
-    Source source = addSource(r'''
-class A {
-  int a;
-  int a;
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.DUPLICATE_DEFINITION]);
-    verify([source]);
-  }
-
-  test_duplicateDefinition_classMembers_fields_oneStatic() async {
-    Source source = addSource(r'''
-class A {
-  int x;
-  static int x;
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.DUPLICATE_DEFINITION]);
-    verify([source]);
-  }
-
-  test_duplicateDefinition_classMembers_methods() async {
-    Source source = addSource(r'''
-class A {
-  m() {}
-  m() {}
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.DUPLICATE_DEFINITION]);
-    verify([source]);
-  }
-
   test_duplicateDefinition_inPart() async {
     Source librarySource = addNamedSource("/lib.dart", r'''
 library test;
@@ -2047,90 +1874,6 @@
     verify([source]);
   }
 
-  test_duplicateDefinitionInheritance_instanceGetter_staticGetter() async {
-    Source source = addSource(r'''
-class A {
-  int get x => 0;
-}
-class B extends A {
-  static int get x => 0;
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [CompileTimeErrorCode.DUPLICATE_DEFINITION_INHERITANCE]);
-    verify([source]);
-  }
-
-  test_duplicateDefinitionInheritance_instanceGetterAbstract_staticGetter() async {
-    Source source = addSource(r'''
-abstract class A {
-  int get x;
-}
-class B extends A {
-  static int get x => 0;
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [CompileTimeErrorCode.DUPLICATE_DEFINITION_INHERITANCE]);
-    verify([source]);
-  }
-
-  test_duplicateDefinitionInheritance_instanceMethod_staticMethod() async {
-    Source source = addSource(r'''
-class A {
-  x() {}
-}
-class B extends A {
-  static x() {}
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [CompileTimeErrorCode.DUPLICATE_DEFINITION_INHERITANCE]);
-    verify([source]);
-  }
-
-  test_duplicateDefinitionInheritance_instanceMethodAbstract_staticMethod() async {
-    Source source = addSource(r'''
-abstract class A {
-  x();
-}
-abstract class B extends A {
-  static x() {}
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [CompileTimeErrorCode.DUPLICATE_DEFINITION_INHERITANCE]);
-    verify([source]);
-  }
-
-  test_duplicateDefinitionInheritance_instanceSetter_staticSetter() async {
-    Source source = addSource(r'''
-class A {
-  set x(value) {}
-}
-class B extends A {
-  static set x(value) {}
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [CompileTimeErrorCode.DUPLICATE_DEFINITION_INHERITANCE]);
-    verify([source]);
-  }
-
-  test_duplicateDefinitionInheritance_instanceSetterAbstract_staticSetter() async {
-    Source source = addSource(r'''
-abstract class A {
-  set x(value);
-}
-class B extends A {
-  static set x(value) {}
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [CompileTimeErrorCode.DUPLICATE_DEFINITION_INHERITANCE]);
-    verify([source]);
-  }
-
   test_duplicateNamedArgument() async {
     Source source = addSource(r'''
 f({a, b}) {}
@@ -2320,31 +2063,6 @@
     verify([source]);
   }
 
-  test_extendsNonClass_dynamic() async {
-    Source source = addSource("class B extends dynamic {}");
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.EXTENDS_NON_CLASS]);
-    verify([source]);
-  }
-
-  test_extendsNonClass_enum() async {
-    Source source = addSource(r'''
-enum E { ONE }
-class A extends E {}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.EXTENDS_NON_CLASS]);
-    verify([source]);
-  }
-
-  test_extendsNonClass_variable() async {
-    Source source = addSource(r'''
-int A;
-class B extends A {}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.EXTENDS_NON_CLASS]);
-    verify([source]);
-  }
-
   test_extraPositionalArguments_const() async {
     Source source = addSource(r'''
 class A {
@@ -2836,18 +2554,6 @@
     verify([source]);
   }
 
-  test_getterAndMethodWithSameName() async {
-    Source source = addSource(r'''
-class A {
-  x(y) {}
-  get x => 0;
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [CompileTimeErrorCode.GETTER_AND_METHOD_WITH_SAME_NAME]);
-    verify([source]);
-  }
-
   test_implementsDeferredClass() async {
     await resolveWithErrors(<String>[
       r'''
@@ -3039,28 +2745,6 @@
     verify([source]);
   }
 
-  test_implementsRepeated() async {
-    Source source = addSource(r'''
-class A {}
-class B implements A, A {}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.IMPLEMENTS_REPEATED]);
-    verify([source]);
-  }
-
-  test_implementsRepeated_3times() async {
-    Source source = addSource(r'''
-class A {} class C{}
-class B implements A, A, A, A {}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [
-      CompileTimeErrorCode.IMPLEMENTS_REPEATED,
-      CompileTimeErrorCode.IMPLEMENTS_REPEATED,
-      CompileTimeErrorCode.IMPLEMENTS_REPEATED
-    ]);
-    verify([source]);
-  }
-
   test_implementsSuperClass() async {
     Source source = addSource(r'''
 class A {}
@@ -3457,6 +3141,38 @@
     verify([source]);
   }
 
+  test_integerLiteralAsDoubleOutOfRange_excessiveExponent() async {
+    Source source = addSource(
+        'double x = 0xfffffffffffff80000000000000000000000000000000000000000000'
+        '0000000000000000000000000000000000000000000000000000000000000000000000'
+        '0000000000000000000000000000000000000000000000000000000000000000000000'
+        '000000000000000000000000000000000000000000000000000000000000;');
+    await computeAnalysisResult(source);
+    assertErrors(
+        source, [CompileTimeErrorCode.INTEGER_LITERAL_IMPRECISE_AS_DOUBLE]);
+    AnalysisError error = analysisResults[source].errors[0];
+
+    // Check that we suggest the max double instead.
+    expect(
+        true,
+        error.correction.contains(
+            '179769313486231570814527423731704356798070567525844996598917476803'
+            '157260780028538760589558632766878171540458953514382464234321326889'
+            '464182768467546703537516986049910576551282076245490090389328944075'
+            '868508455133942304583236903222948165808559332123348274797826204144'
+            '723168738177180919299881250404026184124858368'));
+  }
+
+  test_integerLiteralAsDoubleOutOfRange_excessiveMantissa() async {
+    Source source = addSource('double x = 9223372036854775809;');
+    await computeAnalysisResult(source);
+    assertErrors(
+        source, [CompileTimeErrorCode.INTEGER_LITERAL_IMPRECISE_AS_DOUBLE]);
+    AnalysisError error = analysisResults[source].errors[0];
+    // Check that we suggest a valid double instead.
+    expect(true, error.correction.contains('9223372036854775808'));
+  }
+
   test_integerLiteralOutOfRange_negative() async {
     Source source = addSource('int x = -9223372036854775809;');
     await computeAnalysisResult(source);
@@ -4043,18 +3759,6 @@
     // no test because indistinguishable from constructor
   }
 
-  test_methodAndGetterWithSameName() async {
-    Source source = addSource(r'''
-class A {
-  get x => 0;
-  x(y) {}
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [CompileTimeErrorCode.METHOD_AND_GETTER_WITH_SAME_NAME]);
-    verify([source]);
-  }
-
   test_mixinClassDeclaresConstructor_classDeclaration() async {
     Source source = addSource(r'''
 class A {
@@ -4199,56 +3903,6 @@
     verify([source]);
   }
 
-  @failingTest // Does not work with old task model
-  test_mixinInference_conflictingSubstitution() async {
-    AnalysisOptionsImpl options = new AnalysisOptionsImpl();
-    options.enableSuperMixins = true;
-    resetWith(options: options);
-    Source source = addSource('''
-abstract class A<T> {}
-class M<T> extends A<Map<T, T>> {}
-class C extends A<Map<int, String>> with M {}
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [
-      CompileTimeErrorCode.MIXIN_INFERENCE_NO_POSSIBLE_SUBSTITUTION,
-      CompileTimeErrorCode.CONFLICTING_GENERIC_INTERFACES
-    ]);
-  }
-
-  @failingTest // Does not work with old task model
-  test_mixinInference_doNotIgnorePreviousExplicitMixins() async {
-    AnalysisOptionsImpl options = new AnalysisOptionsImpl();
-    options.enableSuperMixins = true;
-    resetWith(options: options);
-    Source source = addSource('''
-class A extends Object with B<String>, C {}
-class B<T> {}
-class C<T> extends B<T> {}
-''');
-    var analysisResult = await computeAnalysisResult(source);
-    assertNoErrors(source);
-    var mixins = analysisResult.unit.declaredElement.getType('A').mixins;
-    expect(mixins[1].toString(), 'C<String>');
-  }
-
-  @failingTest // Does not work with old task model
-  test_mixinInference_impossibleSubstitution() async {
-    AnalysisOptionsImpl options = new AnalysisOptionsImpl();
-    options.enableSuperMixins = true;
-    resetWith(options: options);
-    Source source = addSource('''
-abstract class A<T> {}
-class M<T> extends A<Map<T, T>> {}
-class C extends A<List<int>> with M {}
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [
-      CompileTimeErrorCode.MIXIN_INFERENCE_NO_POSSIBLE_SUBSTITUTION,
-      CompileTimeErrorCode.CONFLICTING_GENERIC_INTERFACES
-    ]);
-  }
-
   test_mixinInference_matchingClass() async {
     AnalysisOptionsImpl options = new AnalysisOptionsImpl();
     options.enableSuperMixins = true;
@@ -4293,24 +3947,6 @@
         source, [CompileTimeErrorCode.MIXIN_INFERENCE_NO_MATCHING_CLASS]);
   }
 
-  @failingTest // Does not work with old task model
-  test_mixinInference_noMatchingClass_constraintSatisfiedByImplementsClause() async {
-    AnalysisOptionsImpl options = new AnalysisOptionsImpl();
-    options.enableSuperMixins = true;
-    resetWith(options: options);
-    Source source = addSource('''
-abstract class A<T> {}
-class B {}
-class M<T> extends A<T> {}
-class C extends Object with M implements A<B> {}
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [
-      CompileTimeErrorCode.MIXIN_INFERENCE_NO_MATCHING_CLASS,
-      CompileTimeErrorCode.CONFLICTING_GENERIC_INTERFACES
-    ]);
-  }
-
   test_mixinInference_noMatchingClass_namedMixinApplication() async {
     AnalysisOptionsImpl options = new AnalysisOptionsImpl();
     options.enableSuperMixins = true;
@@ -6197,163 +5833,6 @@
     verify([source]);
   }
 
-  test_recursiveInterfaceInheritance_extends() async {
-    Source source = addSource(r'''
-class A extends B {}
-class B extends A {}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [
-      CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE,
-      CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE
-    ]);
-    verify([source]);
-  }
-
-  test_recursiveInterfaceInheritance_extends_implements() async {
-    Source source = addSource(r'''
-class A extends B {}
-class B implements A {}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [
-      CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE,
-      CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE
-    ]);
-    verify([source]);
-  }
-
-  test_recursiveInterfaceInheritance_implements() async {
-    Source source = addSource(r'''
-class A implements B {}
-class B implements A {}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [
-      CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE,
-      CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE
-    ]);
-    verify([source]);
-  }
-
-  test_recursiveInterfaceInheritance_mixin() async {
-    Source source = addSource(r'''
-class M1 = Object with M2;
-class M2 = Object with M1;''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [
-      CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE,
-      CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE
-    ]);
-    verify([source]);
-  }
-
-  test_recursiveInterfaceInheritance_mixin_superclass() async {
-    // Make sure we don't get CompileTimeErrorCode.MIXIN_HAS_NO_CONSTRUCTORS in
-    // addition--that would just be confusing.
-    Source source = addSource('''
-class C = D with M;
-class D = C with M;
-class M {}
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [
-      CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE,
-      CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE
-    ]);
-    verify([source]);
-  }
-
-  test_recursiveInterfaceInheritance_tail() async {
-    Source source = addSource(r'''
-abstract class A implements A {}
-class B implements A {}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [
-      CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_IMPLEMENTS
-    ]);
-    verify([source]);
-  }
-
-  test_recursiveInterfaceInheritance_tail2() async {
-    Source source = addSource(r'''
-abstract class A implements B {}
-abstract class B implements A {}
-class C implements A {}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [
-      CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE,
-      CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE
-    ]);
-    verify([source]);
-  }
-
-  test_recursiveInterfaceInheritance_tail3() async {
-    Source source = addSource(r'''
-abstract class A implements B {}
-abstract class B implements C {}
-abstract class C implements A {}
-class D implements A {}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [
-      CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE,
-      CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE,
-      CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE
-    ]);
-    verify([source]);
-  }
-
-  test_recursiveInterfaceInheritanceBaseCaseExtends() async {
-    Source source = addSource("class A extends A {}");
-    await computeAnalysisResult(source);
-    assertErrors(source, [
-      CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_EXTENDS
-    ]);
-    verify([source]);
-  }
-
-  test_recursiveInterfaceInheritanceBaseCaseExtends_abstract() async {
-    Source source = addSource(r'''
-class C extends C {
-  var bar = 0;
-  m();
-}
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [
-      CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_EXTENDS,
-      StaticWarningCode.CONCRETE_CLASS_WITH_ABSTRACT_MEMBER,
-      StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE
-    ]);
-    verify([source]);
-  }
-
-  test_recursiveInterfaceInheritanceBaseCaseImplements() async {
-    Source source = addSource("class A implements A {}");
-    await computeAnalysisResult(source);
-    assertErrors(source, [
-      CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_IMPLEMENTS
-    ]);
-    verify([source]);
-  }
-
-  test_recursiveInterfaceInheritanceBaseCaseImplements_typeAlias() async {
-    Source source = addSource(r'''
-class A {}
-class M {}
-class B = A with M implements B;''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [
-      CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_IMPLEMENTS
-    ]);
-    verify([source]);
-  }
-
-  test_recursiveInterfaceInheritanceBaseCaseWith() async {
-    Source source = addSource("class M = Object with M;");
-    await computeAnalysisResult(source);
-    assertErrors(source,
-        [CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_WITH]);
-    verify([source]);
-  }
-
   test_redirectGenerativeToMissingConstructor() async {
     Source source = addSource(r'''
 class A {
diff --git a/pkg/analyzer/test/generated/hint_code_test.dart b/pkg/analyzer/test/generated/hint_code_test.dart
index d0ab205..1789773 100644
--- a/pkg/analyzer/test/generated/hint_code_test.dart
+++ b/pkg/analyzer/test/generated/hint_code_test.dart
@@ -96,87 +96,6 @@
     ]);
   }
 
-  test_abstractSuperMemberReference_getter() async {
-    Source source = addSource(r'''
-abstract class A {
-  int get test;
-}
-class B extends A {
-  int get test {
-    super.test;
-    return 0;
-  }
-}
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [HintCode.ABSTRACT_SUPER_MEMBER_REFERENCE]);
-    verify([source]);
-  }
-
-  test_abstractSuperMemberReference_method_invocation() async {
-    Source source = addSource(r'''
-abstract class A {
-  void test();
-}
-class B extends A {
-  void test() {
-    super.test();
-  }
-}
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [HintCode.ABSTRACT_SUPER_MEMBER_REFERENCE]);
-    verify([source]);
-  }
-
-  test_abstractSuperMemberReference_method_reference() async {
-    Source source = addSource(r'''
-abstract class A {
-  void test();
-}
-class B extends A {
-  void test() {
-    super.test;
-  }
-}
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [HintCode.ABSTRACT_SUPER_MEMBER_REFERENCE]);
-    verify([source]);
-  }
-
-  test_abstractSuperMemberReference_setter() async {
-    Source source = addSource(r'''
-abstract class A {
-  void set test(int v);
-}
-class B extends A {
-  void set test(int v){
-    super.test = 0;
-  }
-}
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [HintCode.ABSTRACT_SUPER_MEMBER_REFERENCE]);
-    verify([source]);
-  }
-
-  test_abstractSuperMemberReference_superHasNoSuchMethod() async {
-    Source source = addSource('''
-abstract class A {
-  int m();
-  noSuchMethod(_) => 42;
-}
-
-class B extends A {
-  int m() => super.m();
-}
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [HintCode.ABSTRACT_SUPER_MEMBER_REFERENCE]);
-    verify([source]);
-  }
-
   test_argumentTypeNotAssignable_functionType() async {
     Source source = addSource(r'''
 m() {
@@ -3987,14 +3906,6 @@
     }
   }
 
-  test_undefinedGetter_message() async {
-    // The implementation of HintCode.UNDEFINED_SETTER assumes that
-    // UNDEFINED_SETTER in StaticTypeWarningCode and StaticWarningCode are the
-    // same, this verifies that assumption.
-    expect(StaticWarningCode.UNDEFINED_GETTER.message,
-        StaticTypeWarningCode.UNDEFINED_GETTER.message);
-  }
-
   test_undefinedIdentifier_exportHide() async {
     Source source = addSource(r'''
 library L;
@@ -4181,14 +4092,6 @@
     }
   }
 
-  test_undefinedSetter_message() async {
-    // The implementation of HintCode.UNDEFINED_SETTER assumes that
-    // UNDEFINED_SETTER in StaticTypeWarningCode and StaticWarningCode are the
-    // same, this verifies that assumption.
-    expect(StaticWarningCode.UNDEFINED_SETTER.message,
-        StaticTypeWarningCode.UNDEFINED_SETTER.message);
-  }
-
   test_unnecessaryCast_type_supertype() async {
     Source source = addSource(r'''
 m(int i) {
diff --git a/pkg/analyzer/test/generated/inheritance_manager_test.dart b/pkg/analyzer/test/generated/inheritance_manager_test.dart
index 12a0450..d89fec8 100644
--- a/pkg/analyzer/test/generated/inheritance_manager_test.dart
+++ b/pkg/analyzer/test/generated/inheritance_manager_test.dart
@@ -13,7 +13,6 @@
 import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/dart/element/type.dart';
 import 'package:analyzer/src/dart/resolver/inheritance_manager.dart';
-import 'package:analyzer/src/error/codes.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/resolver.dart';
 import 'package:analyzer/src/generated/source_io.dart';
@@ -318,152 +317,6 @@
     _assertNoErrors(classA);
   }
 
-  void
-      test_getMapOfMembersInheritedFromInterfaces_inconsistentMethodInheritance_getter_method() {
-    // class I1 { int m(); }
-    // class I2 { int get m; }
-    // class A implements I2, I1 {}
-    ClassElementImpl classI1 = ElementFactory.classElement2("I1");
-    String methodName = "m";
-    MethodElement methodM =
-        ElementFactory.methodElement(methodName, _typeProvider.intType);
-    classI1.methods = <MethodElement>[methodM];
-    ClassElementImpl classI2 = ElementFactory.classElement2("I2");
-    PropertyAccessorElement getter =
-        ElementFactory.getterElement(methodName, false, _typeProvider.intType);
-    classI2.accessors = <PropertyAccessorElement>[getter];
-    ClassElementImpl classA = ElementFactory.classElement2("A");
-    classA.interfaces = <InterfaceType>[classI2.type, classI1.type];
-    Map<String, ExecutableElement> mapA =
-        _inheritanceManager.getMembersInheritedFromInterfaces(classA);
-    expect(mapA.length, _numOfMembersInObject);
-    expect(mapA[methodName], isNull);
-    _assertErrors(classA,
-        [StaticWarningCode.INCONSISTENT_METHOD_INHERITANCE_GETTER_AND_METHOD]);
-  }
-
-  void
-      test_getMapOfMembersInheritedFromInterfaces_inconsistentMethodInheritance_int_str() {
-    // class I1 { int m(); }
-    // class I2 { String m(); }
-    // class A implements I1, I2 {}
-    ClassElementImpl classI1 = ElementFactory.classElement2("I1");
-    String methodName = "m";
-    MethodElement methodM1 =
-        ElementFactory.methodElement(methodName, null, [_typeProvider.intType]);
-    classI1.methods = <MethodElement>[methodM1];
-    ClassElementImpl classI2 = ElementFactory.classElement2("I2");
-    MethodElement methodM2 = ElementFactory.methodElement(
-        methodName, null, [_typeProvider.stringType]);
-    classI2.methods = <MethodElement>[methodM2];
-    ClassElementImpl classA = ElementFactory.classElement2("A");
-    classA.interfaces = <InterfaceType>[classI1.type, classI2.type];
-    Map<String, ExecutableElement> mapA =
-        _inheritanceManager.getMembersInheritedFromInterfaces(classA);
-    expect(mapA.length, _numOfMembersInObject);
-    expect(mapA[methodName], isNull);
-    _assertErrors(
-        classA, [StaticTypeWarningCode.INCONSISTENT_METHOD_INHERITANCE]);
-  }
-
-  void
-      test_getMapOfMembersInheritedFromInterfaces_inconsistentMethodInheritance_method_getter() {
-    // class I1 { int m(); }
-    // class I2 { int get m; }
-    // class A implements I1, I2 {}
-    ClassElementImpl classI1 = ElementFactory.classElement2("I1");
-    String methodName = "m";
-    MethodElement methodM =
-        ElementFactory.methodElement(methodName, _typeProvider.intType);
-    classI1.methods = <MethodElement>[methodM];
-    ClassElementImpl classI2 = ElementFactory.classElement2("I2");
-    PropertyAccessorElement getter =
-        ElementFactory.getterElement(methodName, false, _typeProvider.intType);
-    classI2.accessors = <PropertyAccessorElement>[getter];
-    ClassElementImpl classA = ElementFactory.classElement2("A");
-    classA.interfaces = <InterfaceType>[classI1.type, classI2.type];
-    Map<String, ExecutableElement> mapA =
-        _inheritanceManager.getMembersInheritedFromInterfaces(classA);
-    expect(mapA.length, _numOfMembersInObject);
-    expect(mapA[methodName], isNull);
-    _assertErrors(classA,
-        [StaticWarningCode.INCONSISTENT_METHOD_INHERITANCE_GETTER_AND_METHOD]);
-  }
-
-  void
-      test_getMapOfMembersInheritedFromInterfaces_inconsistentMethodInheritance_numOfRequiredParams() {
-    // class I1 { dynamic m(int, [int]); }
-    // class I2 { dynamic m(int, int, int); }
-    // class A implements I1, I2 {}
-    ClassElementImpl classI1 = ElementFactory.classElement2("I1");
-    String methodName = "m";
-    MethodElementImpl methodM1 =
-        ElementFactory.methodElement(methodName, _typeProvider.dynamicType);
-    ParameterElementImpl parameter1 =
-        new ParameterElementImpl.forNode(AstTestFactory.identifier3("a1"));
-    parameter1.type = _typeProvider.intType;
-    parameter1.parameterKind = ParameterKind.REQUIRED;
-    ParameterElementImpl parameter2 =
-        new ParameterElementImpl.forNode(AstTestFactory.identifier3("a2"));
-    parameter2.type = _typeProvider.intType;
-    parameter2.parameterKind = ParameterKind.POSITIONAL;
-    methodM1.parameters = <ParameterElement>[parameter1, parameter2];
-    classI1.methods = <MethodElement>[methodM1];
-    ClassElementImpl classI2 = ElementFactory.classElement2("I2");
-    MethodElementImpl methodM2 =
-        ElementFactory.methodElement(methodName, _typeProvider.dynamicType);
-    ParameterElementImpl parameter3 =
-        new ParameterElementImpl.forNode(AstTestFactory.identifier3("a3"));
-    parameter3.type = _typeProvider.intType;
-    parameter3.parameterKind = ParameterKind.REQUIRED;
-    ParameterElementImpl parameter4 =
-        new ParameterElementImpl.forNode(AstTestFactory.identifier3("a4"));
-    parameter4.type = _typeProvider.intType;
-    parameter4.parameterKind = ParameterKind.REQUIRED;
-    ParameterElementImpl parameter5 =
-        new ParameterElementImpl.forNode(AstTestFactory.identifier3("a5"));
-    parameter5.type = _typeProvider.intType;
-    parameter5.parameterKind = ParameterKind.REQUIRED;
-    methodM2.parameters = <ParameterElement>[
-      parameter3,
-      parameter4,
-      parameter5
-    ];
-    classI2.methods = <MethodElement>[methodM2];
-    ClassElementImpl classA = ElementFactory.classElement2("A");
-    classA.interfaces = <InterfaceType>[classI1.type, classI2.type];
-    Map<String, ExecutableElement> mapA =
-        _inheritanceManager.getMembersInheritedFromInterfaces(classA);
-    expect(mapA.length, _numOfMembersInObject);
-    expect(mapA[methodName], isNull);
-    _assertErrors(
-        classA, [StaticTypeWarningCode.INCONSISTENT_METHOD_INHERITANCE]);
-  }
-
-  void
-      test_getMapOfMembersInheritedFromInterfaces_inconsistentMethodInheritance_str_int() {
-    // class I1 { int m(); }
-    // class I2 { String m(); }
-    // class A implements I2, I1 {}
-    ClassElementImpl classI1 = ElementFactory.classElement2("I1");
-    String methodName = "m";
-    MethodElement methodM1 = ElementFactory.methodElement(
-        methodName, null, [_typeProvider.stringType]);
-    classI1.methods = <MethodElement>[methodM1];
-    ClassElementImpl classI2 = ElementFactory.classElement2("I2");
-    MethodElement methodM2 =
-        ElementFactory.methodElement(methodName, null, [_typeProvider.intType]);
-    classI2.methods = <MethodElement>[methodM2];
-    ClassElementImpl classA = ElementFactory.classElement2("A");
-    classA.interfaces = <InterfaceType>[classI2.type, classI1.type];
-    Map<String, ExecutableElement> mapA =
-        _inheritanceManager.getMembersInheritedFromInterfaces(classA);
-    expect(mapA.length, _numOfMembersInObject);
-    expect(mapA[methodName], isNull);
-    _assertErrors(
-        classA, [StaticTypeWarningCode.INCONSISTENT_METHOD_INHERITANCE]);
-  }
-
   void test_getMapOfMembersInheritedFromInterfaces_method_extends() {
     // class A { int g(); }
     // class B extends A {}
diff --git a/pkg/analyzer/test/generated/non_error_resolver_test.dart b/pkg/analyzer/test/generated/non_error_resolver_test.dart
index a215f04..f411b0f 100644
--- a/pkg/analyzer/test/generated/non_error_resolver_test.dart
+++ b/pkg/analyzer/test/generated/non_error_resolver_test.dart
@@ -40,90 +40,6 @@
     verify([source]);
   }
 
-  test_abstractSuperMemberReference_superHasConcrete_mixinHasAbstract_method() async {
-    Source source = addSource('''
-class A {
-  void method() {}
-}
-
-abstract class B {
-  void method();
-}
-
-class C extends A with B {
-  void method() {
-    super.method();
-  }
-}
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_abstractSuperMemberReference_superSuperHasConcrete_getter() async {
-    Source source = addSource('''
-abstract class A {
-  int get m => 0;
-}
-
-abstract class B extends A {
-  int get m;
-}
-
-class C extends B {
-  int get m => super.m;
-}
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_abstractSuperMemberReference_superSuperHasConcrete_method() async {
-    Source source = addSource('''
-void main() {
-  print(new C().m());
-}
-
-abstract class A {
-  int m() => 0;
-}
-
-abstract class B extends A {
-  int m();
-}
-
-class C extends B {
-  int m() => super.m();
-}
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_abstractSuperMemberReference_superSuperHasConcrete_setter() async {
-    Source source = addSource('''
-abstract class A {
-  void set m(int v) {}
-}
-
-abstract class B extends A {
-  void set m(int v);
-}
-
-class C extends B {
-  void set m(int v) {
-    super.m = 0;
-  }
-}
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
   test_ambiguousExport() async {
     Source source = addSource(r'''
 library L;
@@ -1259,18 +1175,6 @@
     verify([source]);
   }
 
-  @failingTest
-  test_conflictingStaticSetterAndInstanceMember_thisClass_method() async {
-    Source source = addSource(r'''
-class A {
-  static x() {}
-  static set x(int p) {}
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.CONFLICTING_GETTER_AND_METHOD]);
-    verify([source]);
-  }
-
   test_const_constructor_with_named_generic_parameter() async {
     Source source = addSource('''
 class C<T> {
@@ -2943,6 +2847,66 @@
     assertNoErrors(source);
   }
 
+  test_intLiteralInDoubleContext() async {
+    Source source = addSource(r'''
+void takeDouble(double x) {}
+void main() {
+  takeDouble(0);
+  takeDouble(-0);
+  takeDouble(0x0);
+  takeDouble(-0x0);
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_intLiteralInDoubleContext_const() async {
+    Source source = addSource(r'''
+class C {
+  const C(double x)
+    : assert((x + 3) / 2 == 1.5)
+    , assert(x == 0.0);
+}
+@C(0)
+@C(-0)
+@C(0x0)
+@C(-0x0)
+void main() {
+  const C(0);
+  const C(-0);
+  const C(0x0);
+  const C(-0x0);
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  @failingTest
+  test_intLiteralInDoubleContext_const_exact() async {
+    // TODO(mfairhurst): get the commented out assertions to pass.
+    Source source = addSource(r'''
+class C {
+  const C(double x)
+    : assert("$x" == "0.0")
+    , assert(identical(x, 0.0));
+}
+@C(0)
+@C(-0)
+@C(0x0)
+@C(-0x0)
+void main() {
+  const C(0);
+  const C(-0);
+  const C(0x0);
+  const C(-0x0);
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
   test_invalidAnnotation_constantVariable_field() async {
     Source source = addSource(r'''
 @A.C
diff --git a/pkg/analyzer/test/generated/non_hint_code_test.dart b/pkg/analyzer/test/generated/non_hint_code_test.dart
index 9def3f0..a687345 100644
--- a/pkg/analyzer/test/generated/non_hint_code_test.dart
+++ b/pkg/analyzer/test/generated/non_hint_code_test.dart
@@ -6,7 +6,6 @@
 
 import 'package:analyzer/error/error.dart';
 import 'package:analyzer/src/error/codes.dart';
-import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/source_io.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
@@ -1464,26 +1463,6 @@
     assertNoErrors(source);
     verify([source]);
   }
-
-  test_withSuperMixin() async {
-    resetWith(options: new AnalysisOptionsImpl()..enableSuperMixins = true);
-    Source source = addSource(r'''
-abstract class A {
-  void test();
-}
-class B extends A {
-  void test() {
-    super.test;
-  }
-}
-''');
-    await computeAnalysisResult(source);
-    // TODO(brianwilkerson) It isn't clear what the right semantics are in Dart
-    // 2 (https://github.com/dart-lang/sdk/issues/33951). This test should be
-    // updated when that issue is closed.
-    assertNoErrors(source);
-    verify([source]);
-  }
 }
 
 class PubSuggestionCodeTest extends ResolverTestCase {
diff --git a/pkg/analyzer/test/generated/parser_fasta_listener.dart b/pkg/analyzer/test/generated/parser_fasta_listener.dart
index f6325f8..a39d370 100644
--- a/pkg/analyzer/test/generated/parser_fasta_listener.dart
+++ b/pkg/analyzer/test/generated/parser_fasta_listener.dart
@@ -387,12 +387,6 @@
   }
 
   @override
-  void beginMixinApplication(Token token) {
-    super.beginMixinApplication(token);
-    begin('MixinApplication');
-  }
-
-  @override
   void beginMixinDeclaration(Token mixinKeyword, Token name) {
     super.beginMixinDeclaration(mixinKeyword, name);
     begin('MixinDeclaration');
@@ -898,15 +892,10 @@
   }
 
   @override
-  void endMixinApplication(Token withKeyword) {
-    end('MixinApplication');
-    super.endMixinApplication(withKeyword);
-  }
-
-  @override
-  void endMixinDeclaration(Token token) {
+  void endMixinDeclaration(Token mixinKeyword, Token endToken) {
     end('MixinDeclaration');
-    super.endMixinDeclaration(token);
+    end('ClassOrNamedMixinApplication');
+    super.endMixinDeclaration(mixinKeyword, endToken);
   }
 
   @override
diff --git a/pkg/analyzer/test/generated/parser_fasta_test.dart b/pkg/analyzer/test/generated/parser_fasta_test.dart
index 5b1826d..bf161b0 100644
--- a/pkg/analyzer/test/generated/parser_fasta_test.dart
+++ b/pkg/analyzer/test/generated/parser_fasta_test.dart
@@ -337,7 +337,6 @@
     fasta.Parser parser = new fasta.Parser(null);
     AstBuilder astBuilder = new AstBuilder(errorReporter, source.uri, true);
     parser.listener = astBuilder;
-    parser.isMixinSupportEnabled = true;
     astBuilder.parser = parser;
     astBuilder.allowNativeClause = allowNativeClause;
     parser.parseUnit(_fastaTokens);
@@ -843,6 +842,21 @@
 @reflectiveTest
 class RecoveryParserTest_Fasta extends FastaParserTestCase
     with RecoveryParserTestMixin {
+  void test_invalidTypeParameters_super() {
+    parseCompilationUnit('class C<X super Y> {}', errors: [
+      // TODO(danrubel): Improve recovery.
+      expectedError(ParserErrorCode.EXPECTED_TOKEN, 8, 1),
+      expectedError(ParserErrorCode.MISSING_CLASS_BODY, 10, 5),
+      expectedError(ParserErrorCode.MISSING_CONST_FINAL_VAR_OR_TYPE, 10, 5),
+      expectedError(ParserErrorCode.MISSING_IDENTIFIER, 10, 5),
+      expectedError(ParserErrorCode.EXPECTED_TOKEN, 10, 5),
+      expectedError(ParserErrorCode.MISSING_CONST_FINAL_VAR_OR_TYPE, 16, 1),
+      expectedError(ParserErrorCode.EXPECTED_TOKEN, 16, 1),
+      expectedError(ParserErrorCode.EXPECTED_EXECUTABLE, 17, 1),
+      expectedError(ParserErrorCode.EXPECTED_EXECUTABLE, 19, 1),
+    ]);
+  }
+
   @override
   void test_equalityExpression_precedence_relational_right() {
     parseExpression("== is", codes: [
@@ -966,7 +980,6 @@
 
   void test_parseMixinDeclaration_empty() {
     createParser('mixin A {}');
-    _parserProxy.fastaParser.isMixinSupportEnabled = true;
     MixinDeclaration declaration = parseFullCompilationUnitMember();
     expect(declaration, isNotNull);
     assertNoErrors();
@@ -984,7 +997,6 @@
 
   void test_parseMixinDeclaration_implements() {
     createParser('mixin A implements B {}');
-    _parserProxy.fastaParser.isMixinSupportEnabled = true;
     MixinDeclaration declaration = parseFullCompilationUnitMember();
     expect(declaration, isNotNull);
     assertNoErrors();
@@ -1007,7 +1019,6 @@
 
   void test_parseMixinDeclaration_implements2() {
     createParser('mixin A implements B<T>, C {}');
-    _parserProxy.fastaParser.isMixinSupportEnabled = true;
     MixinDeclaration declaration = parseFullCompilationUnitMember();
     expect(declaration, isNotNull);
     assertNoErrors();
@@ -1032,7 +1043,6 @@
 
   void test_parseMixinDeclaration_metadata() {
     createParser('@Z mixin A {}');
-    _parserProxy.fastaParser.isMixinSupportEnabled = true;
     MixinDeclaration declaration = parseFullCompilationUnitMember();
     expect(declaration, isNotNull);
     assertNoErrors();
@@ -1052,7 +1062,6 @@
 
   void test_parseMixinDeclaration_on() {
     createParser('mixin A on B {}');
-    _parserProxy.fastaParser.isMixinSupportEnabled = true;
     MixinDeclaration declaration = parseFullCompilationUnitMember();
     expect(declaration, isNotNull);
     assertNoErrors();
@@ -1075,7 +1084,6 @@
 
   void test_parseMixinDeclaration_on2() {
     createParser('mixin A on B, C<T> {}');
-    _parserProxy.fastaParser.isMixinSupportEnabled = true;
     MixinDeclaration declaration = parseFullCompilationUnitMember();
     expect(declaration, isNotNull);
     assertNoErrors();
@@ -1100,7 +1108,6 @@
 
   void test_parseMixinDeclaration_onAndImplements() {
     createParser('mixin A on B implements C {}');
-    _parserProxy.fastaParser.isMixinSupportEnabled = true;
     MixinDeclaration declaration = parseFullCompilationUnitMember();
     expect(declaration, isNotNull);
     assertNoErrors();
@@ -1134,7 +1141,6 @@
   set s(int v) {f = v;}
   int add(int v) => f = f + v;
 }''');
-    _parserProxy.fastaParser.isMixinSupportEnabled = true;
     MixinDeclaration declaration = parseFullCompilationUnitMember();
     expect(declaration, isNotNull);
     assertNoErrors();
@@ -1152,7 +1158,6 @@
 
   void test_parseMixinDeclaration_withDocumentationComment() {
     createParser('/// Doc\nmixin M {}');
-    _parserProxy.fastaParser.isMixinSupportEnabled = true;
     MixinDeclaration declaration = parseFullCompilationUnitMember();
     expectCommentText(declaration.documentationComment, '/// Doc');
   }
diff --git a/pkg/analyzer/test/generated/parser_test.dart b/pkg/analyzer/test/generated/parser_test.dart
index 2bbf423..070694e 100644
--- a/pkg/analyzer/test/generated/parser_test.dart
+++ b/pkg/analyzer/test/generated/parser_test.dart
@@ -908,6 +908,25 @@
     expect(method.body, isNotNull);
   }
 
+  void test_parseClassMember_method_get_static_namedAsClass() {
+    createParser('static int get C => 0;');
+    ClassMember member = parser.parseClassMember('C');
+    expect(member, isNotNull);
+    assertNoErrors();
+    expect(member, new TypeMatcher<MethodDeclaration>());
+    MethodDeclaration method = member;
+    expect(method.documentationComment, isNull);
+    expect(method.externalKeyword, isNull);
+    expect(method.modifierKeyword, isNotNull);
+    expect(method.propertyKeyword, isNotNull);
+    expect(method.returnType, isNotNull);
+    expect(method.name, isNotNull);
+    expect(method.operatorKeyword, isNull);
+    expect(method.typeParameters, isNull);
+    expect(method.parameters, isNull);
+    expect(method.body, isNotNull);
+  }
+
   void test_parseClassMember_method_get_type() {
     createParser('int get() {}');
     ClassMember member = parser.parseClassMember('C');
@@ -946,44 +965,6 @@
     expect(method.body, isNotNull);
   }
 
-  void test_parseClassMember_method_get_static_namedAsClass() {
-    createParser('static int get C => 0;');
-    ClassMember member = parser.parseClassMember('C');
-    expect(member, isNotNull);
-    assertNoErrors();
-    expect(member, new TypeMatcher<MethodDeclaration>());
-    MethodDeclaration method = member;
-    expect(method.documentationComment, isNull);
-    expect(method.externalKeyword, isNull);
-    expect(method.modifierKeyword, isNotNull);
-    expect(method.propertyKeyword, isNotNull);
-    expect(method.returnType, isNotNull);
-    expect(method.name, isNotNull);
-    expect(method.operatorKeyword, isNull);
-    expect(method.typeParameters, isNull);
-    expect(method.parameters, isNull);
-    expect(method.body, isNotNull);
-  }
-
-  void test_parseClassMember_method_set_static_namedAsClass() {
-    createParser('static void set C(_) {}');
-    ClassMember member = parser.parseClassMember('C');
-    expect(member, isNotNull);
-    assertNoErrors();
-    expect(member, new TypeMatcher<MethodDeclaration>());
-    MethodDeclaration method = member;
-    expect(method.documentationComment, isNull);
-    expect(method.externalKeyword, isNull);
-    expect(method.modifierKeyword, isNotNull);
-    expect(method.propertyKeyword, isNotNull);
-    expect(method.returnType, isNotNull);
-    expect(method.name, isNotNull);
-    expect(method.operatorKeyword, isNull);
-    expect(method.typeParameters, isNull);
-    expect(method.parameters, isNotNull);
-    expect(method.body, isNotNull);
-  }
-
   void test_parseClassMember_method_gftReturnType_noReturnType() {
     createParser('''
 Function<A>(core.List<core.int> x) m() => null;
@@ -1195,6 +1176,25 @@
     expect(method.body, isNotNull);
   }
 
+  void test_parseClassMember_method_set_static_namedAsClass() {
+    createParser('static void set C(_) {}');
+    ClassMember member = parser.parseClassMember('C');
+    expect(member, isNotNull);
+    assertNoErrors();
+    expect(member, new TypeMatcher<MethodDeclaration>());
+    MethodDeclaration method = member;
+    expect(method.documentationComment, isNull);
+    expect(method.externalKeyword, isNull);
+    expect(method.modifierKeyword, isNotNull);
+    expect(method.propertyKeyword, isNotNull);
+    expect(method.returnType, isNotNull);
+    expect(method.name, isNotNull);
+    expect(method.operatorKeyword, isNull);
+    expect(method.typeParameters, isNull);
+    expect(method.parameters, isNotNull);
+    expect(method.body, isNotNull);
+  }
+
   void test_parseClassMember_method_set_type() {
     createParser('int set() {}');
     ClassMember member = parser.parseClassMember('C');
@@ -1251,8 +1251,8 @@
   }
 
   void test_parseClassMember_method_static_mixin() {
+    if (!usingFastaParser) return;
     var unit = parseCompilationUnit('mixin C { static void m() {} }');
-
     MixinDeclaration c = unit.declarations[0];
     MethodDeclaration method = c.members[0];
     expect(method.documentationComment, isNull);
@@ -3948,6 +3948,18 @@
     expectNotNullIfNoErrors(literal);
   }
 
+  void test_invalidInlineFunctionType() {
+    parseCompilationUnit(
+      'typedef F = int Function(int a());',
+      errors: usingFastaParser
+          ? [
+              expectedError(
+                  CompileTimeErrorCode.INVALID_INLINE_FUNCTION_TYPE, 30, 1)
+            ]
+          : [],
+    );
+  }
+
   void test_invalidInterpolationIdentifier_startWithDigit() {
     StringLiteral literal = parseExpression("'\$1'", errors: [
       usingFastaParser
@@ -5680,8 +5692,7 @@
     createParser('class A with B, C {}');
     ClassDeclaration declaration = parseFullCompilationUnitMember();
     expectNotNullIfNoErrors(declaration);
-    listener.assertErrors(
-        [expectedError(ParserErrorCode.WITH_WITHOUT_EXTENDS, 8, 4)]);
+    listener.assertNoErrors();
   }
 
   void test_wrongSeparatorForPositionalParameter() {
@@ -9405,10 +9416,6 @@
     parser.parseFunctionBodies = parseFunctionBodies;
     parser.enableNnbd = enableNnbd;
     parser.enableOptionalNewAndConst = enableOptionalNewAndConst;
-    if (parser is ParserAdapter) {
-      (parser as ParserAdapter).fastaParser.isMixinSupportEnabled =
-          isMixinSupportEnabled;
-    }
     parser.currentToken = token;
   }
 
@@ -9555,9 +9562,6 @@
 
     Parser parser = new Parser(source, listener);
     parser.enableOptionalNewAndConst = enableOptionalNewAndConst;
-    if (parser is ParserAdapter) {
-      parser.fastaParser.isMixinSupportEnabled = isMixinSupportEnabled;
-    }
     CompilationUnit unit = parser.parseCompilationUnit(token);
     expect(unit, isNotNull);
     if (codes != null) {
@@ -10470,6 +10474,18 @@
     expect(conditionalExpression.thenExpression.isSynthetic, isTrue);
   }
 
+  void test_conditionalExpression_super() {
+    parseExpression('x ? super : z', errors: [
+      expectedError(ParserErrorCode.MISSING_ASSIGNABLE_SELECTOR, 4, 5)
+    ]);
+  }
+
+  void test_conditionalExpression_super2() {
+    parseExpression('x ? z : super', errors: [
+      expectedError(ParserErrorCode.MISSING_ASSIGNABLE_SELECTOR, 8, 5)
+    ]);
+  }
+
   void test_declarationBeforeDirective() {
     CompilationUnit unit = parseCompilationUnit(
         "class foo { } import 'bar.dart';",
@@ -10550,6 +10566,12 @@
         BinaryExpression, expression.leftOperand);
   }
 
+  void test_equalityExpression_superRHS() {
+    parseExpression("1 == super", errors: [
+      expectedError(ParserErrorCode.MISSING_ASSIGNABLE_SELECTOR, 5, 5)
+    ]);
+  }
+
   void test_expressionList_multiple_end() {
     List<Expression> result = parseExpressionList(', 2, 3, 4');
     expectNotNullIfNoErrors(result);
@@ -16183,6 +16205,20 @@
     _assertIsDeclarationName(declaration.typeParameters.typeParameters[0].name);
   }
 
+  void test_parseClassDeclaration_typeParameters_extends_void() {
+    parseCompilationUnit('class C<T extends void>{}',
+        errors: usingFastaParser
+            ? [expectedError(ParserErrorCode.EXPECTED_TYPE_NAME, 18, 4)]
+            : [
+                expectedError(ParserErrorCode.EXPECTED_TYPE_NAME, 18, 4),
+                expectedError(ParserErrorCode.EXPECTED_TOKEN, 18, 4),
+                expectedError(ParserErrorCode.MISSING_CLASS_BODY, 18, 4),
+                expectedError(ParserErrorCode.EXPECTED_EXECUTABLE, 22, 1),
+                expectedError(ParserErrorCode.EXPECTED_EXECUTABLE, 22, 1),
+                expectedError(ParserErrorCode.UNEXPECTED_TOKEN, 22, 1),
+              ]);
+  }
+
   void test_parseClassDeclaration_withDocumentationComment() {
     createParser('/// Doc\nclass C {}');
     var classDeclaration = parseFullCompilationUnitMember() as ClassDeclaration;
diff --git a/pkg/analyzer/test/generated/resolver_test.dart b/pkg/analyzer/test/generated/resolver_test.dart
index 0b44b59..0f806d1 100644
--- a/pkg/analyzer/test/generated/resolver_test.dart
+++ b/pkg/analyzer/test/generated/resolver_test.dart
@@ -49,7 +49,6 @@
     defineReflectiveTests(PrefixedNamespaceTest);
     defineReflectiveTests(ScopeTest);
     defineReflectiveTests(StrictModeTest);
-    defineReflectiveTests(SubtypeManagerTest);
     defineReflectiveTests(TypeOverrideManagerTest);
     defineReflectiveTests(TypePropagationTest);
     defineReflectiveTests(TypeProviderImplTest);
@@ -752,107 +751,6 @@
 }
 
 @reflectiveTest
-class SubtypeManagerTest {
-  /**
-   * The inheritance manager being tested.
-   */
-  SubtypeManager _subtypeManager;
-
-  /**
-   * The compilation unit element containing all of the types setup in each test.
-   */
-  CompilationUnitElementImpl _definingCompilationUnit;
-
-  void setUp() {
-    MemoryResourceProvider resourceProvider = new MemoryResourceProvider();
-    AnalysisContext context = AnalysisContextFactory.contextWithCore(
-        resourceProvider: resourceProvider);
-    Source source = new FileSource(resourceProvider.getFile("/test.dart"));
-    _definingCompilationUnit = new CompilationUnitElementImpl("test.dart");
-    _definingCompilationUnit.librarySource =
-        _definingCompilationUnit.source = source;
-    LibraryElementImpl definingLibrary =
-        ElementFactory.library(context, "test");
-    definingLibrary.definingCompilationUnit = _definingCompilationUnit;
-    _subtypeManager = new SubtypeManager();
-  }
-
-  void test_computeAllSubtypes_infiniteLoop() {
-    //
-    // class A extends B
-    // class B extends A
-    //
-    ClassElementImpl classA = ElementFactory.classElement2("A");
-    ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
-    classA.supertype = classB.type;
-    _definingCompilationUnit.types = <ClassElement>[classA, classB];
-    HashSet<ClassElement> subtypesOfA =
-        _subtypeManager.computeAllSubtypes(classA);
-    List<ClassElement> arraySubtypesOfA = new List.from(subtypesOfA);
-    expect(subtypesOfA, hasLength(2));
-    expect(arraySubtypesOfA, unorderedEquals([classA, classB]));
-  }
-
-  void test_computeAllSubtypes_manyRecursiveSubtypes() {
-    //
-    // class A
-    // class B extends A
-    // class C extends B
-    // class D extends B
-    // class E extends B
-    //
-    ClassElementImpl classA = ElementFactory.classElement2("A");
-    ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
-    ClassElementImpl classC = ElementFactory.classElement("C", classB.type);
-    ClassElementImpl classD = ElementFactory.classElement("D", classB.type);
-    ClassElementImpl classE = ElementFactory.classElement("E", classB.type);
-    _definingCompilationUnit.types = <ClassElement>[
-      classA,
-      classB,
-      classC,
-      classD,
-      classE
-    ];
-    HashSet<ClassElement> subtypesOfA =
-        _subtypeManager.computeAllSubtypes(classA);
-    List<ClassElement> arraySubtypesOfA = new List.from(subtypesOfA);
-    HashSet<ClassElement> subtypesOfB =
-        _subtypeManager.computeAllSubtypes(classB);
-    List<ClassElement> arraySubtypesOfB = new List.from(subtypesOfB);
-    expect(subtypesOfA, hasLength(4));
-    expect(arraySubtypesOfA, unorderedEquals([classB, classC, classD, classE]));
-    expect(subtypesOfB, hasLength(3));
-    expect(arraySubtypesOfB, unorderedEquals([classC, classD, classE]));
-  }
-
-  void test_computeAllSubtypes_noSubtypes() {
-    //
-    // class A
-    //
-    ClassElementImpl classA = ElementFactory.classElement2("A");
-    _definingCompilationUnit.types = <ClassElement>[classA];
-    HashSet<ClassElement> subtypesOfA =
-        _subtypeManager.computeAllSubtypes(classA);
-    expect(subtypesOfA, hasLength(0));
-  }
-
-  void test_computeAllSubtypes_oneSubtype() {
-    //
-    // class A
-    // class B extends A
-    //
-    ClassElementImpl classA = ElementFactory.classElement2("A");
-    ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
-    _definingCompilationUnit.types = <ClassElement>[classA, classB];
-    HashSet<ClassElement> subtypesOfA =
-        _subtypeManager.computeAllSubtypes(classA);
-    List<ClassElement> arraySubtypesOfA = new List.from(subtypesOfA);
-    expect(subtypesOfA, hasLength(1));
-    expect(arraySubtypesOfA, unorderedEquals([classB]));
-  }
-}
-
-@reflectiveTest
 class TypeOverrideManagerTest extends EngineTestCase {
   void test_exitScope_noScopes() {
     TypeOverrideManager manager = new TypeOverrideManager();
diff --git a/pkg/analyzer/test/generated/static_type_warning_code_test.dart b/pkg/analyzer/test/generated/static_type_warning_code_test.dart
index e650103..ec2a320 100644
--- a/pkg/analyzer/test/generated/static_type_warning_code_test.dart
+++ b/pkg/analyzer/test/generated/static_type_warning_code_test.dart
@@ -533,42 +533,6 @@
 ''', [StaticTypeWarningCode.ILLEGAL_SYNC_GENERATOR_RETURN_TYPE]);
   }
 
-  test_inconsistentMethodInheritance_paramCount() async {
-    await assertErrorsInCode(r'''
-abstract class A {
-  int x();
-}
-abstract class B {
-  int x(int y);
-}
-class C implements A, B {
-}''', [StaticTypeWarningCode.INCONSISTENT_METHOD_INHERITANCE]);
-  }
-
-  test_inconsistentMethodInheritance_paramType() async {
-    await assertErrorsInCode(r'''
-abstract class A {
-  x(int i);
-}
-abstract class B {
-  x(String s);
-}
-abstract class C implements A, B {}
-''', [StaticTypeWarningCode.INCONSISTENT_METHOD_INHERITANCE]);
-  }
-
-  test_inconsistentMethodInheritance_returnType() async {
-    await assertErrorsInCode(r'''
-abstract class A {
-  int x();
-}
-abstract class B {
-  String x();
-}
-abstract class C implements A, B {}
-''', [StaticTypeWarningCode.INCONSISTENT_METHOD_INHERITANCE]);
-  }
-
   test_instanceAccessToStaticMember_method_invocation() async {
     await assertErrorsInCode(r'''
 class A {
@@ -1769,81 +1733,6 @@
 }''', [StaticTypeWarningCode.UNDEFINED_SETTER]);
   }
 
-  test_undefinedSuperGetter() async {
-    await assertErrorsInCode(r'''
-class A {}
-class B extends A {
-  get g {
-    return super.g;
-  }
-}''', [StaticTypeWarningCode.UNDEFINED_SUPER_GETTER]);
-  }
-
-  test_undefinedSuperMethod() async {
-    await assertErrorsInCode(r'''
-class A {}
-class B extends A {
-  m() { return super.m(); }
-}''', [StaticTypeWarningCode.UNDEFINED_SUPER_METHOD]);
-  }
-
-  test_undefinedSuperOperator_binaryExpression() async {
-    await assertErrorsInUnverifiedCode(r'''
-class A {}
-class B extends A {
-  operator +(value) {
-    return super + value;
-  }
-}''', [StaticTypeWarningCode.UNDEFINED_SUPER_OPERATOR]);
-  }
-
-  test_undefinedSuperOperator_indexBoth() async {
-    await assertErrorsInUnverifiedCode(r'''
-class A {}
-class B extends A {
-  operator [](index) {
-    return super[index]++;
-  }
-}''', [StaticTypeWarningCode.UNDEFINED_SUPER_OPERATOR]);
-  }
-
-  test_undefinedSuperOperator_indexGetter() async {
-    await assertErrorsInUnverifiedCode(r'''
-class A {}
-class B extends A {
-  operator [](index) {
-    return super[index + 1];
-  }
-}''', [StaticTypeWarningCode.UNDEFINED_SUPER_OPERATOR]);
-  }
-
-  test_undefinedSuperOperator_indexSetter() async {
-    await assertErrorsInUnverifiedCode(
-        r'''
-class A {}
-class B extends A {
-  operator []=(index, value) {
-    return super[index] = 0;
-  }
-}''',
-        previewDart2
-            ? [
-                StaticTypeWarningCode.RETURN_OF_INVALID_TYPE,
-                StaticTypeWarningCode.UNDEFINED_SUPER_OPERATOR
-              ]
-            : [StaticTypeWarningCode.UNDEFINED_SUPER_OPERATOR]);
-  }
-
-  test_undefinedSuperSetter() async {
-    await assertErrorsInCode(r'''
-class A {}
-class B extends A {
-  f() {
-    super.m = 0;
-  }
-}''', [StaticTypeWarningCode.UNDEFINED_SUPER_SETTER]);
-  }
-
   test_unqualifiedReferenceToNonLocalStaticMember_getter() async {
     await assertErrorsInCode(r'''
 class A {
diff --git a/pkg/analyzer/test/generated/static_warning_code_test.dart b/pkg/analyzer/test/generated/static_warning_code_test.dart
index 8ee7ee7..b29d20d 100644
--- a/pkg/analyzer/test/generated/static_warning_code_test.dart
+++ b/pkg/analyzer/test/generated/static_warning_code_test.dart
@@ -37,14 +37,6 @@
     verify([source]);
   }
 
-  fail_undefinedGetter() async {
-    Source source = addSource(r'''
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [StaticWarningCode.UNDEFINED_GETTER]);
-    verify([source]);
-  }
-
   fail_undefinedIdentifier_commentReference() async {
     Source source = addSource(r'''
 /** [m] xxx [new B.c] */
@@ -57,17 +49,6 @@
     ]);
   }
 
-  fail_undefinedSetter() async {
-    Source source = addSource(r'''
-class C {}
-f(var p) {
-  C.m = 0;
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [StaticWarningCode.UNDEFINED_SETTER]);
-    verify([source]);
-  }
-
   test_ambiguousImport_as() async {
     Source source = addSource(r'''
 import 'lib1.dart';
@@ -982,122 +963,6 @@
     verify([source]);
   }
 
-  test_conflictingInstanceMethodSetter2() async {
-    Source source = addSource(r'''
-class A {
-  foo() {}
-  set foo(a) {}
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [StaticWarningCode.CONFLICTING_INSTANCE_METHOD_SETTER2]);
-    verify([source]);
-  }
-
-  test_conflictingInstanceMethodSetter_sameClass() async {
-    Source source = addSource(r'''
-class A {
-  set foo(a) {}
-  foo() {}
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [StaticWarningCode.CONFLICTING_INSTANCE_METHOD_SETTER]);
-    verify([source]);
-  }
-
-  test_conflictingInstanceMethodSetter_setterInInterface() async {
-    Source source = addSource(r'''
-abstract class A {
-  set foo(a);
-}
-abstract class B implements A {
-  foo() {}
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [StaticWarningCode.CONFLICTING_INSTANCE_METHOD_SETTER]);
-    verify([source]);
-  }
-
-  test_conflictingInstanceMethodSetter_setterInSuper() async {
-    Source source = addSource(r'''
-class A {
-  set foo(a) {}
-}
-class B extends A {
-  foo() {}
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [StaticWarningCode.CONFLICTING_INSTANCE_METHOD_SETTER]);
-    verify([source]);
-  }
-
-  test_conflictingStaticGetterAndInstanceSetter_mixin() async {
-    Source source = addSource(r'''
-class A {
-  set x(int p) {}
-}
-class B extends Object with A {
-  static get x => 0;
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source,
-        [StaticWarningCode.CONFLICTING_STATIC_GETTER_AND_INSTANCE_SETTER]);
-    verify([source]);
-  }
-
-  test_conflictingStaticGetterAndInstanceSetter_superClass() async {
-    Source source = addSource(r'''
-class A {
-  set x(int p) {}
-}
-class B extends A {
-  static get x => 0;
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source,
-        [StaticWarningCode.CONFLICTING_STATIC_GETTER_AND_INSTANCE_SETTER]);
-    verify([source]);
-  }
-
-  test_conflictingStaticGetterAndInstanceSetter_thisClass() async {
-    Source source = addSource(r'''
-class A {
-  static get x => 0;
-  set x(int p) {}
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source,
-        [StaticWarningCode.CONFLICTING_STATIC_GETTER_AND_INSTANCE_SETTER]);
-    verify([source]);
-  }
-
-  test_conflictingStaticSetterAndInstanceMember_thisClass_getter() async {
-    Source source = addSource(r'''
-class A {
-  get x => 0;
-  static set x(int p) {}
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source,
-        [StaticWarningCode.CONFLICTING_STATIC_SETTER_AND_INSTANCE_MEMBER]);
-    verify([source]);
-  }
-
-  test_conflictingStaticSetterAndInstanceMember_thisClass_method() async {
-    Source source = addSource(r'''
-class A {
-  x() {}
-  static set x(int p) {}
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source,
-        [StaticWarningCode.CONFLICTING_STATIC_SETTER_AND_INSTANCE_MEMBER]);
-    verify([source]);
-  }
-
   test_constWithAbstractClass() async {
     Source source = addSource(r'''
 abstract class A {
@@ -1959,22 +1824,6 @@
     ]);
   }
 
-  test_inconsistentMethodInheritanceGetterAndMethod() async {
-    Source source = addSource(r'''
-abstract class A {
-  int x();
-}
-abstract class B {
-  int get x;
-}
-class C implements A, B {
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source,
-        [StaticWarningCode.INCONSISTENT_METHOD_INHERITANCE_GETTER_AND_METHOD]);
-    verify([source]);
-  }
-
   test_invalidGetterOverrideReturnType() async {
     Source source = addSource(r'''
 class A {
@@ -4029,19 +3878,6 @@
     assertErrors(source, [StaticWarningCode.UNDEFINED_CLASS_BOOLEAN]);
   }
 
-  test_undefinedGetter_fromLibrary() async {
-    Source source1 = addNamedSource("/lib.dart", "");
-    Source source2 = addNamedSource("/lib2.dart", r'''
-import 'lib.dart' as lib;
-void f() {
-  var g = lib.gg;
-}''');
-    await computeAnalysisResult(source1);
-    await computeAnalysisResult(source2);
-    assertErrors(source2, [StaticWarningCode.UNDEFINED_GETTER]);
-    verify([source1]);
-  }
-
   test_undefinedIdentifier_for() async {
     Source source = addSource(r'''
 f(var l) {
@@ -4132,17 +3968,6 @@
     // no verify(), 'c' is not resolved
   }
 
-  test_undefinedSetter() async {
-    addNamedSource("/lib.dart", "");
-    Source source2 = addNamedSource("/lib2.dart", r'''
-import 'lib.dart' as lib;
-void f() {
-  lib.gg = null;
-}''');
-    await computeAnalysisResult(source2);
-    assertErrors(source2, [StaticWarningCode.UNDEFINED_SETTER]);
-  }
-
   test_undefinedStaticMethodOrGetter_getter() async {
     Source source = addSource(r'''
 class C {}
diff --git a/pkg/analyzer/test/source/error_processor_test.dart b/pkg/analyzer/test/source/error_processor_test.dart
index 7a1f208..5ceb965 100644
--- a/pkg/analyzer/test/source/error_processor_test.dart
+++ b/pkg/analyzer/test/source/error_processor_test.dart
@@ -39,8 +39,8 @@
     ['x']
   ]);
 
-  AnalysisError non_bool_operand = new AnalysisError(
-      new TestSource(), 0, 1, StaticTypeWarningCode.NON_BOOL_OPERAND, [
+  AnalysisError assignment_no_type = new AnalysisError(
+      new TestSource(), 0, 1, StaticWarningCode.ASSIGNMENT_TO_TYPE, [
     ['x']
   ]);
 
@@ -71,12 +71,12 @@
       expect(getProcessor(use_of_void_result), isNotNull);
     });
 
-    test('upgrades static type warnings to errors in strong mode', () {
+    test('upgrades static warnings to errors in strong mode', () {
       configureOptions('''
 analyzer:
   strong-mode: true
 ''');
-      expect(getProcessor(non_bool_operand).severity, ErrorSeverity.ERROR);
+      expect(getProcessor(assignment_no_type).severity, ErrorSeverity.ERROR);
     });
 
     test('does not upgrade other warnings to errors in strong mode', () {
diff --git a/pkg/analyzer/test/src/dart/analysis/driver_resolution_test.dart b/pkg/analyzer/test/src/dart/analysis/driver_resolution_test.dart
index 57c42eb..7841c96 100644
--- a/pkg/analyzer/test/src/dart/analysis/driver_resolution_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/driver_resolution_test.dart
@@ -927,8 +927,9 @@
 
   test_binaryExpression_ifNull() async {
     String content = r'''
+int x = 3;
 main() {
-  1.2 ?? 3;
+  1.2 ?? x;
 }
 ''';
     addTestFile(content);
diff --git a/pkg/analyzer/test/src/dart/analysis/driver_test.dart b/pkg/analyzer/test/src/dart/analysis/driver_test.dart
index d8db996..ca03d8e 100644
--- a/pkg/analyzer/test/src/dart/analysis/driver_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/driver_test.dart
@@ -909,7 +909,7 @@
     // Notify the driver about the change.
     driver.changeFile(testFile);
 
-    // The file was added, so it is scheduled for analysis.
+    // The file was changed, so it is scheduled for analysis.
     expect(driver.test.fileTracker.isFilePending(testFile), isTrue);
 
     // We get a new result.
diff --git a/pkg/analyzer/test/src/dart/analysis/file_state_test.dart b/pkg/analyzer/test/src/dart/analysis/file_state_test.dart
index 990c2f8..0379c6b 100644
--- a/pkg/analyzer/test/src/dart/analysis/file_state_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/file_state_test.dart
@@ -58,8 +58,15 @@
       new ResourceUriResolver(provider)
     ], null, provider);
     AnalysisOptions analysisOptions = new AnalysisOptionsImpl();
-    fileSystemState = new FileSystemState(logger, byteStore, contentOverlay,
-        provider, sourceFactory, analysisOptions, new Uint32List(0));
+    fileSystemState = new FileSystemState(
+        logger,
+        byteStore,
+        contentOverlay,
+        provider,
+        sourceFactory,
+        analysisOptions,
+        new Uint32List(0),
+        new Uint32List(0));
   }
 
   test_definedClassMemberNames() {
@@ -351,6 +358,7 @@
     expect(_excludeSdk(file.importedFiles), isEmpty);
     expect(file.exportedFiles, isEmpty);
     expect(file.partedFiles, isEmpty);
+    expect(file.libraryFiles, [file]);
     expect(_excludeSdk(file.directReferencedFiles), isEmpty);
     expect(file.isPart, isFalse);
     expect(file.library, isNull);
@@ -469,6 +477,8 @@
     expect(file.partedFiles[0].path, a4);
     expect(file.partedFiles[0].uri, Uri.parse('package:aaa/a4.dart'));
 
+    expect(file.libraryFiles, [file, file.partedFiles[0]]);
+
     expect(_excludeSdk(file.directReferencedFiles), hasLength(5));
 
     expect(fileSystemState.getFilesForPath(a1), [file]);
@@ -651,22 +661,6 @@
     expect(file.apiSignature, signature);
   }
 
-  test_store_zeroLengthUnlinked() {
-    String path = _p('/test.dart');
-    provider.newFile(path, 'class A {}');
-
-    // Get the file, prepare unlinked.
-    FileState file = fileSystemState.getFileForPath(path);
-    expect(file.unlinked, isNotNull);
-
-    // Make the unlinked unit in the byte store zero-length, damaged.
-    byteStore.put(file.test.unlinkedKey, <int>[]);
-
-    // Refresh should not fail, zero bytes in the store are ignored.
-    file.refresh();
-    expect(file.unlinked, isNotNull);
-  }
-
   test_subtypedNames() {
     String path = _p('/test.dart');
     provider.newFile(path, r'''
diff --git a/pkg/analyzer/test/src/dart/analysis/index_test.dart b/pkg/analyzer/test/src/dart/analysis/index_test.dart
index 9a28fc6..179e4c4 100644
--- a/pkg/analyzer/test/src/dart/analysis/index_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/index_test.dart
@@ -101,6 +101,27 @@
     assertThat(classElementB)..isAncestorOf('C2 = Object with B');
   }
 
+  test_hasAncestor_MixinDeclaration() async {
+    await _indexTestUnit('''
+class A {}
+class B extends A {}
+
+mixin M1 on A {}
+mixin M2 on B {}
+mixin M3 implements A {}
+mixin M4 implements B {}
+mixin M5 on M2 {}
+''');
+    ClassElement classElementA = findElement('A');
+    assertThat(classElementA)
+      ..isAncestorOf('B extends A')
+      ..isAncestorOf('M1 on A')
+      ..isAncestorOf('M2 on B')
+      ..isAncestorOf('M3 implements A')
+      ..isAncestorOf('M4 implements B')
+      ..isAncestorOf('M5 on M2');
+  }
+
   test_isExtendedBy_ClassDeclaration() async {
     await _indexTestUnit('''
 class A {} // 1
@@ -1058,6 +1079,35 @@
     expect(X.members, ['foo']);
   }
 
+  test_subtypes_mixinDeclaration() async {
+    String libP = 'package:test/lib.dart;package:test/lib.dart';
+    provider.newFile(_p('$testProject/lib.dart'), '''
+class A {}
+class B {}
+class C {}
+class D {}
+class E {}
+''');
+    await _indexTestUnit('''
+import 'lib.dart';
+
+mixin X on A implements B, C {}
+mixin Y on A, B implements C;
+''');
+
+    {
+      var X = index.subtypes.singleWhere((t) => t.name == 'X');
+      expect(X.supertypes, ['$libP;A', '$libP;B', '$libP;C']);
+      expect(X.members, isEmpty);
+    }
+
+    {
+      var Y = index.subtypes.singleWhere((t) => t.name == 'Y');
+      expect(Y.supertypes, ['$libP;A', '$libP;B', '$libP;C']);
+      expect(Y.members, isEmpty);
+    }
+  }
+
   test_usedName_inLibraryIdentifier() async {
     await _indexTestUnit('''
 library aaa.bbb.ccc;
diff --git a/pkg/analyzer/test/src/dart/analysis/test_all.dart b/pkg/analyzer/test/src/dart/analysis/test_all.dart
index 7c74b6b..f4f9c49 100644
--- a/pkg/analyzer/test/src/dart/analysis/test_all.dart
+++ b/pkg/analyzer/test/src/dart/analysis/test_all.dart
@@ -18,6 +18,7 @@
 import 'search_test.dart' as search;
 import 'session_helper_test.dart' as session_helper;
 import 'session_test.dart' as session;
+import 'unlinked_api_signature_test.dart' as unlinked_api_signature;
 import 'uri_converter_test.dart' as uri_converter;
 
 main() {
@@ -36,6 +37,7 @@
     search.main();
     session_helper.main();
     session.main();
+    unlinked_api_signature.main();
     uri_converter.main();
   }, name: 'analysis');
 }
diff --git a/pkg/analyzer/test/src/dart/analysis/unlinked_api_signature_test.dart b/pkg/analyzer/test/src/dart/analysis/unlinked_api_signature_test.dart
new file mode 100644
index 0000000..dae6df2
--- /dev/null
+++ b/pkg/analyzer/test/src/dart/analysis/unlinked_api_signature_test.dart
@@ -0,0 +1,834 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for 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:typed_data';
+
+import 'package:analyzer/file_system/file_system.dart';
+import 'package:analyzer/src/dart/analysis/file_state.dart';
+import 'package:analyzer/src/file_system/file_system.dart';
+import 'package:analyzer/src/generated/engine.dart' show AnalysisOptionsImpl;
+import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/source/package_map_resolver.dart';
+import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
+import 'package:front_end/src/api_prototype/byte_store.dart';
+import 'package:front_end/src/base/performance_logger.dart';
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../../context/mock_sdk.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(UnitApiSignatureTest);
+  });
+}
+
+@reflectiveTest
+class UnitApiSignatureTest extends Object with ResourceProviderMixin {
+  FileSystemState fileSystemState;
+
+  Future<Null> assertNotSameSignature(String oldCode, String newCode) async {
+    assertSignature(oldCode, newCode, same: false);
+  }
+
+  Future<Null> assertSameSignature(String oldCode, String newCode) async {
+    assertSignature(oldCode, newCode, same: true);
+  }
+
+  Future<Null> assertSignature(String oldCode, String newCode,
+      {bool same}) async {
+    var path = convertPath('/test.dart');
+
+    newFile(path, content: oldCode);
+    var file = fileSystemState.getFileForPath(path);
+    var lastSignature = file.apiSignature;
+
+    newFile(path, content: newCode);
+    await file.refresh();
+
+    var newSignature = file.apiSignature;
+    if (same) {
+      expect(newSignature, lastSignature);
+    } else {
+      expect(newSignature, isNot(lastSignature));
+    }
+  }
+
+  void setUp() {
+    var sdk = new MockSdk(resourceProvider: resourceProvider);
+    var sourceFactory = new SourceFactory([
+      new DartUriResolver(sdk),
+      new PackageMapUriResolver(resourceProvider, <String, List<Folder>>{
+        'aaa': [getFolder('/aaa/lib')],
+        'bbb': [getFolder('/bbb/lib')],
+      }),
+      new ResourceUriResolver(resourceProvider)
+    ], null, resourceProvider);
+    fileSystemState = new FileSystemState(
+        new PerformanceLog(new StringBuffer()),
+        new MemoryByteStore(),
+        new FileContentOverlay(),
+        resourceProvider,
+        sourceFactory,
+        new AnalysisOptionsImpl(),
+        new Uint32List(0),
+        new Uint32List(0));
+  }
+
+  test_class_annotation() async {
+    await assertNotSameSignature(r'''
+const a = 0;
+
+class C {}
+''', r'''
+const a = 0;
+
+@a
+class C {}
+''');
+  }
+
+  test_class_constructor_block_to_empty() async {
+    await assertSameSignature(r'''
+class C {
+  C() {
+    var v = 1;
+  }
+}
+''', r'''
+class C {
+  C();
+}
+''');
+  }
+
+  test_class_constructor_body() async {
+    await assertSameSignature(r'''
+class C {
+  C() {
+    var v = 1;
+  }
+}
+''', r'''
+class C {
+  C() {
+    var v = 2;
+  }
+}
+''');
+  }
+
+  test_class_constructor_empty_to_block() async {
+    await assertSameSignature(r'''
+class C {
+  C();
+}
+''', r'''
+class C {
+  C() {
+    var v = 1;
+  }
+}
+''');
+  }
+
+  test_class_constructor_initializer_const() async {
+    await assertNotSameSignature(r'''
+class C {
+  final int f;
+  const C() : f = 1;
+}
+''', r'''
+class C {
+  final int f;
+  const C() : f = 2;
+}
+''');
+  }
+
+  test_class_constructor_initializer_empty() async {
+    await assertSameSignature(r'''
+class C {
+  C.foo() : ;
+}
+''', r'''
+class C {
+  C.foo() : f;
+}
+''');
+  }
+
+  test_class_constructor_initializer_notConst() async {
+    await assertSameSignature(r'''
+class C {
+  final int f;
+  C.foo() : f = 1;
+  const C.bar();
+}
+''', r'''
+class C {
+  final int f;
+  C.foo() : f = 2;
+  const C.bar();
+}
+''');
+  }
+
+  test_class_constructor_parameters_add() async {
+    await assertNotSameSignature(r'''
+class C {
+  C(int a);
+}
+''', r'''
+class C {
+  C(int a, int b);
+}
+''');
+  }
+
+  test_class_constructor_parameters_remove() async {
+    await assertNotSameSignature(r'''
+class C {
+  C(int a, int b);
+}
+''', r'''
+class C {
+  C(int a);
+}
+''');
+  }
+
+  test_class_constructor_parameters_rename() async {
+    await assertNotSameSignature(r'''
+class C {
+  C(int a);
+}
+''', r'''
+class C {
+  C(int b);
+}
+''');
+  }
+
+  test_class_constructor_parameters_type() async {
+    await assertNotSameSignature(r'''
+class C {
+  C(int p);
+}
+''', r'''
+class C {
+  C(double p);
+}
+''');
+  }
+
+  test_class_extends() async {
+    await assertNotSameSignature(r'''
+class A {}
+class B {}
+''', r'''
+class A {}
+class B extends A {}
+''');
+  }
+
+  test_class_field_withoutType() async {
+    await assertNotSameSignature(r'''
+class C {
+  var a = 1;
+}
+''', r'''
+class C {
+  var a = 2;
+}
+''');
+  }
+
+  test_class_field_withoutType2() async {
+    await assertNotSameSignature(r'''
+class C {
+  var a = 1, b = 2, c, d = 4;
+}
+''', r'''
+class C {
+  var a = 1, b, c = 3, d = 4;
+}
+''');
+  }
+
+  test_class_field_withType() async {
+    await assertSameSignature(r'''
+class C {
+  int a = 1, b, c = 3;
+}
+''', r'''
+class C {
+  int a = 0, b = 2, c;
+}
+''');
+  }
+
+  test_class_field_withType_const() async {
+    await assertNotSameSignature(r'''
+class C {
+  static const int a = 1;
+}
+''', r'''
+class C {
+  static const int a = 2;
+}
+''');
+  }
+
+  test_class_field_withType_final_hasConstConstructor() async {
+    await assertNotSameSignature(r'''
+class C {
+  final int a = 1;
+  const C();
+}
+''', r'''
+class C {
+  final int a = 2;
+  const C();
+}
+''');
+  }
+
+  test_class_field_withType_final_noConstConstructor() async {
+    await assertSameSignature(r'''
+class C {
+  final int a = 1;
+}
+''', r'''
+class C {
+  final int a = 2;
+}
+''');
+  }
+
+  test_class_implements() async {
+    await assertNotSameSignature(r'''
+class A {}
+class B {}
+''', r'''
+class A {}
+class B implements A {}
+''');
+  }
+
+  test_class_method_annotation() async {
+    await assertNotSameSignature(r'''
+const a = 0;
+
+class C {
+  void foo() {}
+}
+''', r'''
+const a = 0;
+
+class C {
+  @a
+  void foo() {}
+}
+''');
+  }
+
+  test_class_method_body_async_to_sync() async {
+    await assertSameSignature(r'''
+class C {
+  Future foo() async {}
+}
+''', r'''
+class C {
+  Future foo() {}
+}
+''');
+  }
+
+  test_class_method_body_block() async {
+    await assertSameSignature(r'''
+class C {
+  int foo() {
+    return 1;
+  }
+}
+''', r'''
+class C {
+  int foo() {
+    return 2;
+  }
+}
+''');
+  }
+
+  test_class_method_body_block_to_expression() async {
+    await assertSameSignature(r'''
+class C {
+  int foo() {
+    return 1;
+  }
+}
+''', r'''
+class C {
+  int foo() => 2;
+}
+''');
+  }
+
+  test_class_method_body_empty_to_block() async {
+    await assertSameSignature(r'''
+class C {
+  int foo();
+}
+''', r'''
+class C {
+  int foo() {
+    var v = 0;
+  }
+}
+''');
+  }
+
+  test_class_method_body_expression() async {
+    await assertSameSignature(r'''
+class C {
+  int foo() => 1;
+}
+''', r'''
+class C {
+  int foo() => 2;
+}
+''');
+  }
+
+  test_class_method_body_sync_to_async() async {
+    await assertSameSignature(r'''
+class C {
+  Future foo() {}
+}
+''', r'''
+class C {
+  Future foo() async {}
+}
+''');
+  }
+
+  test_class_method_getter_body_block_to_expression() async {
+    await assertSameSignature(r'''
+class C {
+  int get foo {
+    return 1;
+  }
+}
+''', r'''
+class C {
+  int get foo => 2;
+}
+''');
+  }
+
+  test_class_method_getter_body_empty_to_expression() async {
+    await assertSameSignature(r'''
+class C {
+  int get foo;
+}
+''', r'''
+class C {
+  int get foo => 2;
+}
+''');
+  }
+
+  test_class_method_parameters_add() async {
+    await assertNotSameSignature(r'''
+class C {
+  foo(int a) {}
+}
+''', r'''
+class C {
+  foo(int a, int b) {}
+}
+''');
+  }
+
+  test_class_method_parameters_remove() async {
+    await assertNotSameSignature(r'''
+class C {
+  foo(int a, int b) {}
+}
+''', r'''
+class C {
+  foo(int a) {}
+}
+''');
+  }
+
+  test_class_method_parameters_rename() async {
+    await assertNotSameSignature(r'''
+class C {
+  void foo(int a) {}
+}
+''', r'''
+class C {
+  void foo(int b) {}
+}
+''');
+  }
+
+  test_class_method_parameters_type() async {
+    await assertNotSameSignature(r'''
+class C {
+  void foo(int p) {}
+}
+''', r'''
+class C {
+  void foo(double p) {}
+}
+''');
+  }
+
+  test_class_method_returnType() async {
+    await assertNotSameSignature(r'''
+class C {
+  int foo() => 0;
+}
+''', r'''
+class C {
+  num foo() => 0;
+}
+''');
+  }
+
+  test_class_method_typeParameters_add() async {
+    await assertNotSameSignature(r'''
+class C {
+  void foo() {}
+}
+''', r'''
+class C {
+  void foo<T>() {}
+}
+''');
+  }
+
+  test_class_method_typeParameters_remove() async {
+    await assertNotSameSignature(r'''
+class C {
+  void foo<T>() {}
+}
+''', r'''
+class C {
+  void foo() {}
+}
+''');
+  }
+
+  test_class_method_typeParameters_rename() async {
+    await assertNotSameSignature(r'''
+class C {
+  void foo<T>() {}
+}
+''', r'''
+class C {
+  void foo<U>() {}
+}
+''');
+  }
+
+  test_class_modifier() async {
+    await assertNotSameSignature(r'''
+class C {}
+''', r'''
+abstract class C {}
+''');
+  }
+
+  test_class_with() async {
+    await assertNotSameSignature(r'''
+class A {}
+class B {}
+class C extends A {}
+''', r'''
+class A {}
+class B {}
+class C extends A with B {}
+''');
+  }
+
+  test_commentAdd() async {
+    await assertSameSignature(r'''
+var a = 1;
+var b = 2;
+var c = 3;
+''', r'''
+var a = 1; // comment
+
+/// comment 1
+/// comment 2
+var b = 2;
+
+/**
+ *  Comment
+ */
+var c = 3;
+''');
+  }
+
+  test_commentRemove() async {
+    await assertSameSignature(r'''
+var a = 1; // comment
+
+/// comment 1
+/// comment 2
+var b = 2;
+
+/**
+ *  Comment
+ */
+var c = 3;
+''', r'''
+var a = 1;
+var b = 2;
+var c = 3;
+''');
+  }
+
+  test_function_annotation() async {
+    await assertNotSameSignature(r'''
+const a = 0;
+
+void foo() {}
+''', r'''
+const a = 0;
+
+@a
+void foo() {}
+''');
+  }
+
+  test_function_body_async_to_sync() async {
+    await assertSameSignature(r'''
+Future foo() async {}
+''', r'''
+Future foo() {}
+''');
+  }
+
+  test_function_body_block() async {
+    await assertSameSignature(r'''
+int foo() {
+  return 1;
+}
+''', r'''
+int foo() {
+  return 2;
+}
+''');
+  }
+
+  test_function_body_block_to_expression() async {
+    await assertSameSignature(r'''
+int foo() {
+  return 1;
+}
+''', r'''
+int foo() => 2;
+''');
+  }
+
+  test_function_body_expression() async {
+    await assertSameSignature(r'''
+int foo() => 1;
+''', r'''
+int foo() => 2;
+''');
+  }
+
+  test_function_body_sync_to_async() async {
+    await assertSameSignature(r'''
+Future foo() {}
+''', r'''
+Future foo() async {}
+''');
+  }
+
+  test_function_getter_block_to_expression() async {
+    await assertSameSignature(r'''
+int get foo {
+  return 1;
+}
+''', r'''
+int get foo => 2;
+''');
+  }
+
+  test_function_parameters_rename() async {
+    await assertNotSameSignature(r'''
+void foo(int a) {}
+''', r'''
+void foo(int b) {}
+''');
+  }
+
+  test_function_parameters_type() async {
+    await assertNotSameSignature(r'''
+void foo(int p) {}
+''', r'''
+void foo(double p) {}
+''');
+  }
+
+  test_function_returnType() async {
+    await assertNotSameSignature(r'''
+int foo() => 0;
+''', r'''
+num foo() => 0;
+''');
+  }
+
+  test_function_typeParameters_add() async {
+    await assertNotSameSignature(r'''
+void foo() {}
+''', r'''
+void foo<T>() {}
+''');
+  }
+
+  test_function_typeParameters_remove() async {
+    await assertNotSameSignature(r'''
+void foo<T>() {}
+''', r'''
+void foo() {}
+''');
+  }
+
+  test_function_typeParameters_rename() async {
+    await assertNotSameSignature(r'''
+void foo<T>() {}
+''', r'''
+void foo<U>() {}
+''');
+  }
+
+  test_mixin_field_withoutType() async {
+    await assertNotSameSignature(r'''
+mixin M {
+  var a = 1;
+}
+''', r'''
+mixin M {
+  var a = 2;
+}
+''');
+  }
+
+  test_mixin_field_withType() async {
+    await assertSameSignature(r'''
+mixin M {
+  int a = 1, b, c = 3;
+}
+''', r'''
+mixin M {
+  int a = 0, b = 2, c;
+}
+''');
+  }
+
+  test_mixin_implements() async {
+    await assertNotSameSignature(r'''
+class A {}
+mixin M {}
+''', r'''
+class A {}
+mixin M implements A {}
+''');
+  }
+
+  test_mixin_method_body_block() async {
+    await assertSameSignature(r'''
+mixin M {
+  int foo() {
+    return 1;
+  }
+}
+''', r'''
+mixin M {
+  int foo() {
+    return 2;
+  }
+}
+''');
+  }
+
+  test_mixin_method_body_expression() async {
+    await assertSameSignature(r'''
+mixin M {
+  int foo() => 1;
+}
+''', r'''
+mixin M {
+  int foo() => 2;
+}
+''');
+  }
+
+  test_mixin_on() async {
+    await assertNotSameSignature(r'''
+class A {}
+mixin M {}
+''', r'''
+class A {}
+mixin M on A {}
+''');
+  }
+
+  test_topLevelVariable_withoutType() async {
+    await assertNotSameSignature(r'''
+var a = 1;
+''', r'''
+var a = 2;
+''');
+  }
+
+  test_topLevelVariable_withoutType2() async {
+    await assertNotSameSignature(r'''
+var a = 1, b = 2, c, d = 4;;
+''', r'''
+var a = 1, b, c = 3, d = 4;;
+''');
+  }
+
+  test_topLevelVariable_withType() async {
+    await assertSameSignature(r'''
+int a = 1, b, c = 3;
+''', r'''
+int a = 0, b = 2, c;
+''');
+  }
+
+  test_topLevelVariable_withType_const() async {
+    await assertNotSameSignature(r'''
+const int a = 1;
+''', r'''
+const int a = 2;
+''');
+  }
+
+  test_topLevelVariable_withType_final() async {
+    await assertSameSignature(r'''
+final int a = 1;
+''', r'''
+final int a = 2;
+''');
+  }
+
+  test_typedef_generic_parameters_type() async {
+    await assertNotSameSignature(r'''
+typedef F = void Function(int);
+''', r'''
+typedef F = void Function(double);
+''');
+  }
+}
diff --git a/pkg/analyzer/test/src/dart/ast/ast_test.dart b/pkg/analyzer/test/src/dart/ast/ast_test.dart
index d79a662..1bbecda 100644
--- a/pkg/analyzer/test/src/dart/ast/ast_test.dart
+++ b/pkg/analyzer/test/src/dart/ast/ast_test.dart
@@ -3,6 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'dart:async';
+
 import 'package:analyzer/src/dart/ast/ast.dart';
 import 'package:analyzer/src/dart/ast/utilities.dart';
 import 'package:analyzer/src/generated/engine.dart';
@@ -763,183 +764,294 @@
 
 @reflectiveTest
 class IntegerLiteralImplTest {
-  test_isValidLiteral_dec_negative_equalMax() {
+  test_isValidAsDouble_dec_1024Bits() {
     expect(
-        IntegerLiteralImpl.isValidLiteral('9223372036854775808', true), true);
-  }
-
-  test_isValidLiteral_dec_negative_fewDigits() {
-    expect(IntegerLiteralImpl.isValidLiteral('24', true), true);
-  }
-
-  test_isValidLiteral_dec_negative_leadingZeros_overMax() {
-    expect(IntegerLiteralImpl.isValidLiteral('009923372036854775807', true),
+        IntegerLiteralImpl.isValidAsDouble(
+            '179769313486231570814527423731704356798070567525844996598917476803'
+            '157260780028538760589558632766878171540458953514382464234321326889'
+            '464182768467546703537516986049910576551282076245490090389328944075'
+            '868508455133942304583236903222948165808559332123348274797826204144'
+            '723168738177180919299881250404026184124858369'),
         false);
   }
 
-  test_isValidLiteral_dec_negative_leadingZeros_underMax() {
+  test_isValidAsDouble_dec_11ExponentBits() {
     expect(
-        IntegerLiteralImpl.isValidLiteral('004223372036854775807', true), true);
-  }
-
-  test_isValidLiteral_dec_negative_oneOverMax() {
-    expect(
-        IntegerLiteralImpl.isValidLiteral('9223372036854775809', true), false);
-  }
-
-  test_isValidLiteral_dec_negative_tooManyDigits() {
-    expect(
-        IntegerLiteralImpl.isValidLiteral('10223372036854775808', true), false);
-  }
-
-  test_isValidLiteral_dec_positive_equalMax() {
-    expect(
-        IntegerLiteralImpl.isValidLiteral('9223372036854775807', false), true);
-  }
-
-  test_isValidLiteral_dec_positive_fewDigits() {
-    expect(IntegerLiteralImpl.isValidLiteral('42', false), true);
-  }
-
-  test_isValidLiteral_dec_positive_leadingZeros_overMax() {
-    expect(IntegerLiteralImpl.isValidLiteral('009923372036854775807', false),
+        IntegerLiteralImpl.isValidAsDouble(
+            '359538626972463141629054847463408713596141135051689993197834953606'
+            '314521560057077521179117265533756343080917907028764928468642653778'
+            '928365536935093407075033972099821153102564152490980180778657888151'
+            '737016910267884609166473806445896331617118664246696549595652408289'
+            '446337476354361838599762500808052368249716736'),
         false);
   }
 
-  test_isValidLiteral_dec_positive_leadingZeros_underMax() {
-    expect(IntegerLiteralImpl.isValidLiteral('004223372036854775807', false),
+  test_isValidAsDouble_dec_16CharValue() {
+    // 16 characters is used as a cutoff point for optimization
+    expect(IntegerLiteralImpl.isValidAsDouble('9007199254740991'), true);
+  }
+
+  test_isValidAsDouble_dec_53BitsMax() {
+    expect(
+        IntegerLiteralImpl.isValidAsDouble(
+            '179769313486231570814527423731704356798070567525844996598917476803'
+            '157260780028538760589558632766878171540458953514382464234321326889'
+            '464182768467546703537516986049910576551282076245490090389328944075'
+            '868508455133942304583236903222948165808559332123348274797826204144'
+            '723168738177180919299881250404026184124858368'),
         true);
   }
 
-  test_isValidLiteral_dec_positive_oneOverMax() {
-    expect(
-        IntegerLiteralImpl.isValidLiteral('9223372036854775808', false), false);
+  test_isValidAsDouble_dec_54BitsMax() {
+    expect(IntegerLiteralImpl.isValidAsDouble('18014398509481983'), false);
   }
 
-  test_isValidLiteral_dec_positive_tooManyDigits() {
-    expect(IntegerLiteralImpl.isValidLiteral('10223372036854775808', false),
+  test_isValidAsDouble_dec_54BitsMin() {
+    expect(IntegerLiteralImpl.isValidAsDouble('9007199254740993'), false);
+  }
+
+  test_isValidAsDouble_dec_fewDigits() {
+    expect(IntegerLiteralImpl.isValidAsDouble('45'), true);
+  }
+
+  test_isValidAsDouble_dec_largest15CharValue() {
+    // 16 characters is used as a cutoff point for optimization
+    expect(IntegerLiteralImpl.isValidAsDouble('999999999999999'), true);
+  }
+
+  test_isValidAsDouble_hex_1024Bits() {
+    expect(
+        IntegerLiteralImpl.isValidAsDouble(
+            '0xFFFFFFFFFFFFF800000000000000000000000000000000000000000000000000'
+            '000000000000000000000000000000000000000000000000000000000000000000'
+            '000000000000000000000000000000000000000000000000000000000000000000'
+            '000000000000000000000000000000000000000000000000000000000001'),
         false);
   }
 
-  test_isValidLiteral_hex_negative_equalMax() {
-    expect(IntegerLiteralImpl.isValidLiteral('0x8000000000000000', true), true);
-  }
-
-  test_isValidLiteral_heX_negative_equalMax() {
-    expect(IntegerLiteralImpl.isValidLiteral('0X8000000000000000', true), true);
-  }
-
-  test_isValidLiteral_hex_negative_fewDigits() {
-    expect(IntegerLiteralImpl.isValidLiteral('0xFF', true), true);
-  }
-
-  test_isValidLiteral_heX_negative_fewDigits() {
-    expect(IntegerLiteralImpl.isValidLiteral('0XFF', true), true);
-  }
-
-  test_isValidLiteral_hex_negative_leadingZeros_overMax() {
-    expect(IntegerLiteralImpl.isValidLiteral('0x00FFFFFFFFFFFFFFFFF', true),
+  test_isValidAsDouble_hex_11ExponentBits() {
+    expect(
+        IntegerLiteralImpl.isValidAsDouble(
+            '0x1FFFFFFFFFFFFF00000000000000000000000000000000000000000000000000'
+            '000000000000000000000000000000000000000000000000000000000000000000'
+            '000000000000000000000000000000000000000000000000000000000000000000'
+            '0000000000000000000000000000000000000000000000000000000000000'),
         false);
   }
 
-  test_isValidLiteral_heX_negative_leadingZeros_overMax() {
-    expect(IntegerLiteralImpl.isValidLiteral('0X00FFFFFFFFFFFFFFFFF', true),
+  test_isValidAsDouble_hex_16CharValue() {
+    // 16 characters is used as a cutoff point for optimization
+    expect(IntegerLiteralImpl.isValidAsDouble('0x0FFFFFFFFFFFFF'), true);
+  }
+
+  test_isValidAsDouble_hex_53BitsMax() {
+    expect(
+        IntegerLiteralImpl.isValidAsDouble(
+            '0xFFFFFFFFFFFFF800000000000000000000000000000000000000000000000000'
+            '000000000000000000000000000000000000000000000000000000000000000000'
+            '000000000000000000000000000000000000000000000000000000000000000000'
+            '000000000000000000000000000000000000000000000000000000000000'),
+        true);
+  }
+
+  test_isValidAsDouble_hex_54BitsMax() {
+    expect(IntegerLiteralImpl.isValidAsDouble('0x3FFFFFFFFFFFFF'), false);
+  }
+
+  test_isValidAsDouble_hex_54BitsMin() {
+    expect(IntegerLiteralImpl.isValidAsDouble('0x20000000000001'), false);
+  }
+
+  test_isValidAsDouble_hex_fewDigits() {
+    expect(IntegerLiteralImpl.isValidAsDouble('0x45'), true);
+  }
+
+  test_isValidAsDouble_hex_largest15CharValue() {
+    // 16 characters is used as a cutoff point for optimization
+    expect(IntegerLiteralImpl.isValidAsDouble('0xFFFFFFFFFFFFF'), true);
+  }
+
+  test_isValidAsInteger_dec_negative_equalMax() {
+    expect(
+        IntegerLiteralImpl.isValidAsInteger('9223372036854775808', true), true);
+  }
+
+  test_isValidAsInteger_dec_negative_fewDigits() {
+    expect(IntegerLiteralImpl.isValidAsInteger('24', true), true);
+  }
+
+  test_isValidAsInteger_dec_negative_leadingZeros_overMax() {
+    expect(IntegerLiteralImpl.isValidAsInteger('009923372036854775807', true),
         false);
   }
 
-  test_isValidLiteral_hex_negative_leadingZeros_underMax() {
-    expect(
-        IntegerLiteralImpl.isValidLiteral('0x007FFFFFFFFFFFFFFF', true), true);
+  test_isValidAsInteger_dec_negative_leadingZeros_underMax() {
+    expect(IntegerLiteralImpl.isValidAsInteger('004223372036854775807', true),
+        true);
   }
 
-  test_isValidLiteral_heX_negative_leadingZeros_underMax() {
-    expect(
-        IntegerLiteralImpl.isValidLiteral('0X007FFFFFFFFFFFFFFF', true), true);
-  }
-
-  test_isValidLiteral_hex_negative_oneBelowMax() {
-    expect(IntegerLiteralImpl.isValidLiteral('0x7FFFFFFFFFFFFFFF', true), true);
-  }
-
-  test_isValidLiteral_heX_negative_oneBelowMax() {
-    expect(IntegerLiteralImpl.isValidLiteral('0X7FFFFFFFFFFFFFFF', true), true);
-  }
-
-  test_isValidLiteral_hex_negative_oneOverMax() {
-    expect(
-        IntegerLiteralImpl.isValidLiteral('0x8000000000000001', true), false);
-  }
-
-  test_isValidLiteral_heX_negative_oneOverMax() {
-    expect(
-        IntegerLiteralImpl.isValidLiteral('0X8000000000000001', true), false);
-  }
-
-  test_isValidLiteral_hex_negative_tooManyDigits() {
-    expect(
-        IntegerLiteralImpl.isValidLiteral('0x10000000000000000', true), false);
-  }
-
-  test_isValidLiteral_heX_negative_tooManyDigits() {
-    expect(
-        IntegerLiteralImpl.isValidLiteral('0X10000000000000000', true), false);
-  }
-
-  test_isValidLiteral_hex_positive_equalMax() {
-    expect(
-        IntegerLiteralImpl.isValidLiteral('0x7FFFFFFFFFFFFFFF', false), true);
-  }
-
-  test_isValidLiteral_heX_positive_equalMax() {
-    expect(
-        IntegerLiteralImpl.isValidLiteral('0X7FFFFFFFFFFFFFFF', false), true);
-  }
-
-  test_isValidLiteral_hex_positive_fewDigits() {
-    expect(IntegerLiteralImpl.isValidLiteral('0xFF', false), true);
-  }
-
-  test_isValidLiteral_heX_positive_fewDigits() {
-    expect(IntegerLiteralImpl.isValidLiteral('0XFF', false), true);
-  }
-
-  test_isValidLiteral_hex_positive_leadingZeros_overMax() {
-    expect(IntegerLiteralImpl.isValidLiteral('0x00FFFFFFFFFFFFFFFFF', false),
+  test_isValidAsInteger_dec_negative_oneOverMax() {
+    expect(IntegerLiteralImpl.isValidAsInteger('9223372036854775809', true),
         false);
   }
 
-  test_isValidLiteral_heX_positive_leadingZeros_overMax() {
-    expect(IntegerLiteralImpl.isValidLiteral('0X00FFFFFFFFFFFFFFFFF', false),
+  test_isValidAsInteger_dec_negative_tooManyDigits() {
+    expect(IntegerLiteralImpl.isValidAsInteger('10223372036854775808', true),
         false);
   }
 
-  test_isValidLiteral_hex_positive_leadingZeros_underMax() {
-    expect(
-        IntegerLiteralImpl.isValidLiteral('0x007FFFFFFFFFFFFFFF', false), true);
+  test_isValidAsInteger_dec_positive_equalMax() {
+    expect(IntegerLiteralImpl.isValidAsInteger('9223372036854775807', false),
+        true);
   }
 
-  test_isValidLiteral_heX_positive_leadingZeros_underMax() {
-    expect(
-        IntegerLiteralImpl.isValidLiteral('0X007FFFFFFFFFFFFFFF', false), true);
+  test_isValidAsInteger_dec_positive_fewDigits() {
+    expect(IntegerLiteralImpl.isValidAsInteger('42', false), true);
   }
 
-  test_isValidLiteral_hex_positive_oneOverMax() {
-    expect(
-        IntegerLiteralImpl.isValidLiteral('0x10000000000000000', false), false);
-  }
-
-  test_isValidLiteral_heX_positive_oneOverMax() {
-    expect(
-        IntegerLiteralImpl.isValidLiteral('0X10000000000000000', false), false);
-  }
-
-  test_isValidLiteral_hex_positive_tooManyDigits() {
-    expect(IntegerLiteralImpl.isValidLiteral('0xFF0000000000000000', false),
+  test_isValidAsInteger_dec_positive_leadingZeros_overMax() {
+    expect(IntegerLiteralImpl.isValidAsInteger('009923372036854775807', false),
         false);
   }
 
-  test_isValidLiteral_heX_positive_tooManyDigits() {
-    expect(IntegerLiteralImpl.isValidLiteral('0XFF0000000000000000', false),
+  test_isValidAsInteger_dec_positive_leadingZeros_underMax() {
+    expect(IntegerLiteralImpl.isValidAsInteger('004223372036854775807', false),
+        true);
+  }
+
+  test_isValidAsInteger_dec_positive_oneOverMax() {
+    expect(IntegerLiteralImpl.isValidAsInteger('9223372036854775808', false),
+        false);
+  }
+
+  test_isValidAsInteger_dec_positive_tooManyDigits() {
+    expect(IntegerLiteralImpl.isValidAsInteger('10223372036854775808', false),
+        false);
+  }
+
+  test_isValidAsInteger_hex_negative_equalMax() {
+    expect(
+        IntegerLiteralImpl.isValidAsInteger('0x8000000000000000', true), true);
+  }
+
+  test_isValidAsInteger_heX_negative_equalMax() {
+    expect(
+        IntegerLiteralImpl.isValidAsInteger('0X8000000000000000', true), true);
+  }
+
+  test_isValidAsInteger_hex_negative_fewDigits() {
+    expect(IntegerLiteralImpl.isValidAsInteger('0xFF', true), true);
+  }
+
+  test_isValidAsInteger_heX_negative_fewDigits() {
+    expect(IntegerLiteralImpl.isValidAsInteger('0XFF', true), true);
+  }
+
+  test_isValidAsInteger_heX_negative_leadingZeros_overMax() {
+    expect(IntegerLiteralImpl.isValidAsInteger('0X00FFFFFFFFFFFFFFFFF', true),
+        false);
+  }
+
+  test_isValidAsInteger_hex_negative_leadingZeros_overMax() {
+    expect(IntegerLiteralImpl.isValidAsInteger('0x00FFFFFFFFFFFFFFFFF', true),
+        false);
+  }
+
+  test_isValidAsInteger_hex_negative_leadingZeros_underMax() {
+    expect(IntegerLiteralImpl.isValidAsInteger('0x007FFFFFFFFFFFFFFF', true),
+        true);
+  }
+
+  test_isValidAsInteger_heX_negative_leadingZeros_underMax() {
+    expect(IntegerLiteralImpl.isValidAsInteger('0X007FFFFFFFFFFFFFFF', true),
+        true);
+  }
+
+  test_isValidAsInteger_hex_negative_oneBelowMax() {
+    expect(
+        IntegerLiteralImpl.isValidAsInteger('0x7FFFFFFFFFFFFFFF', true), true);
+  }
+
+  test_isValidAsInteger_heX_negative_oneBelowMax() {
+    expect(
+        IntegerLiteralImpl.isValidAsInteger('0X7FFFFFFFFFFFFFFF', true), true);
+  }
+
+  test_isValidAsInteger_hex_negative_oneOverMax() {
+    expect(
+        IntegerLiteralImpl.isValidAsInteger('0x8000000000000001', true), false);
+  }
+
+  test_isValidAsInteger_heX_negative_oneOverMax() {
+    expect(
+        IntegerLiteralImpl.isValidAsInteger('0X8000000000000001', true), false);
+  }
+
+  test_isValidAsInteger_hex_negative_tooManyDigits() {
+    expect(IntegerLiteralImpl.isValidAsInteger('0x10000000000000000', true),
+        false);
+  }
+
+  test_isValidAsInteger_heX_negative_tooManyDigits() {
+    expect(IntegerLiteralImpl.isValidAsInteger('0X10000000000000000', true),
+        false);
+  }
+
+  test_isValidAsInteger_heX_positive_equalMax() {
+    expect(
+        IntegerLiteralImpl.isValidAsInteger('0X7FFFFFFFFFFFFFFF', false), true);
+  }
+
+  test_isValidAsInteger_hex_positive_equalMax() {
+    expect(
+        IntegerLiteralImpl.isValidAsInteger('0x7FFFFFFFFFFFFFFF', false), true);
+  }
+
+  test_isValidAsInteger_heX_positive_fewDigits() {
+    expect(IntegerLiteralImpl.isValidAsInteger('0XFF', false), true);
+  }
+
+  test_isValidAsInteger_hex_positive_fewDigits() {
+    expect(IntegerLiteralImpl.isValidAsInteger('0xFF', false), true);
+  }
+
+  test_isValidAsInteger_heX_positive_leadingZeros_overMax() {
+    expect(IntegerLiteralImpl.isValidAsInteger('0X00FFFFFFFFFFFFFFFFF', false),
+        false);
+  }
+
+  test_isValidAsInteger_hex_positive_leadingZeros_overMax() {
+    expect(IntegerLiteralImpl.isValidAsInteger('0x00FFFFFFFFFFFFFFFFF', false),
+        false);
+  }
+
+  test_isValidAsInteger_heX_positive_leadingZeros_underMax() {
+    expect(IntegerLiteralImpl.isValidAsInteger('0X007FFFFFFFFFFFFFFF', false),
+        true);
+  }
+
+  test_isValidAsInteger_hex_positive_leadingZeros_underMax() {
+    expect(IntegerLiteralImpl.isValidAsInteger('0x007FFFFFFFFFFFFFFF', false),
+        true);
+  }
+
+  test_isValidAsInteger_heX_positive_oneOverMax() {
+    expect(IntegerLiteralImpl.isValidAsInteger('0X10000000000000000', false),
+        false);
+  }
+
+  test_isValidAsInteger_hex_positive_oneOverMax() {
+    expect(IntegerLiteralImpl.isValidAsInteger('0x10000000000000000', false),
+        false);
+  }
+
+  test_isValidAsInteger_hex_positive_tooManyDigits() {
+    expect(IntegerLiteralImpl.isValidAsInteger('0xFF0000000000000000', false),
+        false);
+  }
+
+  test_isValidAsInteger_heX_positive_tooManyDigits() {
+    expect(IntegerLiteralImpl.isValidAsInteger('0XFF0000000000000000', false),
         false);
   }
 }
diff --git a/pkg/analyzer/test/src/dart/resolution/assignment_test.dart b/pkg/analyzer/test/src/dart/resolution/assignment_test.dart
index 6316ceb..7f21b03 100644
--- a/pkg/analyzer/test/src/dart/resolution/assignment_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/assignment_test.dart
@@ -243,7 +243,7 @@
     assertType(creation, 'B');
 
     var fRef = left.propertyName;
-    assertElement(fRef, findElement.setter('f', inClass: 'A'));
+    assertElement(fRef, findElement.setter('f', className: 'A'));
     assertType(fRef, 'int');
 
     var right = assignment.rightHandSide;
diff --git a/pkg/analyzer/test/src/dart/resolution/class_test.dart b/pkg/analyzer/test/src/dart/resolution/class_test.dart
index 166176c..7edebf0 100644
--- a/pkg/analyzer/test/src/dart/resolution/class_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/class_test.dart
@@ -18,6 +18,1226 @@
     with ClassResolutionMixin {}
 
 abstract class ClassResolutionMixin implements ResolutionTest {
+  test_abstractSuperMemberReference_getter() async {
+    addTestFile(r'''
+abstract class A {
+  get foo;
+}
+abstract class B extends A {
+  bar() {
+    super.foo; // ref
+  }
+}
+''');
+    await resolveTestFile();
+    assertTestErrors([CompileTimeErrorCode.ABSTRACT_SUPER_MEMBER_REFERENCE]);
+    assertElement(findNode.simple('foo; // ref'), findElement.getter('foo'));
+  }
+
+  test_abstractSuperMemberReference_getter2() async {
+    addTestFile(r'''
+abstract class Foo {
+  String get foo;
+}
+
+abstract class Bar implements Foo {
+}
+
+class Baz extends Bar {
+  String get foo => super.foo; // ref
+}
+''');
+    await resolveTestFile();
+    assertTestErrors([CompileTimeErrorCode.ABSTRACT_SUPER_MEMBER_REFERENCE]);
+    assertElement(
+      findNode.simple('foo; // ref'),
+      findElement.getter('foo', className: 'Foo'),
+    );
+  }
+
+  test_abstractSuperMemberReference_method_invocation() async {
+    addTestFile(r'''
+abstract class A {
+  foo();
+}
+abstract class B extends A {
+  bar() {
+    super.foo(); // ref
+  }
+
+  foo() {} // does not matter
+}
+''');
+    await resolveTestFile();
+    assertTestErrors([CompileTimeErrorCode.ABSTRACT_SUPER_MEMBER_REFERENCE]);
+    assertElement(
+      findNode.simple('foo(); // ref'),
+      findElement.method('foo', of: 'A'),
+    );
+  }
+
+  test_abstractSuperMemberReference_method_reference() async {
+    addTestFile(r'''
+abstract class A {
+  foo();
+}
+abstract class B extends A {
+  bar() {
+    super.foo; // ref
+  }
+}
+''');
+    await resolveTestFile();
+    assertTestErrors([CompileTimeErrorCode.ABSTRACT_SUPER_MEMBER_REFERENCE]);
+    assertElement(findNode.simple('foo; // ref'), findElement.method('foo'));
+  }
+
+  test_abstractSuperMemberReference_OK_mixinHasConcrete2_method() async {
+    addTestFile('''
+class A {
+}
+
+class M {
+  void foo() {}
+}
+
+class B = A with M;
+
+class C extends B {
+  void bar() {
+    super.foo(); // ref
+  }
+}
+''');
+    await resolveTestFile();
+    assertNoTestErrors();
+    assertElement(
+      findNode.simple('foo(); // ref'),
+      findElement.method('foo', of: 'M'),
+    );
+  }
+
+  test_abstractSuperMemberReference_OK_noSuchMethod() async {
+    setAnalysisOptions(enableSuperMixins: true);
+    addTestFile('''
+class A {
+  void foo();
+  noSuchMethod(im) {}
+}
+
+abstract class B {
+  void foo();
+  noSuchMethod(im) {}
+}
+
+class C extends A with B {
+  void bar() {
+    super.foo(); // ref
+  }
+}
+''');
+    await resolveTestFile();
+    assertNoTestErrors();
+    assertElement(
+      findNode.simple('foo(); // ref'),
+      findElement.method('foo', of: 'B'),
+    );
+  }
+
+  test_abstractSuperMemberReference_OK_superHasConcrete_mixinHasAbstract_method() async {
+    addTestFile('''
+class A {
+  void foo() {}
+}
+
+abstract class B {
+  void foo();
+}
+
+class C extends A with B {
+  void bar() {
+    super.foo(); // ref
+  }
+}
+''');
+    await resolveTestFile();
+    assertNoTestErrors();
+    assertElement(
+      findNode.simple('foo(); // ref'),
+      findElement.method('foo', of: 'A'),
+    );
+  }
+
+  test_abstractSuperMemberReference_OK_superSuperHasConcrete_getter() async {
+    addTestFile('''
+abstract class A {
+  int get foo => 0;
+}
+
+abstract class B extends A {
+  int get foo;
+}
+
+class C extends B {
+  int get bar => super.foo; // ref
+}
+''');
+    await resolveTestFile();
+    assertNoTestErrors();
+    assertElement(
+      findNode.simple('foo; // ref'),
+      findElement.getter('foo', className: 'A'),
+    );
+  }
+
+  test_abstractSuperMemberReference_OK_superSuperHasConcrete_method() async {
+    addTestFile('''
+abstract class A {
+  void foo() {}
+}
+
+abstract class B extends A {
+  void foo();
+}
+
+class C extends B {
+  void bar() {
+    super.foo(); // ref
+  }
+}
+''');
+    await resolveTestFile();
+    assertNoTestErrors();
+    assertElement(
+      findNode.simple('foo(); // ref'),
+      findElement.method('foo', of: 'A'),
+    );
+  }
+
+  test_abstractSuperMemberReference_OK_superSuperHasConcrete_setter() async {
+    addTestFile('''
+abstract class A {
+  void set foo(_) {}
+}
+
+abstract class B extends A {
+  void set foo(_);
+}
+
+class C extends B {
+  void bar() {
+    super.foo = 0;
+  }
+}
+''');
+    await resolveTestFile();
+    assertNoTestErrors();
+    assertElement(
+      findNode.simple('foo = 0;'),
+      findElement.setter('foo', className: 'A'),
+    );
+  }
+
+  test_abstractSuperMemberReference_setter() async {
+    addTestFile(r'''
+abstract class A {
+  set foo(_);
+}
+abstract class B extends A {
+  bar() {
+    super.foo = 0;
+  }
+}
+''');
+    await resolveTestFile();
+    assertTestErrors([CompileTimeErrorCode.ABSTRACT_SUPER_MEMBER_REFERENCE]);
+    assertElement(findNode.simple('foo = 0;'), findElement.setter('foo'));
+  }
+
+  test_conflictingGenericInterfaces_simple() async {
+    addTestFile('''
+class I<T> {}
+class A implements I<int> {}
+class B implements I<String> {}
+class C extends A implements B {}
+''');
+    await resolveTestFile();
+    assertTestErrors([CompileTimeErrorCode.CONFLICTING_GENERIC_INTERFACES]);
+  }
+
+  test_conflictingGenericInterfaces_viaMixin() async {
+    addTestFile('''
+class I<T> {}
+class A implements I<int> {}
+class B implements I<String> {}
+class C extends A with B {}
+''');
+    await resolveTestFile();
+    assertTestErrors([CompileTimeErrorCode.CONFLICTING_GENERIC_INTERFACES]);
+  }
+
+  test_element_allSupertypes() async {
+    addTestFile(r'''
+class A {}
+class B {}
+class C {}
+class D {}
+class E {}
+
+class X1 extends A {}
+class X2 implements B {}
+class X3 extends A implements B {}
+class X4 extends A with B implements C {}
+class X5 extends A with B, C implements D, E {}
+''');
+    await resolveTestFile();
+    assertNoTestErrors();
+
+    var a = findElement.class_('A');
+    var b = findElement.class_('B');
+    var c = findElement.class_('C');
+    var d = findElement.class_('D');
+    var e = findElement.class_('E');
+    assertElementTypes(
+      findElement.class_('X1').allSupertypes,
+      [a.type, objectType],
+    );
+    assertElementTypes(
+      findElement.class_('X2').allSupertypes,
+      [objectType, b.type],
+    );
+    assertElementTypes(
+      findElement.class_('X3').allSupertypes,
+      [a.type, objectType, b.type],
+    );
+    assertElementTypes(
+      findElement.class_('X4').allSupertypes,
+      [a.type, b.type, objectType, c.type],
+    );
+    assertElementTypes(
+      findElement.class_('X5').allSupertypes,
+      [a.type, b.type, c.type, objectType, d.type, e.type],
+    );
+  }
+
+  test_element_allSupertypes_generic() async {
+    addTestFile(r'''
+class A<T> {}
+class B<T, U> {}
+class C<T> extends B<int, T> {}
+
+class X1 extends A<String> {}
+class X2 extends B<String, List<int>> {}
+class X3 extends C<double> {}
+''');
+    await resolveTestFile();
+    assertNoTestErrors();
+
+    var a = findElement.class_('A');
+    var b = findElement.class_('B');
+    var c = findElement.class_('C');
+    assertElementTypes(
+      findElement.class_('X1').allSupertypes,
+      [
+        a.type.instantiate([stringType]),
+        objectType
+      ],
+    );
+    assertElementTypes(
+      findElement.class_('X2').allSupertypes,
+      [
+        b.type.instantiate([
+          stringType,
+          typeProvider.listType.instantiate([intType])
+        ]),
+        objectType
+      ],
+    );
+    assertElementTypes(
+      findElement.class_('X3').allSupertypes,
+      [
+        c.type.instantiate([doubleType]),
+        b.type.instantiate([intType, doubleType]),
+        objectType
+      ],
+    );
+  }
+
+  test_element_allSupertypes_recursive() async {
+    addTestFile(r'''
+class A extends B {}
+class B extends C {}
+class C extends A {}
+
+class X extends A {}
+''');
+    await resolveTestFile();
+    assertHasTestErrors();
+
+    var a = findElement.class_('A');
+    var b = findElement.class_('B');
+    var c = findElement.class_('C');
+    assertElementTypes(
+      findElement.class_('X').allSupertypes,
+      [a.type, b.type, c.type],
+    );
+  }
+
+  test_error_conflictingConstructorAndStaticField_field() async {
+    addTestFile(r'''
+class C {
+  C.foo();
+  static int foo;
+}
+''');
+    await resolveTestFile();
+    assertTestErrors([
+      CompileTimeErrorCode.CONFLICTING_CONSTRUCTOR_AND_STATIC_FIELD,
+    ]);
+  }
+
+  test_error_conflictingConstructorAndStaticField_getter() async {
+    addTestFile(r'''
+class C {
+  C.foo();
+  static int get foo => 0;
+}
+''');
+    await resolveTestFile();
+    assertTestErrors([
+      CompileTimeErrorCode.CONFLICTING_CONSTRUCTOR_AND_STATIC_FIELD,
+    ]);
+  }
+
+  test_error_conflictingConstructorAndStaticField_OK_notSameClass() async {
+    addTestFile(r'''
+class A {
+  static int foo;
+}
+class B extends A {
+  B.foo();
+}
+''');
+    await resolveTestFile();
+    assertNoTestErrors();
+  }
+
+  test_error_conflictingConstructorAndStaticField_OK_notStatic() async {
+    addTestFile(r'''
+class C {
+  C.foo();
+  int foo;
+}
+''');
+    await resolveTestFile();
+    assertNoTestErrors();
+  }
+
+  test_error_conflictingConstructorAndStaticField_setter() async {
+    addTestFile(r'''
+class C {
+  C.foo();
+  static void set foo(_) {}
+}
+''');
+    await resolveTestFile();
+    assertTestErrors([
+      CompileTimeErrorCode.CONFLICTING_CONSTRUCTOR_AND_STATIC_FIELD,
+    ]);
+  }
+
+  test_error_conflictingConstructorAndStaticMethod() async {
+    addTestFile(r'''
+class C {
+  C.foo();
+  static void foo() {}
+}
+''');
+    await resolveTestFile();
+    assertTestErrors([
+      CompileTimeErrorCode.CONFLICTING_CONSTRUCTOR_AND_STATIC_METHOD,
+    ]);
+  }
+
+  test_error_conflictingConstructorAndStaticMethod_OK_notSameClass() async {
+    addTestFile(r'''
+class A {
+  static void foo() {}
+}
+class B extends A {
+  B.foo();
+}
+''');
+    await resolveTestFile();
+    assertNoTestErrors();
+  }
+
+  test_error_conflictingConstructorAndStaticMethod_OK_notStatic() async {
+    addTestFile(r'''
+class C {
+  C.foo();
+  void foo() {}
+}
+''');
+    await resolveTestFile();
+    assertNoTestErrors();
+  }
+
+  test_error_conflictingFieldAndMethod_inSuper_field() async {
+    addTestFile(r'''
+class A {
+  foo() {}
+}
+class B extends A {
+  int foo;
+}
+''');
+    await resolveTestFile();
+    assertTestErrors([CompileTimeErrorCode.CONFLICTING_FIELD_AND_METHOD]);
+  }
+
+  test_error_conflictingFieldAndMethod_inSuper_getter() async {
+    addTestFile(r'''
+class A {
+  foo() {}
+}
+class B extends A {
+  get foo => 0;
+}
+''');
+    await resolveTestFile();
+    assertTestErrors([CompileTimeErrorCode.CONFLICTING_FIELD_AND_METHOD]);
+  }
+
+  test_error_conflictingFieldAndMethod_inSuper_setter() async {
+    addTestFile(r'''
+class A {
+  foo() {}
+}
+class B extends A {
+  set foo(_) {}
+}
+''');
+    await resolveTestFile();
+    assertTestErrors([CompileTimeErrorCode.CONFLICTING_FIELD_AND_METHOD]);
+  }
+
+  test_error_conflictingMethodAndField_inSuper_field() async {
+    addTestFile(r'''
+class A {
+  int foo;
+}
+class B extends A {
+  foo() {}
+}
+''');
+    await resolveTestFile();
+    assertTestErrors([CompileTimeErrorCode.CONFLICTING_METHOD_AND_FIELD]);
+  }
+
+  test_error_conflictingMethodAndField_inSuper_getter() async {
+    addTestFile(r'''
+class A {
+  get foo => 0;
+}
+class B extends A {
+  foo() {}
+}
+''');
+    await resolveTestFile();
+    assertTestErrors([CompileTimeErrorCode.CONFLICTING_METHOD_AND_FIELD]);
+  }
+
+  test_error_conflictingMethodAndField_inSuper_setter() async {
+    addTestFile(r'''
+class A {
+  set foo(_) {}
+}
+class B extends A {
+  foo() {}
+}
+''');
+    await resolveTestFile();
+    assertTestErrors([CompileTimeErrorCode.CONFLICTING_METHOD_AND_FIELD]);
+  }
+
+  test_error_conflictingStaticAndInstance_inClass_getter_getter() async {
+    addTestFile(r'''
+class C {
+  static int get foo => 0;
+  int get foo => 0;
+}
+''');
+    await resolveTestFile();
+    assertTestErrors([CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
+  }
+
+  test_error_conflictingStaticAndInstance_inClass_getter_method() async {
+    addTestFile(r'''
+class C {
+  static int get foo => 0;
+  void foo() {}
+}
+''');
+    await resolveTestFile();
+    assertTestErrors([CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
+  }
+
+  test_error_conflictingStaticAndInstance_inClass_getter_setter() async {
+    addTestFile(r'''
+class C {
+  static int get foo => 0;
+  set foo(_) {}
+}
+''');
+    await resolveTestFile();
+    assertTestErrors([CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
+  }
+
+  test_error_conflictingStaticAndInstance_inClass_method_getter() async {
+    addTestFile(r'''
+class C {
+  static void foo() {}
+  int get foo => 0;
+}
+''');
+    await resolveTestFile();
+    assertTestErrors([CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
+  }
+
+  test_error_conflictingStaticAndInstance_inClass_method_method() async {
+    addTestFile(r'''
+class C {
+  static void foo() {}
+  void foo() {}
+}
+''');
+    await resolveTestFile();
+    assertTestErrors([CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
+  }
+
+  test_error_conflictingStaticAndInstance_inClass_method_setter() async {
+    addTestFile(r'''
+class C {
+  static void foo() {}
+  set foo(_) {}
+}
+''');
+    await resolveTestFile();
+    assertTestErrors([CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
+  }
+
+  test_error_conflictingStaticAndInstance_inClass_setter_getter() async {
+    addTestFile(r'''
+class C {
+  static set foo(_) {}
+  int get foo => 0;
+}
+''');
+    await resolveTestFile();
+    assertTestErrors([CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
+  }
+
+  test_error_conflictingStaticAndInstance_inClass_setter_method() async {
+    addTestFile(r'''
+class C {
+  static set foo(_) {}
+  void foo() {}
+}
+''');
+    await resolveTestFile();
+    assertTestErrors([CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
+  }
+
+  test_error_conflictingStaticAndInstance_inClass_setter_setter() async {
+    addTestFile(r'''
+class C {
+  static set foo(_) {}
+  set foo(_) {}
+}
+''');
+    await resolveTestFile();
+    assertTestErrors([CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
+  }
+
+  test_error_conflictingStaticAndInstance_inInterface_getter_getter() async {
+    addTestFile(r'''
+class A {
+  int get foo => 0;
+}
+abstract class B implements A {
+  static int get foo => 0;
+}
+''');
+    await resolveTestFile();
+    assertTestErrors([CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
+  }
+
+  test_error_conflictingStaticAndInstance_inInterface_getter_method() async {
+    addTestFile(r'''
+class A {
+  int get foo => 0;
+}
+abstract class B implements A {
+  static void foo() {}
+}
+''');
+    await resolveTestFile();
+    assertTestErrors([CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
+  }
+
+  test_error_conflictingStaticAndInstance_inInterface_getter_setter() async {
+    addTestFile(r'''
+class A {
+  set foo(_) {}
+}
+abstract class B implements A {
+  static int get foo => 0;
+}
+''');
+    await resolveTestFile();
+    assertTestErrors([CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
+  }
+
+  test_error_conflictingStaticAndInstance_inInterface_method_getter() async {
+    addTestFile(r'''
+class A {
+  int get foo => 0;
+}
+abstract class B implements A {
+  static void foo() {}
+}
+''');
+    await resolveTestFile();
+    assertTestErrors([CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
+  }
+
+  test_error_conflictingStaticAndInstance_inInterface_method_method() async {
+    addTestFile(r'''
+class A {
+  void foo() {}
+}
+abstract class B implements A {
+  static void foo() {}
+}
+''');
+    await resolveTestFile();
+    assertTestErrors([CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
+  }
+
+  test_error_conflictingStaticAndInstance_inInterface_method_setter() async {
+    addTestFile(r'''
+class A {
+  set foo(_) {}
+}
+abstract class B implements A {
+  static void foo() {}
+}
+''');
+    await resolveTestFile();
+    assertTestErrors([CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
+  }
+
+  test_error_conflictingStaticAndInstance_inInterface_setter_method() async {
+    addTestFile(r'''
+class A {
+  void foo() {}
+}
+abstract class B implements A {
+  static set foo(_) {}
+}
+''');
+    await resolveTestFile();
+    assertTestErrors([CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
+  }
+
+  test_error_conflictingStaticAndInstance_inInterface_setter_setter() async {
+    addTestFile(r'''
+class A {
+  set foo(_) {}
+}
+abstract class B implements A {
+  static set foo(_) {}
+}
+''');
+    await resolveTestFile();
+    assertTestErrors([CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
+  }
+
+  test_error_conflictingStaticAndInstance_inMixin_getter_getter() async {
+    addTestFile(r'''
+class A {
+  int get foo => 0;
+}
+class B extends Object with A {
+  static int get foo => 0;
+}
+''');
+    await resolveTestFile();
+    assertTestErrors([CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
+  }
+
+  test_error_conflictingStaticAndInstance_inMixin_getter_method() async {
+    addTestFile(r'''
+class A {
+  int get foo => 0;
+}
+class B extends Object with A {
+  static void foo() {}
+}
+''');
+    await resolveTestFile();
+    assertTestErrors([CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
+  }
+
+  test_error_conflictingStaticAndInstance_inMixin_getter_setter() async {
+    addTestFile(r'''
+class A {
+  set foo(_) {}
+}
+class B extends Object with A {
+  static int get foo => 0;
+}
+''');
+    await resolveTestFile();
+    assertTestErrors([CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
+  }
+
+  test_error_conflictingStaticAndInstance_inMixin_method_getter() async {
+    addTestFile(r'''
+class A {
+  int get foo => 0;
+}
+class B extends Object with A {
+  static void foo() {}
+}
+''');
+    await resolveTestFile();
+    assertTestErrors([CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
+  }
+
+  test_error_conflictingStaticAndInstance_inMixin_method_method() async {
+    addTestFile(r'''
+class A {
+  void foo() {}
+}
+class B extends Object with A {
+  static void foo() {}
+}
+''');
+    await resolveTestFile();
+    assertTestErrors([CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
+  }
+
+  test_error_conflictingStaticAndInstance_inMixin_method_setter() async {
+    addTestFile(r'''
+class A {
+  set foo(_) {}
+}
+class B extends Object with A {
+  static void foo() {}
+}
+''');
+    await resolveTestFile();
+    assertTestErrors([CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
+  }
+
+  test_error_conflictingStaticAndInstance_inMixin_setter_method() async {
+    addTestFile(r'''
+class A {
+  void foo() {}
+}
+class B extends Object with A {
+  static set foo(_) {}
+}
+''');
+    await resolveTestFile();
+    assertTestErrors([CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
+  }
+
+  test_error_conflictingStaticAndInstance_inMixin_setter_setter() async {
+    addTestFile(r'''
+class A {
+  set foo(_) {}
+}
+class B extends Object with A {
+  static set foo(_) {}
+}
+''');
+    await resolveTestFile();
+    assertTestErrors([CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
+  }
+
+  test_error_conflictingStaticAndInstance_inSuper_getter_getter() async {
+    addTestFile(r'''
+class A {
+  int get foo => 0;
+}
+class B extends A {
+  static int get foo => 0;
+}
+''');
+    await resolveTestFile();
+    assertTestErrors([CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
+  }
+
+  test_error_conflictingStaticAndInstance_inSuper_getter_method() async {
+    addTestFile(r'''
+class A {
+  int get foo => 0;
+}
+class B extends A {
+  static void foo() {}
+}
+''');
+    await resolveTestFile();
+    assertTestErrors([CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
+  }
+
+  test_error_conflictingStaticAndInstance_inSuper_getter_setter() async {
+    addTestFile(r'''
+class A {
+  set foo(_) {}
+}
+class B extends A {
+  static int get foo => 0;
+}
+''');
+    await resolveTestFile();
+    assertTestErrors([CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
+  }
+
+  test_error_conflictingStaticAndInstance_inSuper_method_getter() async {
+    addTestFile(r'''
+class A {
+  int get foo => 0;
+}
+class B extends A {
+  static void foo() {}
+}
+''');
+    await resolveTestFile();
+    assertTestErrors([CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
+  }
+
+  test_error_conflictingStaticAndInstance_inSuper_method_method() async {
+    addTestFile(r'''
+class A {
+  void foo() {}
+}
+class B extends A {
+  static void foo() {}
+}
+''');
+    await resolveTestFile();
+    assertTestErrors([CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
+  }
+
+  test_error_conflictingStaticAndInstance_inSuper_method_setter() async {
+    addTestFile(r'''
+class A {
+  set foo(_) {}
+}
+class B extends A {
+  static void foo() {}
+}
+''');
+    await resolveTestFile();
+    assertTestErrors([CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
+  }
+
+  test_error_conflictingStaticAndInstance_inSuper_setter_method() async {
+    addTestFile(r'''
+class A {
+  void foo() {}
+}
+class B extends A {
+  static set foo(_) {}
+}
+''');
+    await resolveTestFile();
+    assertTestErrors([CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
+  }
+
+  test_error_conflictingStaticAndInstance_inSuper_setter_setter() async {
+    addTestFile(r'''
+class A {
+  set foo(_) {}
+}
+class B extends A {
+  static set foo(_) {}
+}
+''');
+    await resolveTestFile();
+    assertTestErrors([CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
+  }
+
+  test_error_duplicateConstructorDefault() async {
+    addTestFile(r'''
+class C {
+  C();
+  C();
+}
+''');
+    await resolveTestFile();
+    assertTestErrors([
+      CompileTimeErrorCode.DUPLICATE_CONSTRUCTOR_DEFAULT,
+    ]);
+  }
+
+  test_error_duplicateConstructorName() async {
+    addTestFile(r'''
+class C {
+  C.foo();
+  C.foo();
+}
+''');
+    await resolveTestFile();
+    assertTestErrors([
+      CompileTimeErrorCode.DUPLICATE_CONSTRUCTOR_NAME,
+    ]);
+  }
+
+  test_error_duplicateDefinition_field_field() async {
+    addTestFile(r'''
+class C {
+  int foo;
+  int foo;
+}
+''');
+    await resolveTestFile();
+    assertTestErrors([CompileTimeErrorCode.DUPLICATE_DEFINITION]);
+  }
+
+  test_error_duplicateDefinition_field_field_static() async {
+    addTestFile(r'''
+class C {
+  static int foo;
+  static int foo;
+}
+''');
+    await resolveTestFile();
+    assertTestErrors([CompileTimeErrorCode.DUPLICATE_DEFINITION]);
+  }
+
+  test_error_duplicateDefinition_field_getter() async {
+    addTestFile(r'''
+class C {
+  int foo;
+  int get foo => 0;
+}
+''');
+    await resolveTestFile();
+    assertTestErrors([CompileTimeErrorCode.DUPLICATE_DEFINITION]);
+  }
+
+  test_error_duplicateDefinition_field_method() async {
+    addTestFile(r'''
+class C {
+  int foo;
+  void foo() {}
+}
+''');
+    await resolveTestFile();
+    assertTestErrors([CompileTimeErrorCode.DUPLICATE_DEFINITION]);
+  }
+
+  test_error_duplicateDefinition_getter_getter() async {
+    addTestFile(r'''
+class C {
+  int get foo => 0;
+  int get foo => 0;
+}
+''');
+    await resolveTestFile();
+    assertTestErrors([CompileTimeErrorCode.DUPLICATE_DEFINITION]);
+  }
+
+  test_error_duplicateDefinition_getter_method() async {
+    addTestFile(r'''
+class C {
+  int get foo => 0;
+  void foo() {}
+}
+''');
+    await resolveTestFile();
+    assertTestErrors([CompileTimeErrorCode.DUPLICATE_DEFINITION]);
+  }
+
+  test_error_duplicateDefinition_method_getter() async {
+    addTestFile(r'''
+class C {
+  void foo() {}
+  int get foo => 0;
+}
+''');
+    await resolveTestFile();
+    assertTestErrors([CompileTimeErrorCode.DUPLICATE_DEFINITION]);
+  }
+
+  test_error_duplicateDefinition_method_method() async {
+    addTestFile(r'''
+class C {
+  void foo() {}
+  void foo() {}
+}
+''');
+    await resolveTestFile();
+    assertTestErrors([CompileTimeErrorCode.DUPLICATE_DEFINITION]);
+  }
+
+  test_error_duplicateDefinition_method_setter() async {
+    addTestFile(r'''
+class C {
+  void foo() {}
+  set foo(_) {}
+}
+''');
+    await resolveTestFile();
+    assertTestErrors([CompileTimeErrorCode.DUPLICATE_DEFINITION]);
+  }
+
+  test_error_duplicateDefinition_OK_fieldFinal_setter() async {
+    addTestFile(r'''
+class C {
+  final int foo = 0;
+  set foo(int x) {}
+}
+''');
+    await resolveTestFile();
+    assertNoTestErrors();
+  }
+
+  test_error_duplicateDefinition_OK_getter_setter() async {
+    addTestFile(r'''
+class C {
+  int get foo => 0;
+  set foo(_) {}
+}
+''');
+    await resolveTestFile();
+    assertNoTestErrors();
+  }
+
+  test_error_duplicateDefinition_OK_setter_getter() async {
+    addTestFile(r'''
+class C {
+  set foo(_) {}
+  int get foo => 0;
+}
+''');
+    await resolveTestFile();
+    assertNoTestErrors();
+  }
+
+  test_error_duplicateDefinition_setter_method() async {
+    addTestFile(r'''
+class C {
+  set foo(_) {}
+  void foo() {}
+}
+''');
+    await resolveTestFile();
+    assertTestErrors([CompileTimeErrorCode.DUPLICATE_DEFINITION]);
+  }
+
+  test_error_duplicateDefinition_setter_setter() async {
+    addTestFile(r'''
+class C {
+  void set foo(_) {}
+  void set foo(_) {}
+}
+''');
+    await resolveTestFile();
+    assertTestErrors([CompileTimeErrorCode.DUPLICATE_DEFINITION]);
+  }
+
+  test_error_extendsNonClass_dynamic() async {
+    addTestFile(r'''
+class A extends dynamic {}
+''');
+    await resolveTestFile();
+    assertTestErrors([
+      CompileTimeErrorCode.EXTENDS_NON_CLASS,
+    ]);
+
+    var a = findElement.class_('A');
+    assertElementType(a.supertype, objectType);
+  }
+
+  test_error_extendsNonClass_enum() async {
+    addTestFile(r'''
+enum E { ONE }
+class A extends E {}
+''');
+    await resolveTestFile();
+    assertTestErrors([
+      CompileTimeErrorCode.EXTENDS_NON_CLASS,
+    ]);
+
+    var a = findElement.class_('A');
+    assertElementType(a.supertype, objectType);
+
+    var eRef = findNode.typeName('E {}');
+    assertTypeName(eRef, findElement.enum_('E'), 'E');
+  }
+
+  test_error_extendsNonClass_mixin() async {
+    addTestFile(r'''
+mixin M {}
+class A extends M {} // ref
+''');
+    await resolveTestFile();
+    assertTestErrors([
+      CompileTimeErrorCode.EXTENDS_NON_CLASS,
+    ]);
+
+    var a = findElement.class_('A');
+    assertElementType(a.supertype, objectType);
+
+    var mRef = findNode.typeName('M {} // ref');
+    assertTypeName(mRef, findElement.mixin('M'), 'M');
+  }
+
+  test_error_extendsNonClass_variable() async {
+    addTestFile(r'''
+int v;
+class A extends v {}
+''');
+    await resolveTestFile();
+    assertTestErrors([
+      CompileTimeErrorCode.EXTENDS_NON_CLASS,
+    ]);
+
+    var a = findElement.class_('A');
+    assertElementType(a.supertype, objectType);
+  }
+
+  test_error_implementsRepeated() async {
+    addTestFile(r'''
+class A {}
+class B implements A, A {} // ref
+''');
+    await resolveTestFile();
+    assertTestErrors([CompileTimeErrorCode.IMPLEMENTS_REPEATED]);
+
+    var a = findElement.class_('A');
+    assertTypeName(findNode.typeName('A, A {} // ref'), a, 'A');
+    assertTypeName(findNode.typeName('A {} // ref'), a, 'A');
+  }
+
+  test_error_implementsRepeated_3times() async {
+    addTestFile(r'''
+class A {} class C{}
+class B implements A, A, A, A {}''');
+    await resolveTestFile();
+    assertTestErrors([
+      CompileTimeErrorCode.IMPLEMENTS_REPEATED,
+      CompileTimeErrorCode.IMPLEMENTS_REPEATED,
+      CompileTimeErrorCode.IMPLEMENTS_REPEATED
+    ]);
+  }
+
   test_error_memberWithClassName_getter() async {
     addTestFile(r'''
 class C {
@@ -66,8 +1286,400 @@
     expect(method.isSetter, isTrue);
     expect(method.isStatic, isTrue);
   }
+
+  test_inconsistentMethodInheritance_parameterType() async {
+    addTestFile(r'''
+abstract class A {
+  x(int i);
+}
+abstract class B {
+  x(String s);
+}
+abstract class C implements A, B {}
+''');
+    await resolveTestFile();
+    assertTestErrors([
+      StaticTypeWarningCode.INCONSISTENT_METHOD_INHERITANCE,
+    ]);
+  }
+
+  test_inconsistentMethodInheritance_requiredParameters() async {
+    addTestFile(r'''
+abstract class A {
+  x();
+}
+abstract class B {
+  x(int y);
+}
+abstract class C implements A, B {}
+''');
+    await resolveTestFile();
+    assertTestErrors([
+      StaticTypeWarningCode.INCONSISTENT_METHOD_INHERITANCE,
+    ]);
+  }
+
+  test_inconsistentMethodInheritance_returnType() async {
+    addTestFile(r'''
+abstract class A {
+  int x();
+}
+abstract class B {
+  String x();
+}
+abstract class C implements A, B {}
+''');
+    await resolveTestFile();
+    assertTestErrors([
+      StaticTypeWarningCode.INCONSISTENT_METHOD_INHERITANCE,
+    ]);
+  }
+
+  test_inconsistentMethodInheritanceGetterAndMethod_getter_method() async {
+    addTestFile(r'''
+abstract class A {
+  int get x;
+}
+abstract class B {
+  int x();
+}
+abstract class C implements A, B {}
+''');
+    await resolveTestFile();
+    assertTestErrors([
+      StaticWarningCode.INCONSISTENT_METHOD_INHERITANCE_GETTER_AND_METHOD,
+    ]);
+  }
+
+  test_inconsistentMethodInheritanceGetterAndMethod_method_getter() async {
+    addTestFile(r'''
+abstract class A {
+  int x();
+}
+abstract class B {
+  int get x;
+}
+abstract class C implements A, B {}
+''');
+    await resolveTestFile();
+    assertTestErrors([
+      StaticWarningCode.INCONSISTENT_METHOD_INHERITANCE_GETTER_AND_METHOD,
+    ]);
+  }
+
+  test_mixinInference_conflictingSubstitution() async {
+    setAnalysisOptions(enableSuperMixins: true);
+    addTestFile('''
+abstract class A<T> {}
+class M<T> extends A<Map<T, T>> {}
+class C extends A<Map<int, String>> with M {}
+''');
+    await resolveTestFile();
+    assertTestErrors([
+      CompileTimeErrorCode.MIXIN_INFERENCE_NO_POSSIBLE_SUBSTITUTION,
+      CompileTimeErrorCode.CONFLICTING_GENERIC_INTERFACES
+    ]);
+  }
+
+  test_mixinInference_doNotIgnorePreviousExplicitMixins() async {
+    setAnalysisOptions(enableSuperMixins: true);
+    addTestFile('''
+class A extends Object with B<String>, C {}
+class B<T> {}
+class C<T> extends B<T> {}
+''');
+    await resolveTestFile();
+    assertNoTestErrors();
+    var mixins = result.unit.declaredElement.getType('A').mixins;
+    expect(mixins[1].toString(), 'C<String>');
+  }
+
+  test_mixinInference_impossibleSubstitution() async {
+    setAnalysisOptions(enableSuperMixins: true);
+    addTestFile('''
+abstract class A<T> {}
+class M<T> extends A<Map<T, T>> {}
+class C extends A<List<int>> with M {}
+''');
+    await resolveTestFile();
+    assertTestErrors([
+      CompileTimeErrorCode.MIXIN_INFERENCE_NO_POSSIBLE_SUBSTITUTION,
+      CompileTimeErrorCode.CONFLICTING_GENERIC_INTERFACES
+    ]);
+  }
+
+  test_mixinInference_noMatchingClass_constraintSatisfiedByImplementsClause() async {
+    setAnalysisOptions(enableSuperMixins: true);
+    addTestFile('''
+abstract class A<T> {}
+class B {}
+class M<T> extends A<T> {}
+class C extends Object with M implements A<B> {}
+''');
+    await resolveTestFile();
+    assertTestErrors([
+      CompileTimeErrorCode.MIXIN_INFERENCE_NO_MATCHING_CLASS,
+      CompileTimeErrorCode.CONFLICTING_GENERIC_INTERFACES,
+    ]);
+  }
+
+  test_recursiveInterfaceInheritance_extends() async {
+    addTestFile(r'''
+class A extends B {}
+class B extends A {}''');
+    await resolveTestFile();
+    assertTestErrors([
+      CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE,
+      CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE
+    ]);
+  }
+
+  test_recursiveInterfaceInheritance_extends_implements() async {
+    addTestFile(r'''
+class A extends B {}
+class B implements A {}''');
+    await resolveTestFile();
+    assertTestErrors([
+      CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE,
+      CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE
+    ]);
+  }
+
+  test_recursiveInterfaceInheritance_implements() async {
+    addTestFile(r'''
+class A implements B {}
+class B implements A {}''');
+    await resolveTestFile();
+    assertTestErrors([
+      CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE,
+      CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE
+    ]);
+  }
+
+  test_recursiveInterfaceInheritance_mixin() async {
+    addTestFile(r'''
+class M1 = Object with M2;
+class M2 = Object with M1;''');
+    await resolveTestFile();
+    assertTestErrors([
+      CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE,
+      CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE
+    ]);
+  }
+
+  test_recursiveInterfaceInheritance_mixin_superclass() async {
+    // Make sure we don't get CompileTimeErrorCode.MIXIN_HAS_NO_CONSTRUCTORS in
+    // addition--that would just be confusing.
+    addTestFile('''
+class C = D with M;
+class D = C with M;
+class M {}
+''');
+    await resolveTestFile();
+    assertTestErrors([
+      CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE,
+      CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE
+    ]);
+  }
+
+  test_recursiveInterfaceInheritance_tail() async {
+    addTestFile(r'''
+abstract class A implements A {}
+class B implements A {}''');
+    await resolveTestFile();
+    assertTestErrors(
+        [CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_IMPLEMENTS]);
+  }
+
+  test_recursiveInterfaceInheritance_tail2() async {
+    addTestFile(r'''
+abstract class A implements B {}
+abstract class B implements A {}
+class C implements A {}''');
+    await resolveTestFile();
+    assertTestErrors([
+      CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE,
+      CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE
+    ]);
+  }
+
+  test_recursiveInterfaceInheritance_tail3() async {
+    addTestFile(r'''
+abstract class A implements B {}
+abstract class B implements C {}
+abstract class C implements A {}
+class D implements A {}''');
+    await resolveTestFile();
+    assertTestErrors([
+      CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE,
+      CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE,
+      CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE
+    ]);
+  }
+
+  test_recursiveInterfaceInheritanceExtends() async {
+    addTestFile("class A extends A {}");
+    await resolveTestFile();
+    assertTestErrors(
+        [CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_EXTENDS]);
+  }
+
+  test_recursiveInterfaceInheritanceExtends_abstract() async {
+    addTestFile(r'''
+class C extends C {
+  var bar = 0;
+  m();
+}
+''');
+    await resolveTestFile();
+    assertTestErrors([
+      CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_EXTENDS,
+      StaticWarningCode.CONCRETE_CLASS_WITH_ABSTRACT_MEMBER,
+      StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE
+    ]);
+  }
+
+  test_recursiveInterfaceInheritanceImplements() async {
+    addTestFile("class A implements A {}");
+    await resolveTestFile();
+    assertTestErrors(
+        [CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_IMPLEMENTS]);
+  }
+
+  test_recursiveInterfaceInheritanceImplements_typeAlias() async {
+    addTestFile(r'''
+class A {}
+class M {}
+class B = A with M implements B;''');
+    await resolveTestFile();
+    assertTestErrors(
+        [CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_IMPLEMENTS]);
+  }
+
+  test_recursiveInterfaceInheritanceWith() async {
+    addTestFile("class M = Object with M;");
+    await resolveTestFile();
+    assertTestErrors([
+      CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_WITH,
+    ]);
+  }
+
+  test_undefinedSuperGetter() async {
+    addTestFile(r'''
+class A {}
+class B extends A {
+  get g {
+    return super.g;
+  }
+}''');
+    await resolveTestFile();
+    assertTestErrors([StaticTypeWarningCode.UNDEFINED_SUPER_GETTER]);
+  }
+
+  test_undefinedSuperMethod() async {
+    addTestFile(r'''
+class A {}
+class B extends A {
+  m() {
+    return super.m();
+  }
+}''');
+    await resolveTestFile();
+    assertTestErrors([StaticTypeWarningCode.UNDEFINED_SUPER_METHOD]);
+  }
+
+  test_undefinedSuperOperator_binaryExpression() async {
+    addTestFile(r'''
+class A {}
+class B extends A {
+  operator +(value) {
+    return super + value;
+  }
+}''');
+    await resolveTestFile();
+    assertTestErrors([StaticTypeWarningCode.UNDEFINED_SUPER_OPERATOR]);
+  }
+
+  test_undefinedSuperOperator_indexBoth() async {
+    addTestFile(r'''
+class A {}
+class B extends A {
+  operator [](index) {
+    return super[index]++;
+  }
+}''');
+    await resolveTestFile();
+    assertTestErrors([StaticTypeWarningCode.UNDEFINED_SUPER_OPERATOR]);
+  }
+
+  test_undefinedSuperOperator_indexGetter() async {
+    addTestFile(r'''
+class A {}
+class B extends A {
+  operator [](index) {
+    return super[index + 1];
+  }
+}''');
+    await resolveTestFile();
+    assertTestErrors([StaticTypeWarningCode.UNDEFINED_SUPER_OPERATOR]);
+  }
+
+  test_undefinedSuperOperator_indexSetter() async {
+    addTestFile(r'''
+class A {}
+class B extends A {
+  operator []=(index, value) {
+    super[index] = 0;
+  }
+}''');
+    await resolveTestFile();
+    assertTestErrors([StaticTypeWarningCode.UNDEFINED_SUPER_OPERATOR]);
+  }
+
+  test_undefinedSuperSetter() async {
+    addTestFile(r'''
+class A {}
+class B extends A {
+  f() {
+    super.m = 0;
+  }
+}''');
+    await resolveTestFile();
+    assertTestErrors([StaticTypeWarningCode.UNDEFINED_SUPER_SETTER]);
+  }
 }
 
 @reflectiveTest
 class ClassTaskResolutionTest extends TaskResolutionTest
-    with ClassResolutionMixin {}
+    with ClassResolutionMixin {
+  @failingTest
+  test_conflictingGenericInterfaces_simple() {
+    return super.test_conflictingGenericInterfaces_simple();
+  }
+
+  @failingTest
+  test_conflictingGenericInterfaces_viaMixin() {
+    return super.test_conflictingGenericInterfaces_viaMixin();
+  }
+
+  @failingTest
+  test_mixinInference_conflictingSubstitution() {
+    return super.test_mixinInference_conflictingSubstitution();
+  }
+
+  @failingTest
+  test_mixinInference_doNotIgnorePreviousExplicitMixins() {
+    return super.test_mixinInference_doNotIgnorePreviousExplicitMixins();
+  }
+
+  @failingTest
+  test_mixinInference_impossibleSubstitution() {
+    return super.test_mixinInference_impossibleSubstitution();
+  }
+
+  @failingTest
+  test_mixinInference_noMatchingClass_constraintSatisfiedByImplementsClause() {
+    return super
+        .test_mixinInference_noMatchingClass_constraintSatisfiedByImplementsClause();
+  }
+}
diff --git a/pkg/analyzer/test/src/dart/resolution/driver_resolution.dart b/pkg/analyzer/test/src/dart/resolution/driver_resolution.dart
index 9c93015..2f4059c 100644
--- a/pkg/analyzer/test/src/dart/resolution/driver_resolution.dart
+++ b/pkg/analyzer/test/src/dart/resolution/driver_resolution.dart
@@ -37,6 +37,15 @@
     );
   }
 
+  @override
+  void setAnalysisOptions({bool enableSuperMixins}) {
+    var analysisOptions = new AnalysisOptionsImpl();
+    if (enableSuperMixins != null) {
+      analysisOptions.enableSuperMixins = enableSuperMixins;
+    }
+    driver.configure(analysisOptions: analysisOptions);
+  }
+
   void setUp() {
     sdk = new MockSdk(resourceProvider: resourceProvider);
     logger = new PerformanceLog(logBuffer);
diff --git a/pkg/analyzer/test/src/dart/resolution/enum_test.dart b/pkg/analyzer/test/src/dart/resolution/enum_test.dart
new file mode 100644
index 0000000..2171622
--- /dev/null
+++ b/pkg/analyzer/test/src/dart/resolution/enum_test.dart
@@ -0,0 +1,47 @@
+import 'package:analyzer/src/error/codes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'driver_resolution.dart';
+import 'resolution.dart';
+import 'task_resolution.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(EnumDriverResolutionTest);
+    defineReflectiveTests(EnumTaskResolutionTest);
+  });
+}
+
+@reflectiveTest
+class EnumDriverResolutionTest extends DriverResolutionTest
+    with EnumResolutionMixin {}
+
+abstract class EnumResolutionMixin implements ResolutionTest {
+  test_error_conflictingStaticAndInstance_index() async {
+    addTestFile(r'''
+enum E {
+  a, index
+}
+''');
+    await resolveTestFile();
+    assertTestErrors([CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
+  }
+
+  test_inference_listLiteral() async {
+    addTestFile(r'''
+enum E1 {a, b}
+enum E2 {a, b}
+
+var v = [E1.a, E2.b];
+''');
+    await resolveTestFile();
+    assertNoTestErrors();
+
+    var v = findElement.topVar('v');
+    assertElementTypeString(v.type, 'List<Object>');
+  }
+}
+
+@reflectiveTest
+class EnumTaskResolutionTest extends TaskResolutionTest
+    with EnumResolutionMixin {}
diff --git a/pkg/analyzer/test/src/dart/resolution/find_element.dart b/pkg/analyzer/test/src/dart/resolution/find_element.dart
index 0b1ed90..fe7cb76 100644
--- a/pkg/analyzer/test/src/dart/resolution/find_element.dart
+++ b/pkg/analyzer/test/src/dart/resolution/find_element.dart
@@ -21,6 +21,27 @@
     fail('Not found class: $name');
   }
 
+  ConstructorElement constructor(String name, {String className}) {
+    assert(name != '');
+    ConstructorElement result;
+    for (var class_ in unitElement.types) {
+      if (className == null || class_.name == className) {
+        for (var constructor in class_.constructors) {
+          if (constructor.name == name) {
+            if (result != null) {
+              throw new StateError('Not constructor name: $name');
+            }
+            result = constructor;
+          }
+        }
+      }
+    }
+    if (result != null) {
+      return result;
+    }
+    fail('Not found constructor: $name');
+  }
+
   ClassElement enum_(String name) {
     for (var enum_ in unitElement.enums) {
       if (enum_.name == name) {
@@ -74,8 +95,11 @@
     fail('Not found top-level function: $name');
   }
 
-  PropertyAccessorElement getter(String name) {
+  PropertyAccessorElement getter(String name, {String className}) {
     for (var class_ in unitElement.types) {
+      if (className != null && class_.name != className) {
+        continue;
+      }
       for (var accessor in class_.accessors) {
         if (accessor.isGetter && accessor.displayName == name) {
           return accessor;
@@ -125,14 +149,37 @@
     return result;
   }
 
-  MethodElement method(String name) {
-    for (var type in unitElement.types) {
-      for (var method in type.methods) {
+  MethodElement method(String name, {String of}) {
+    MethodElement result;
+
+    void findIn(List<MethodElement> methods) {
+      for (var method in methods) {
         if (method.name == name) {
-          return method;
+          if (result != null) {
+            throw new StateError('Method name $name is not unique.');
+          }
+          result = method;
         }
       }
     }
+
+    for (var class_ in unitElement.types) {
+      if (of != null && class_.name != of) {
+        continue;
+      }
+      findIn(class_.methods);
+    }
+
+    for (var mixin in unitElement.mixins) {
+      if (of != null && mixin.name != of) {
+        continue;
+      }
+      findIn(mixin.methods);
+    }
+
+    if (result != null) {
+      return result;
+    }
     fail('Not found class method: $name');
   }
 
@@ -189,10 +236,10 @@
     fail('Prefix not found: $name');
   }
 
-  PropertyAccessorElement setter(String name, {String inClass}) {
+  PropertyAccessorElement setter(String name, {String className}) {
     PropertyAccessorElement result;
     for (var class_ in unitElement.types) {
-      if (inClass != null && class_.name != inClass) {
+      if (className != null && class_.name != className) {
         continue;
       }
       for (var accessor in class_.accessors) {
diff --git a/pkg/analyzer/test/src/dart/resolution/find_node.dart b/pkg/analyzer/test/src/dart/resolution/find_node.dart
index 55998cc..2b99226 100644
--- a/pkg/analyzer/test/src/dart/resolution/find_node.dart
+++ b/pkg/analyzer/test/src/dart/resolution/find_node.dart
@@ -100,6 +100,10 @@
     return _node(search, (n) => n is PrefixedIdentifier);
   }
 
+  PropertyAccess propertyAccess(String search) {
+    return _node(search, (n) => n is PropertyAccess);
+  }
+
   RethrowExpression rethrow_(String search) {
     return _node(search, (n) => n is RethrowExpression);
   }
diff --git a/pkg/analyzer/test/src/dart/resolution/instance_creation_test.dart b/pkg/analyzer/test/src/dart/resolution/instance_creation_test.dart
new file mode 100644
index 0000000..6ac6d4c
--- /dev/null
+++ b/pkg/analyzer/test/src/dart/resolution/instance_creation_test.dart
@@ -0,0 +1,77 @@
+import 'package:analyzer/src/error/codes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'driver_resolution.dart';
+import 'resolution.dart';
+import 'task_resolution.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(InstanceCreationDriverResolutionTest);
+    defineReflectiveTests(InstanceCreationTaskResolutionTest);
+  });
+}
+
+@reflectiveTest
+class InstanceCreationDriverResolutionTest extends DriverResolutionTest
+    with InstanceCreationResolutionMixin {}
+
+abstract class InstanceCreationResolutionMixin implements ResolutionTest {
+  test_error_wrongNumberOfTypeArgumentsConstructor_implicitNew() async {
+    addTestFile(r'''
+class Foo<X> {
+  Foo.bar();
+}
+
+main() {
+  Foo.bar<int>();
+}
+''');
+    await resolveTestFile();
+    assertTestErrors([
+      StaticTypeWarningCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS_CONSTRUCTOR,
+    ]);
+
+    var creation = findNode.instanceCreation('Foo.bar<int>');
+    assertInstanceCreation(
+      creation,
+      findElement.class_('Foo'),
+      'Foo<int>',
+      constructorName: 'bar',
+    );
+  }
+
+  test_error_wrongNumberOfTypeArgumentsConstructor_implicitNew_prefix() async {
+    newFile('/test/lib/a.dart', content: '''
+class Foo<X> {
+  Foo.bar();
+}
+''');
+    addTestFile('''
+import 'a.dart' as p;
+
+main() {
+  p.Foo.bar<int>();
+}
+''');
+    await resolveTestFile();
+    assertTestErrors([
+      StaticTypeWarningCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS_CONSTRUCTOR,
+    ]);
+
+    var import = findElement.import('package:test/a.dart');
+
+    var creation = findNode.instanceCreation('Foo.bar<int>');
+    assertInstanceCreation(
+      creation,
+      import.importedLibrary.getType('Foo'),
+      'Foo<int>',
+      constructorName: 'bar',
+      expectedPrefix: import.prefix,
+    );
+  }
+}
+
+@reflectiveTest
+class InstanceCreationTaskResolutionTest extends TaskResolutionTest
+    with InstanceCreationResolutionMixin {}
diff --git a/pkg/analyzer/test/src/dart/resolution/instance_member_inference_class_test.dart b/pkg/analyzer/test/src/dart/resolution/instance_member_inference_class_test.dart
new file mode 100644
index 0000000..1218643
--- /dev/null
+++ b/pkg/analyzer/test/src/dart/resolution/instance_member_inference_class_test.dart
@@ -0,0 +1,296 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for 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_reflective_loader/test_reflective_loader.dart';
+
+import 'driver_resolution.dart';
+import 'resolution.dart';
+import 'task_resolution.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(InstanceMemberInferenceClassDriverResolutionTest);
+    defineReflectiveTests(InstanceMemberInferenceClassTaskResolutionTest);
+  });
+}
+
+@reflectiveTest
+class InstanceMemberInferenceClassDriverResolutionTest
+    extends DriverResolutionTest with InstanceMemberInferenceClassMixin {}
+
+abstract class InstanceMemberInferenceClassMixin implements ResolutionTest {
+  test_invalid_inheritanceCycle() async {
+    addTestFile('''
+class A extends C {}
+class B extends A {}
+class C extends B {}
+''');
+    await resolveTestFile();
+  }
+
+  test_method_parameter_multiple_different() async {
+    addTestFile('''
+class A {
+  foo(int p) => 0;
+}
+class B {
+  foo(double p) => 0;
+}
+class C implements A, B {
+  foo(p) => 0;
+}
+''');
+    await resolveTestFile();
+
+    var p = findElement.method('foo', of: 'C').parameters[0];
+    assertElementTypeDynamic(p.type);
+  }
+
+  test_method_parameter_multiple_named_different() async {
+    addTestFile('''
+class A {
+  foo({int p}) => 0;
+}
+class B {
+  foo({int q}) => 0;
+}
+class C implements A, B {
+  foo({p}) => 0;
+}
+''');
+    await resolveTestFile();
+
+    var p = findElement.method('foo', of: 'C').parameters[0];
+    assertElementTypeDynamic(p.type);
+  }
+
+  test_method_parameter_multiple_named_same() async {
+    addTestFile('''
+class A {
+  foo({int p}) => 0;
+}
+class B {
+  foo({int p}) => 0;
+}
+class C implements A, B {
+  foo({p}) => 0;
+}
+''');
+    await resolveTestFile();
+
+    var p = findElement.method('foo', of: 'C').parameters[0];
+    assertElementTypeString(p.type, 'int');
+  }
+
+  test_method_parameter_multiple_namedAndRequired() async {
+    addTestFile('''
+class A {
+  foo({int p}) => 0;
+}
+class B {
+  foo(int p) => 0;
+}
+class C implements A, B {
+  foo(p) => 0;
+}
+''');
+    await resolveTestFile();
+
+    var p = findElement.method('foo', of: 'C').parameters[0];
+    assertElementTypeDynamic(p.type);
+  }
+
+  test_method_parameter_multiple_optionalAndRequired() async {
+    addTestFile('''
+class A {
+  foo(int p) => 0;
+}
+class B {
+  foo([int p]) => 0;
+}
+class C implements A, B {
+  foo(p) => 0;
+}
+''');
+    await resolveTestFile();
+
+    var p = findElement.method('foo', of: 'C').parameters[0];
+    assertElementTypeString(p.type, 'int');
+  }
+
+  test_method_parameter_single_generic() async {
+    addTestFile('''
+class A<E> {
+  foo(E p) => 0;
+}
+class C<T> implements A<T> {
+  foo(p) => 0;
+}
+''');
+    await resolveTestFile();
+
+    var p = findElement.method('foo', of: 'C').parameters[0];
+    assertElementTypeString(p.type, 'T');
+  }
+
+  test_method_return_multiple_different() async {
+    addTestFile('''
+class A {
+  int foo() => 0;
+}
+class B {
+  double foo() => 0.0;
+}
+class C implements A, B {
+  foo() => 0;
+}
+''');
+    await resolveTestFile();
+
+    var foo = findElement.method('foo', of: 'C');
+    assertElementTypeDynamic(foo.returnType);
+  }
+
+  test_method_return_multiple_different_generic() async {
+    addTestFile('''
+class A<E> {
+  E foo() => null;
+}
+class B<E> {
+  E foo() => null;
+}
+class C implements A<int>, B<double> {
+  foo() => null;
+}
+''');
+    await resolveTestFile();
+
+    var foo = findElement.method('foo', of: 'C');
+    assertElementTypeDynamic(foo.returnType);
+  }
+
+  test_method_return_multiple_different_void() async {
+    addTestFile('''
+class A {
+  int foo() => 0;
+}
+class B {
+  void foo() => 0;
+}
+class C implements A, B {
+  foo() => 0;
+}
+''');
+    await resolveTestFile();
+
+    var foo = findElement.method('foo', of: 'C');
+    assertElementTypeDynamic(foo.returnType);
+  }
+
+  test_method_return_multiple_dynamic() async {
+    addTestFile('''
+class A {
+  int foo() => 0;
+}
+class B {
+  foo() => 0;
+}
+class C implements A, B {
+  foo() => 0;
+}
+''');
+    await resolveTestFile();
+
+    var foo = findElement.method('foo', of: 'C');
+    assertElementTypeDynamic(foo.returnType);
+  }
+
+  test_method_return_multiple_same_generic() async {
+    addTestFile('''
+class A<E> {
+  E foo() => 0;
+}
+class B<E> {
+  E foo() => 0;
+}
+class C<T> implements A<T>, B<T> {
+  foo() => 0;
+}
+''');
+    await resolveTestFile();
+
+    var foo = findElement.method('foo', of: 'C');
+    assertElementTypeString(foo.returnType, 'T');
+  }
+
+  test_method_return_multiple_same_nonVoid() async {
+    addTestFile('''
+class A {
+  int foo() => 0;
+}
+class B {
+  int foo() => 0;
+}
+class C implements A, B {
+  foo() => 0;
+}
+''');
+    await resolveTestFile();
+
+    var foo = findElement.method('foo', of: 'C');
+    assertElementTypeString(foo.returnType, 'int');
+  }
+
+  test_method_return_multiple_same_void() async {
+    addTestFile('''
+class A {
+  void foo() {};
+}
+class B {
+  void foo() {};
+}
+class C implements A, B {
+  foo() {};
+}
+''');
+    await resolveTestFile();
+
+    var foo = findElement.method('foo', of: 'C');
+    assertElementTypeString(foo.returnType, 'void');
+  }
+
+  test_method_return_single() async {
+    addTestFile('''
+class A {
+  int foo() => 0;
+}
+class B extends A {
+  foo() => 0;
+}
+''');
+    await resolveTestFile();
+
+    var foo = findElement.method('foo', of: 'B');
+    assertElementTypeString(foo.returnType, 'int');
+  }
+
+  test_method_return_single_generic() async {
+    addTestFile('''
+class A<E> {
+  E foo() => 0;
+}
+class B<T> extends A<T> {
+  foo() => 0;
+}
+''');
+    await resolveTestFile();
+
+    var foo = findElement.method('foo', of: 'B');
+    assertElementTypeString(foo.returnType, 'T');
+  }
+}
+
+@reflectiveTest
+class InstanceMemberInferenceClassTaskResolutionTest extends TaskResolutionTest
+    with InstanceMemberInferenceClassMixin {}
diff --git a/pkg/analyzer/test/src/dart/resolution/instance_member_inference_mixin_test.dart b/pkg/analyzer/test/src/dart/resolution/instance_member_inference_mixin_test.dart
new file mode 100644
index 0000000..387e166
--- /dev/null
+++ b/pkg/analyzer/test/src/dart/resolution/instance_member_inference_mixin_test.dart
@@ -0,0 +1,296 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for 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_reflective_loader/test_reflective_loader.dart';
+
+import 'driver_resolution.dart';
+import 'resolution.dart';
+import 'task_resolution.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(InstanceMemberInferenceMixinDriverResolutionTest);
+    defineReflectiveTests(InstanceMemberInferenceMixinTaskResolutionTest);
+  });
+}
+
+@reflectiveTest
+class InstanceMemberInferenceMixinDriverResolutionTest
+    extends DriverResolutionTest with InstanceMemberInferenceMixinMixin {}
+
+abstract class InstanceMemberInferenceMixinMixin implements ResolutionTest {
+  test_invalid_inheritanceCycle() async {
+    addTestFile('''
+mixin A on C {}
+mixin B on A {}
+mixin C on B {}
+''');
+    await resolveTestFile();
+  }
+
+  test_method_parameter_multiple_different() async {
+    addTestFile('''
+class A {
+  foo(int p) => 0;
+}
+class B {
+  foo(double p) => 0;
+}
+mixin M on A, B {
+  foo(p) => 0;
+}
+''');
+    await resolveTestFile();
+
+    var p = findElement.method('foo', of: 'M').parameters[0];
+    assertElementTypeDynamic(p.type);
+  }
+
+  test_method_parameter_multiple_named_different() async {
+    addTestFile('''
+class A {
+  foo({int p}) => 0;
+}
+class B {
+  foo({int q}) => 0;
+}
+mixin M on A, B {
+  foo({p}) => 0;
+}
+''');
+    await resolveTestFile();
+
+    var p = findElement.method('foo', of: 'M').parameters[0];
+    assertElementTypeDynamic(p.type);
+  }
+
+  test_method_parameter_multiple_named_same() async {
+    addTestFile('''
+class A {
+  foo({int p}) => 0;
+}
+class B {
+  foo({int p}) => 0;
+}
+mixin M on A, B {
+  foo({p}) => 0;
+}
+''');
+    await resolveTestFile();
+
+    var p = findElement.method('foo', of: 'M').parameters[0];
+    assertElementTypeString(p.type, 'int');
+  }
+
+  test_method_parameter_multiple_namedAndRequired() async {
+    addTestFile('''
+class A {
+  foo({int p}) => 0;
+}
+class B {
+  foo(int p) => 0;
+}
+mixin M on A, B {
+  foo(p) => 0;
+}
+''');
+    await resolveTestFile();
+
+    var p = findElement.method('foo', of: 'M').parameters[0];
+    assertElementTypeDynamic(p.type);
+  }
+
+  test_method_parameter_multiple_optionalAndRequired() async {
+    addTestFile('''
+class A {
+  foo(int p) => 0;
+}
+class B {
+  foo([int p]) => 0;
+}
+mixin M on A, B {
+  foo(p) => 0;
+}
+''');
+    await resolveTestFile();
+
+    var p = findElement.method('foo', of: 'M').parameters[0];
+    assertElementTypeString(p.type, 'int');
+  }
+
+  test_method_parameter_single_generic() async {
+    addTestFile('''
+class A<E> {
+  foo(E p) => 0;
+}
+mixin M<T> on A<T> {
+  foo(p) => 0;
+}
+''');
+    await resolveTestFile();
+
+    var p = findElement.method('foo', of: 'M').parameters[0];
+    assertElementTypeString(p.type, 'T');
+  }
+
+  test_method_return_multiple_different() async {
+    addTestFile('''
+class A {
+  int foo() => 0;
+}
+class B {
+  double foo() => 0.0;
+}
+mixin M on A, B {
+  foo() => 0;
+}
+''');
+    await resolveTestFile();
+
+    var foo = findElement.method('foo', of: 'M');
+    assertElementTypeDynamic(foo.returnType);
+  }
+
+  test_method_return_multiple_different_generic() async {
+    addTestFile('''
+class A<E> {
+  E foo() => null;
+}
+class B<E> {
+  E foo() => null;
+}
+mixin M on A<int>, B<double> {
+  foo() => null;
+}
+''');
+    await resolveTestFile();
+
+    var foo = findElement.method('foo', of: 'M');
+    assertElementTypeDynamic(foo.returnType);
+  }
+
+  test_method_return_multiple_different_void() async {
+    addTestFile('''
+class A {
+  int foo() => 0;
+}
+class B {
+  void foo() => 0;
+}
+mixin M on A, B {
+  foo() => 0;
+}
+''');
+    await resolveTestFile();
+
+    var foo = findElement.method('foo', of: 'M');
+    assertElementTypeDynamic(foo.returnType);
+  }
+
+  test_method_return_multiple_dynamic() async {
+    addTestFile('''
+class A {
+  int foo() => 0;
+}
+class B {
+  foo() => 0;
+}
+mixin M on A, B {
+  foo() => 0;
+}
+''');
+    await resolveTestFile();
+
+    var foo = findElement.method('foo', of: 'M');
+    assertElementTypeDynamic(foo.returnType);
+  }
+
+  test_method_return_multiple_same_generic() async {
+    addTestFile('''
+class A<E> {
+  E foo() => 0;
+}
+class B<E> {
+  E foo() => 0;
+}
+mixin M<T> on A<T>, B<T> {
+  foo() => 0;
+}
+''');
+    await resolveTestFile();
+
+    var foo = findElement.method('foo', of: 'M');
+    assertElementTypeString(foo.returnType, 'T');
+  }
+
+  test_method_return_multiple_same_nonVoid() async {
+    addTestFile('''
+class A {
+  int foo() => 0;
+}
+class B {
+  int foo() => 0;
+}
+mixin M on A, B {
+  foo() => 0;
+}
+''');
+    await resolveTestFile();
+
+    var foo = findElement.method('foo', of: 'M');
+    assertElementTypeString(foo.returnType, 'int');
+  }
+
+  test_method_return_multiple_same_void() async {
+    addTestFile('''
+class A {
+  void foo() {};
+}
+class B {
+  void foo() {};
+}
+mixin M on A, B {
+  foo() {};
+}
+''');
+    await resolveTestFile();
+
+    var foo = findElement.method('foo', of: 'M');
+    assertElementTypeString(foo.returnType, 'void');
+  }
+
+  test_method_return_single() async {
+    addTestFile('''
+class A {
+  int foo() => 0;
+}
+mixin M on A {
+  foo() => 0;
+}
+''');
+    await resolveTestFile();
+
+    var foo = findElement.method('foo', of: 'M');
+    assertElementTypeString(foo.returnType, 'int');
+  }
+
+  test_method_return_single_generic() async {
+    addTestFile('''
+class A<E> {
+  E foo() => 0;
+}
+mixin M<T> on A<T> {
+  foo() => 0;
+}
+''');
+    await resolveTestFile();
+
+    var foo = findElement.method('foo', of: 'M');
+    assertElementTypeString(foo.returnType, 'T');
+  }
+}
+
+@reflectiveTest
+class InstanceMemberInferenceMixinTaskResolutionTest extends TaskResolutionTest
+    with InstanceMemberInferenceMixinMixin {}
diff --git a/pkg/analyzer/test/src/dart/resolution/mixin_test.dart b/pkg/analyzer/test/src/dart/resolution/mixin_test.dart
index 2440c6a..c06d210 100644
--- a/pkg/analyzer/test/src/dart/resolution/mixin_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/mixin_test.dart
@@ -1,4 +1,5 @@
 import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/src/dart/error/syntactic_errors.dart';
 import 'package:analyzer/src/error/codes.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -139,6 +140,17 @@
     assertTypeNull(aRef);
   }
 
+  test_conflictingGenericInterfaces() async {
+    addTestFile('''
+class I<T> {}
+class A implements I<int> {}
+class B implements I<String> {}
+mixin M on A implements B {}
+''');
+    await resolveTestFile();
+    assertTestErrors([CompileTimeErrorCode.CONFLICTING_GENERIC_INTERFACES]);
+  }
+
   test_element() async {
     addTestFile(r'''
 mixin M {}
@@ -151,7 +163,400 @@
     assertElement(mixin, element);
 
     expect(element.typeParameters, isEmpty);
+
+    expect(element.supertype, isNull);
+    expect(element.type.isObject, isFalse);
+
     assertElementTypes(element.superclassConstraints, [objectType]);
+    assertElementTypes(element.interfaces, []);
+  }
+
+  test_element_allSupertypes() async {
+    addTestFile(r'''
+class A {}
+class B {}
+class C {}
+
+mixin M1 on A, B {}
+mixin M2 on A implements B, C {}
+''');
+    await resolveTestFile();
+    assertNoTestErrors();
+
+    var a = findElement.class_('A');
+    var b = findElement.class_('B');
+    var c = findElement.class_('C');
+    assertElementTypes(
+      findElement.mixin('M1').allSupertypes,
+      [a.type, b.type, objectType],
+    );
+    assertElementTypes(
+      findElement.mixin('M2').allSupertypes,
+      [a.type, objectType, b.type, c.type],
+    );
+  }
+
+  test_element_allSupertypes_generic() async {
+    addTestFile(r'''
+class A<T, U> {}
+class B<T> extends A<int, T> {}
+
+mixin M1 on A<int, double> {}
+mixin M2 on B<String> {}
+''');
+    await resolveTestFile();
+    assertNoTestErrors();
+
+    var a = findElement.class_('A');
+    var b = findElement.class_('B');
+    assertElementTypes(
+      findElement.mixin('M1').allSupertypes,
+      [
+        a.type.instantiate([intType, doubleType]),
+        objectType
+      ],
+    );
+    assertElementTypes(
+      findElement.mixin('M2').allSupertypes,
+      [
+        b.type.instantiate([stringType]),
+        a.type.instantiate([intType, stringType]),
+        objectType
+      ],
+    );
+  }
+
+  test_error_builtInIdentifierAsTypeName() async {
+    addTestFile(r'''
+mixin as {}
+''');
+    await resolveTestFile();
+    assertTestErrors([CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_NAME]);
+  }
+
+  test_error_builtInIdentifierAsTypeName_OK_on() async {
+    addTestFile(r'''
+class A {}
+
+mixin on on A {}
+
+mixin M on on {}
+
+mixin M2 implements on {}
+
+class B = A with on;
+class C = B with M;
+class D = Object with M2;
+''');
+    await resolveTestFile();
+    assertNoTestErrors();
+  }
+
+  test_error_conflictingStaticAndInstance_inClass_getter_getter() async {
+    addTestFile(r'''
+mixin M {
+  static int get foo => 0;
+  int get foo => 0;
+}
+''');
+    await resolveTestFile();
+    assertTestErrors([CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
+  }
+
+  test_error_conflictingStaticAndInstance_inClass_getter_method() async {
+    addTestFile(r'''
+mixin M {
+  static int get foo => 0;
+  void foo() {}
+}
+''');
+    await resolveTestFile();
+    assertTestErrors([CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
+  }
+
+  test_error_conflictingStaticAndInstance_inClass_getter_setter() async {
+    addTestFile(r'''
+mixin M {
+  static int get foo => 0;
+  set foo(_) {}
+}
+''');
+    await resolveTestFile();
+    assertTestErrors([CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
+  }
+
+  test_error_conflictingStaticAndInstance_inClass_method_getter() async {
+    addTestFile(r'''
+mixin M {
+  static void foo() {}
+  int get foo => 0;
+}
+''');
+    await resolveTestFile();
+    assertTestErrors([CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
+  }
+
+  test_error_conflictingStaticAndInstance_inClass_method_method() async {
+    addTestFile(r'''
+mixin M {
+  static void foo() {}
+  void foo() {}
+}
+''');
+    await resolveTestFile();
+    assertTestErrors([CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
+  }
+
+  test_error_conflictingStaticAndInstance_inClass_method_setter() async {
+    addTestFile(r'''
+mixin M {
+  static void foo() {}
+  set foo(_) {}
+}
+''');
+    await resolveTestFile();
+    assertTestErrors([CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
+  }
+
+  test_error_conflictingStaticAndInstance_inClass_setter_getter() async {
+    addTestFile(r'''
+mixin M {
+  static set foo(_) {}
+  int get foo => 0;
+}
+''');
+    await resolveTestFile();
+    assertTestErrors([CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
+  }
+
+  test_error_conflictingStaticAndInstance_inClass_setter_method() async {
+    addTestFile(r'''
+mixin M {
+  static set foo(_) {}
+  void foo() {}
+}
+''');
+    await resolveTestFile();
+    assertTestErrors([CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
+  }
+
+  test_error_conflictingStaticAndInstance_inClass_setter_setter() async {
+    addTestFile(r'''
+mixin M {
+  static set foo(_) {}
+  set foo(_) {}
+}
+''');
+    await resolveTestFile();
+    assertTestErrors([CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
+  }
+
+  test_error_conflictingStaticAndInstance_inConstraint_getter_getter() async {
+    addTestFile(r'''
+class A {
+  int get foo => 0;
+}
+mixin M on A {
+  static int get foo => 0;
+}
+''');
+    await resolveTestFile();
+    assertTestErrors([CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
+  }
+
+  test_error_conflictingStaticAndInstance_inConstraint_getter_method() async {
+    addTestFile(r'''
+class A {
+  int get foo => 0;
+}
+mixin M on A {
+  static void foo() {}
+}
+''');
+    await resolveTestFile();
+    assertTestErrors([CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
+  }
+
+  test_error_conflictingStaticAndInstance_inConstraint_getter_setter() async {
+    addTestFile(r'''
+class A {
+  set foo(_) {}
+}
+mixin M on A {
+  static int get foo => 0;
+}
+''');
+    await resolveTestFile();
+    assertTestErrors([CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
+  }
+
+  test_error_conflictingStaticAndInstance_inConstraint_method_getter() async {
+    addTestFile(r'''
+class A {
+  int get foo => 0;
+}
+mixin M on A {
+  static void foo() {}
+}
+''');
+    await resolveTestFile();
+    assertTestErrors([CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
+  }
+
+  test_error_conflictingStaticAndInstance_inConstraint_method_method() async {
+    addTestFile(r'''
+class A {
+  void foo() {}
+}
+mixin M on A {
+  static void foo() {}
+}
+''');
+    await resolveTestFile();
+    assertTestErrors([CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
+  }
+
+  test_error_conflictingStaticAndInstance_inConstraint_method_setter() async {
+    addTestFile(r'''
+class A {
+  set foo(_) {}
+}
+mixin M on A {
+  static void foo() {}
+}
+''');
+    await resolveTestFile();
+    assertTestErrors([CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
+  }
+
+  test_error_conflictingStaticAndInstance_inConstraint_setter_method() async {
+    addTestFile(r'''
+class A {
+  void foo() {}
+}
+mixin M on A {
+  static set foo(_) {}
+}
+''');
+    await resolveTestFile();
+    assertTestErrors([CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
+  }
+
+  test_error_conflictingStaticAndInstance_inConstraint_setter_setter() async {
+    addTestFile(r'''
+class A {
+  set foo(_) {}
+}
+mixin M on A {
+  static set foo(_) {}
+}
+''');
+    await resolveTestFile();
+    assertTestErrors([CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
+  }
+
+  test_error_conflictingStaticAndInstance_inInterface_getter_getter() async {
+    addTestFile(r'''
+class A {
+  int get foo => 0;
+}
+mixin M implements A {
+  static int get foo => 0;
+}
+''');
+    await resolveTestFile();
+    assertTestErrors([CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
+  }
+
+  test_error_conflictingStaticAndInstance_inInterface_getter_method() async {
+    addTestFile(r'''
+class A {
+  int get foo => 0;
+}
+mixin M implements A {
+  static void foo() {}
+}
+''');
+    await resolveTestFile();
+    assertTestErrors([CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
+  }
+
+  test_error_conflictingStaticAndInstance_inInterface_getter_setter() async {
+    addTestFile(r'''
+class A {
+  set foo(_) {}
+}
+mixin M implements A {
+  static int get foo => 0;
+}
+''');
+    await resolveTestFile();
+    assertTestErrors([CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
+  }
+
+  test_error_conflictingStaticAndInstance_inInterface_method_getter() async {
+    addTestFile(r'''
+class A {
+  int get foo => 0;
+}
+mixin M implements A {
+  static void foo() {}
+}
+''');
+    await resolveTestFile();
+    assertTestErrors([CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
+  }
+
+  test_error_conflictingStaticAndInstance_inInterface_method_method() async {
+    addTestFile(r'''
+class A {
+  void foo() {}
+}
+mixin M implements A {
+  static void foo() {}
+}
+''');
+    await resolveTestFile();
+    assertTestErrors([CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
+  }
+
+  test_error_conflictingStaticAndInstance_inInterface_method_setter() async {
+    addTestFile(r'''
+class A {
+  set foo(_) {}
+}
+mixin M implements A {
+  static void foo() {}
+}
+''');
+    await resolveTestFile();
+    assertTestErrors([CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
+  }
+
+  test_error_conflictingStaticAndInstance_inInterface_setter_method() async {
+    addTestFile(r'''
+class A {
+  void foo() {}
+}
+mixin M implements A {
+  static set foo(_) {}
+}
+''');
+    await resolveTestFile();
+    assertTestErrors([CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
+  }
+
+  test_error_conflictingStaticAndInstance_inInterface_setter_setter() async {
+    addTestFile(r'''
+class A {
+  set foo(_) {}
+}
+mixin M implements A {
+  static set foo(_) {}
+}
+''');
+    await resolveTestFile();
+    assertTestErrors([CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
   }
 
   test_error_conflictingTypeVariableAndClass() async {
@@ -257,6 +662,17 @@
     assertTestErrors([CompileTimeErrorCode.DUPLICATE_DEFINITION]);
   }
 
+  test_error_duplicateDefinition_getter_method() async {
+    addTestFile(r'''
+mixin M {
+  int get foo => 0;
+  void foo() {}
+}
+''');
+    await resolveTestFile();
+    assertTestErrors([CompileTimeErrorCode.DUPLICATE_DEFINITION]);
+  }
+
   test_error_duplicateDefinition_method() async {
     addTestFile(r'''
 mixin M {
@@ -268,6 +684,17 @@
     assertTestErrors([CompileTimeErrorCode.DUPLICATE_DEFINITION]);
   }
 
+  test_error_duplicateDefinition_method_getter() async {
+    addTestFile(r'''
+mixin M {
+  void foo() {}
+  int get foo => 0;
+}
+''');
+    await resolveTestFile();
+    assertTestErrors([CompileTimeErrorCode.DUPLICATE_DEFINITION]);
+  }
+
   test_error_duplicateDefinition_setter() async {
     addTestFile(r'''
 mixin M {
@@ -333,17 +760,6 @@
     expect(fpElement.field, same(findElement.field('f')));
   }
 
-  test_error_getterAndMethodWithSameName() async {
-    addTestFile(r'''
-mixin M {
-  void t() {}
-  int get t => 0;
-}
-''');
-    await resolveTestFile();
-    assertTestErrors([CompileTimeErrorCode.GETTER_AND_METHOD_WITH_SAME_NAME]);
-  }
-
   test_error_implementsClause_deferredClass() async {
     addTestFile(r'''
 import 'dart:math' deferred as math;
@@ -390,6 +806,7 @@
 
     assertTestErrors([
       CompileTimeErrorCode.IMPLEMENTS_NON_CLASS,
+      ParserErrorCode.EXPECTED_TYPE_NAME,
     ]);
 
     var element = findElement.mixin('M');
@@ -399,6 +816,16 @@
     assertTypeName(typeRef, null, 'void');
   }
 
+  test_error_implementsRepeated() async {
+    addTestFile(r'''
+class A {}
+mixin M implements A, A {}
+''');
+    await resolveTestFile();
+    CompileTimeErrorCode.IMPLEMENTS_REPEATED;
+    assertTestErrors([CompileTimeErrorCode.IMPLEMENTS_REPEATED]);
+  }
+
   test_error_memberWithClassName_getter() async {
     addTestFile(r'''
 mixin M {
@@ -439,15 +866,222 @@
     assertTestErrors([CompileTimeErrorCode.MEMBER_WITH_CLASS_NAME]);
   }
 
-  test_error_methodAndGetterWithSameName() async {
+  test_error_mixinApplicationConcreteSuperInvokedMemberType_method() async {
     addTestFile(r'''
-mixin M {
-  int get t => 0;
-  void t() {}
+class I {
+  void foo([int p]) {}
 }
+
+class A {
+  void foo(int p) {}
+}
+
+abstract class B extends A implements I {
+  void foo([int p]);
+}
+
+mixin M on I {
+  void bar() {
+    super.foo(42);
+  }
+}
+
+abstract class X extends B with M {}
 ''');
     await resolveTestFile();
-    assertTestErrors([CompileTimeErrorCode.METHOD_AND_GETTER_WITH_SAME_NAME]);
+    assertTestErrors([
+      CompileTimeErrorCode.MIXIN_APPLICATION_CONCRETE_SUPER_INVOKED_MEMBER_TYPE,
+    ]);
+  }
+
+  test_error_mixinApplicationNoConcreteSuperInvokedMember_getter() async {
+    addTestFile(r'''
+abstract class A {
+  int get foo;
+}
+
+mixin M on A {
+  void bar() {
+    super.foo;
+  }
+}
+
+abstract class X extends A with M {}
+''');
+    await resolveTestFile();
+    assertTestErrors([
+      CompileTimeErrorCode.MIXIN_APPLICATION_NO_CONCRETE_SUPER_INVOKED_MEMBER,
+    ]);
+  }
+
+  test_error_mixinApplicationNoConcreteSuperInvokedMember_method() async {
+    addTestFile(r'''
+abstract class A {
+  void foo();
+}
+
+mixin M on A {
+  void bar() {
+    super.foo();
+  }
+}
+
+abstract class X extends A with M {}
+''');
+    await resolveTestFile();
+    assertTestErrors([
+      CompileTimeErrorCode.MIXIN_APPLICATION_NO_CONCRETE_SUPER_INVOKED_MEMBER,
+    ]);
+  }
+
+  test_error_mixinApplicationNoConcreteSuperInvokedMember_OK_inPreviousMixin() async {
+    addTestFile(r'''
+abstract class A {
+  void foo();
+}
+
+mixin M1 {
+  void foo() {}
+}
+
+mixin M2 on A {
+  void bar() {
+    super.foo();
+  }
+}
+
+class X extends A with M1, M2 {}
+''');
+    await resolveTestFile();
+    assertNoTestErrors();
+  }
+
+  test_error_mixinApplicationNoConcreteSuperInvokedMember_OK_notInvoked() async {
+    addTestFile(r'''
+abstract class A {
+  void foo();
+}
+
+mixin M on A {}
+
+abstract class X extends A with M {}
+''');
+    await resolveTestFile();
+    assertNoTestErrors();
+  }
+
+  test_error_mixinApplicationNoConcreteSuperInvokedMember_setter() async {
+    addTestFile(r'''
+abstract class A {
+  void set foo(_);
+}
+
+mixin M on A {
+  void bar() {
+    super.foo = 0;
+  }
+}
+
+abstract class X extends A with M {}
+''');
+    await resolveTestFile();
+    assertTestErrors([
+      CompileTimeErrorCode.MIXIN_APPLICATION_NO_CONCRETE_SUPER_INVOKED_MEMBER,
+    ]);
+  }
+
+  test_error_mixinApplicationNotImplementedInterface() async {
+    addTestFile(r'''
+class A {}
+
+mixin M on A {}
+
+class X = Object with M;
+''');
+    await resolveTestFile();
+    assertTestErrors([
+      CompileTimeErrorCode.MIXIN_APPLICATION_NOT_IMPLEMENTED_INTERFACE,
+    ]);
+  }
+
+  test_error_mixinApplicationNotImplementedInterface_generic() async {
+    addTestFile(r'''
+class A<T> {}
+
+mixin M on A<int> {}
+
+class X = A<double> with M;
+''');
+    await resolveTestFile();
+    assertTestErrors([
+      CompileTimeErrorCode.MIXIN_APPLICATION_NOT_IMPLEMENTED_INTERFACE,
+    ]);
+  }
+
+  test_error_mixinApplicationNotImplementedInterface_OK_0() async {
+    addTestFile(r'''
+mixin M {}
+
+class X = Object with M;
+''');
+    await resolveTestFile();
+    assertNoTestErrors();
+  }
+
+  test_error_mixinApplicationNotImplementedInterface_OK_1() async {
+    addTestFile(r'''
+class A {}
+
+mixin M on A {}
+
+class X = A with M;
+''');
+    await resolveTestFile();
+    assertNoTestErrors();
+  }
+
+  test_error_mixinApplicationNotImplementedInterface_OK_generic() async {
+    addTestFile(r'''
+class A<T> {}
+
+mixin M<T> on A<T> {}
+
+class B<T> implements A<T> {}
+
+class C<T> = B<T> with M<T>;
+''');
+    await resolveTestFile();
+    assertNoTestErrors();
+  }
+
+  test_error_mixinApplicationNotImplementedInterface_OK_previousMixin() async {
+    addTestFile(r'''
+class A {}
+
+mixin M1 implements A {}
+
+mixin M2 on A {}
+
+class X = Object with M1, M2;
+''');
+    await resolveTestFile();
+    assertNoTestErrors();
+  }
+
+  test_error_mixinApplicationNotImplementedInterface_oneOfTwo() async {
+    addTestFile(r'''
+class A {}
+class B {}
+class C {}
+
+mixin M on A, B {}
+
+class X = C with M;
+''');
+    await resolveTestFile();
+    assertTestErrors([
+      CompileTimeErrorCode.MIXIN_APPLICATION_NOT_IMPLEMENTED_INTERFACE,
+    ]);
   }
 
   test_error_mixinDeclaresConstructor() async {
@@ -481,6 +1115,43 @@
     assertType(aRef, 'int');
   }
 
+  test_error_mixinInstantiate_default() async {
+    addTestFile(r'''
+mixin M {}
+
+main() {
+  new M();
+}
+''');
+    await resolveTestFile();
+    assertTestErrors([CompileTimeErrorCode.MIXIN_INSTANTIATE]);
+
+    var creation = findNode.instanceCreation('M();');
+    var m = findElement.mixin('M');
+    assertInstanceCreation(creation, m, 'M');
+  }
+
+  test_error_mixinInstantiate_named() async {
+    addTestFile(r'''
+mixin M {
+  M.named() {}
+}
+
+main() {
+  new M.named();
+}
+''');
+    await resolveTestFile();
+    assertTestErrors([
+      CompileTimeErrorCode.MIXIN_DECLARES_CONSTRUCTOR,
+      CompileTimeErrorCode.MIXIN_INSTANTIATE,
+    ]);
+
+    var creation = findNode.instanceCreation('M.named();');
+    var m = findElement.mixin('M');
+    assertInstanceCreation(creation, m, 'M', constructorName: 'named');
+  }
+
   test_error_onClause_deferredClass() async {
     addTestFile(r'''
 import 'dart:math' deferred as math;
@@ -519,14 +1190,14 @@
     assertTypeName(typeRef, intElement, 'int');
   }
 
-  test_error_onClause_nonClass_dynamic() async {
+  test_error_onClause_nonInterface_dynamic() async {
     addTestFile(r'''
 mixin M on dynamic {}
 ''');
     await resolveTestFile();
 
     assertTestErrors([
-      CompileTimeErrorCode.MIXIN_SUPER_CLASS_CONSTRAINT_NON_CLASS,
+      CompileTimeErrorCode.MIXIN_SUPER_CLASS_CONSTRAINT_NON_INTERFACE,
     ]);
 
     var element = findElement.mixin('M');
@@ -536,7 +1207,7 @@
     assertTypeName(typeRef, dynamicElement, 'dynamic');
   }
 
-  test_error_onClause_nonClass_enum() async {
+  test_error_onClause_nonInterface_enum() async {
     addTestFile(r'''
 enum E {E1, E2, E3}
 mixin M on E {}
@@ -544,7 +1215,7 @@
     await resolveTestFile();
 
     assertTestErrors([
-      CompileTimeErrorCode.MIXIN_SUPER_CLASS_CONSTRAINT_NON_CLASS,
+      CompileTimeErrorCode.MIXIN_SUPER_CLASS_CONSTRAINT_NON_INTERFACE,
     ]);
 
     var element = findElement.mixin('M');
@@ -554,14 +1225,15 @@
     assertTypeName(typeRef, findElement.enum_('E'), 'E');
   }
 
-  test_error_onClause_nonClass_void() async {
+  test_error_onClause_nonInterface_void() async {
     addTestFile(r'''
 mixin M on void {}
 ''');
     await resolveTestFile();
 
     assertTestErrors([
-      CompileTimeErrorCode.MIXIN_SUPER_CLASS_CONSTRAINT_NON_CLASS,
+      CompileTimeErrorCode.MIXIN_SUPER_CLASS_CONSTRAINT_NON_INTERFACE,
+      ParserErrorCode.EXPECTED_TYPE_NAME,
     ]);
 
     var element = findElement.mixin('M');
@@ -571,6 +1243,48 @@
     assertTypeName(typeRef, null, 'void');
   }
 
+  test_error_onClause_OK_mixin() async {
+    addTestFile(r'''
+mixin A {}
+mixin B on A {} // ref
+''');
+    await resolveTestFile();
+    assertNoTestErrors();
+
+    var a = findElement.mixin('A');
+    var b = findElement.mixin('B');
+    assertElementTypes(b.superclassConstraints, [a.type]);
+  }
+
+  test_error_onRepeated() async {
+    addTestFile(r'''
+class A {}
+mixin M on A, A {}
+''');
+    await resolveTestFile();
+    CompileTimeErrorCode.IMPLEMENTS_REPEATED;
+    assertTestErrors([CompileTimeErrorCode.ON_REPEATED]);
+  }
+
+  test_error_undefinedSuperMethod() async {
+    addTestFile(r'''
+class A {}
+
+mixin M on A {
+  void bar() {
+    super.foo(42);
+  }
+}
+''');
+    await resolveTestFile();
+    assertTestErrors([StaticTypeWarningCode.UNDEFINED_SUPER_METHOD]);
+
+    var invocation = findNode.methodInvocation('foo(42)');
+    assertElementNull(invocation.methodName);
+    assertInvokeTypeDynamic(invocation);
+    assertTypeDynamic(invocation);
+  }
+
   test_field() async {
     addTestFile(r'''
 mixin M<T> {
@@ -633,6 +1347,166 @@
     assertTypeName(bRef, findElement.class_('B'), 'B');
   }
 
+  test_inconsistentMethodInheritance_implements_parameterType() async {
+    addTestFile(r'''
+abstract class A {
+  x(int i);
+}
+abstract class B {
+  x(String s);
+}
+mixin M implements A, B {}
+''');
+    await resolveTestFile();
+    assertTestErrors([
+      StaticTypeWarningCode.INCONSISTENT_METHOD_INHERITANCE,
+    ]);
+  }
+
+  test_inconsistentMethodInheritance_implements_requiredParameters() async {
+    addTestFile(r'''
+abstract class A {
+  x();
+}
+abstract class B {
+  x(int y);
+}
+mixin M implements A, B {}
+''');
+    await resolveTestFile();
+    assertTestErrors([
+      StaticTypeWarningCode.INCONSISTENT_METHOD_INHERITANCE,
+    ]);
+  }
+
+  test_inconsistentMethodInheritance_implements_returnType() async {
+    addTestFile(r'''
+abstract class A {
+  int x();
+}
+abstract class B {
+  String x();
+}
+mixin M implements A, B {}
+''');
+    await resolveTestFile();
+    assertTestErrors([
+      StaticTypeWarningCode.INCONSISTENT_METHOD_INHERITANCE,
+    ]);
+  }
+
+  test_inconsistentMethodInheritance_on_parameterType() async {
+    addTestFile(r'''
+abstract class A {
+  x(int i);
+}
+abstract class B {
+  x(String s);
+}
+mixin M on A, B {}
+''');
+    await resolveTestFile();
+    assertTestErrors([
+      StaticTypeWarningCode.INCONSISTENT_METHOD_INHERITANCE,
+    ]);
+  }
+
+  test_inconsistentMethodInheritance_on_requiredParameters() async {
+    addTestFile(r'''
+abstract class A {
+  x();
+}
+abstract class B {
+  x(int y);
+}
+mixin M on A, B {}
+''');
+    await resolveTestFile();
+    assertTestErrors([
+      StaticTypeWarningCode.INCONSISTENT_METHOD_INHERITANCE,
+    ]);
+  }
+
+  test_inconsistentMethodInheritance_on_returnType() async {
+    addTestFile(r'''
+abstract class A {
+  int x();
+}
+abstract class B {
+  String x();
+}
+mixin M on A, B {}
+''');
+    await resolveTestFile();
+    assertTestErrors([
+      StaticTypeWarningCode.INCONSISTENT_METHOD_INHERITANCE,
+    ]);
+  }
+
+  test_inconsistentMethodInheritanceGetterAndMethod_implements_getter_method() async {
+    addTestFile(r'''
+abstract class A {
+  int get x;
+}
+abstract class B {
+  int x();
+}
+mixin M implements A, B {}
+''');
+    await resolveTestFile();
+    assertTestErrors([
+      StaticWarningCode.INCONSISTENT_METHOD_INHERITANCE_GETTER_AND_METHOD,
+    ]);
+  }
+
+  test_inconsistentMethodInheritanceGetterAndMethod_implements_method_getter() async {
+    addTestFile(r'''
+abstract class A {
+  int x();
+}
+abstract class B {
+  int get x;
+}
+mixin M implements A, B {}
+''');
+    await resolveTestFile();
+    assertTestErrors([
+      StaticWarningCode.INCONSISTENT_METHOD_INHERITANCE_GETTER_AND_METHOD,
+    ]);
+  }
+
+  test_inconsistentMethodInheritanceGetterAndMethod_on_getter_method() async {
+    addTestFile(r'''
+abstract class A {
+  int get x;
+}
+abstract class B {
+  int x();
+}
+mixin M implements A, B {}
+''');
+    await resolveTestFile();
+    assertTestErrors([
+      StaticWarningCode.INCONSISTENT_METHOD_INHERITANCE_GETTER_AND_METHOD,
+    ]);
+  }
+
+  test_inconsistentMethodInheritanceGetterAndMethod_on_method_getter() async {
+    addTestFile(r'''
+abstract class A {
+  int x();
+}
+abstract class B {
+  int get x;
+}
+mixin M implements A, B {}
+''');
+    await resolveTestFile();
+    assertTestErrors([
+      StaticWarningCode.INCONSISTENT_METHOD_INHERITANCE_GETTER_AND_METHOD,
+    ]);
+  }
+
   test_metadata() async {
     addTestFile(r'''
 const a = 0;
@@ -677,8 +1551,113 @@
     var bRef = findNode.typeName('B {} // M');
     assertTypeName(bRef, findElement.class_('B'), 'B');
   }
+
+  test_recursiveInterfaceInheritance_implements() async {
+    addTestFile(r'''
+mixin A implements B {}
+mixin B implements A {}''');
+    await resolveTestFile();
+    assertTestErrors([
+      CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE,
+      CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE
+    ]);
+  }
+
+  test_recursiveInterfaceInheritance_on() async {
+    addTestFile(r'''
+mixin A on B {}
+mixin B on A {}''');
+    await resolveTestFile();
+    assertTestErrors([
+      CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE,
+      CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE
+    ]);
+  }
+
+  test_recursiveInterfaceInheritanceOn() async {
+    addTestFile(r'''
+mixin A on A {}
+''');
+    await resolveTestFile();
+    assertTestErrors([
+      CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_ON,
+    ]);
+  }
+
+  test_superInvocation_getter() async {
+    addTestFile(r'''
+class A {
+  int get foo => 0;
+}
+
+mixin M on A {
+  void bar() {
+    super.foo;
+  }
+}
+
+class X extends A with M {}
+''');
+    await resolveTestFile();
+    assertNoTestErrors();
+
+    var access = findNode.propertyAccess('super.foo;');
+    assertElement(access, findElement.getter('foo'));
+    assertType(access, 'int');
+  }
+
+  test_superInvocation_method() async {
+    addTestFile(r'''
+class A {
+  void foo(int x) {}
+}
+
+mixin M on A {
+  void bar() {
+    super.foo(42);
+  }
+}
+
+class X extends A with M {}
+''');
+    await resolveTestFile();
+    assertNoTestErrors();
+
+    var invocation = findNode.methodInvocation('foo(42)');
+    assertElement(invocation, findElement.method('foo'));
+    assertInvokeType(invocation, '(int) → void');
+    assertType(invocation, 'void');
+  }
+
+  test_superInvocation_setter() async {
+    addTestFile(r'''
+class A {
+  void set foo(_) {}
+}
+
+mixin M on A {
+  void bar() {
+    super.foo = 0;
+  }
+}
+
+class X extends A with M {}
+''');
+    await resolveTestFile();
+    assertNoTestErrors();
+
+    var access = findNode.propertyAccess('super.foo = 0');
+    assertElement(access, findElement.setter('foo'));
+    // Hm... Does it need any type?
+    assertTypeDynamic(access);
+  }
 }
 
 @reflectiveTest
 class MixinTaskResolutionTest extends TaskResolutionTest
-    with MixinResolutionMixin {}
+    with MixinResolutionMixin {
+  @failingTest
+  test_conflictingGenericInterfaces() {
+    return super.test_conflictingGenericInterfaces();
+  }
+}
diff --git a/pkg/analyzer/test/src/dart/resolution/resolution.dart b/pkg/analyzer/test/src/dart/resolution/resolution.dart
index eacf271..e01671b 100644
--- a/pkg/analyzer/test/src/dart/resolution/resolution.dart
+++ b/pkg/analyzer/test/src/dart/resolution/resolution.dart
@@ -47,6 +47,8 @@
 
   InterfaceType get objectType => typeProvider.objectType;
 
+  InterfaceType get stringType => typeProvider.stringType;
+
   TypeProvider get typeProvider =>
       result.unit.declaredElement.context.typeProvider;
 
@@ -77,13 +79,23 @@
     expect(type, expected);
   }
 
-  void assertElementTypes(List<DartType> types, List<DartType> expected) {
-    expect(types, hasLength(expected.length));
-    for (var i = 0; i < types.length; ++i) {
-      assertElementType(types[i], expected[i]);
+  void assertElementTypeDynamic(DartType type) {
+    expect(type, isDynamicType);
+  }
+
+  void assertElementTypes(List<DartType> types, List<DartType> expected,
+      {bool ordered = false}) {
+    if (ordered) {
+      expect(types, expected);
+    } else {
+      expect(types, unorderedEquals(expected));
     }
   }
 
+  void assertElementTypeString(DartType type, String expected) {
+    expect(type.toString(), expected);
+  }
+
   void assertEnclosingElement(Element element, Element expectedEnclosing) {
     expect(element.enclosingElement, expectedEnclosing);
   }
@@ -129,6 +141,50 @@
     assertType(ref, type);
   }
 
+  void assertInstanceCreation(InstanceCreationExpression creation,
+      ClassElement expectedClassElement, String expectedType,
+      {String constructorName, PrefixElement expectedPrefix}) {
+    String expectedClassName = expectedClassElement.name;
+
+    ConstructorElement expectedConstructorElement;
+    if (constructorName != null) {
+      expectedConstructorElement =
+          expectedClassElement.getNamedConstructor(constructorName);
+      if (expectedConstructorElement == null) {
+        fail("No constructor '$constructorName' in class"
+            " '$expectedClassName'.");
+      }
+    } else {
+      expectedConstructorElement = expectedClassElement.unnamedConstructor;
+      if (expectedConstructorElement == null) {
+        fail("No unnamed constructor in class '$expectedClassName'.");
+      }
+    }
+
+    var actualConstructorElement = getNodeElement(creation);
+    if (actualConstructorElement is ConstructorMember) {
+      assertMember(creation, expectedType, expectedConstructorElement);
+    } else {
+      assertElement(creation, actualConstructorElement);
+    }
+
+    assertType(creation, expectedType);
+
+    var typeName = creation.constructorName.type;
+    assertTypeName(typeName, expectedClassElement, expectedType,
+        expectedPrefix: expectedPrefix);
+  }
+
+  void assertInvokeType(InvocationExpression node, String expected) {
+    DartType actual = node.staticInvokeType;
+    expect(actual?.toString(), expected);
+  }
+
+  void assertInvokeTypeDynamic(InvocationExpression node) {
+    DartType actual = node.staticInvokeType;
+    expect(actual, isDynamicType);
+  }
+
   void assertMember(
       Expression node, String expectedDefiningType, Element expectedBase) {
     Member actual = getNodeElement(node);
@@ -137,7 +193,7 @@
   }
 
   void assertNoTestErrors() {
-    expect(result.errors, isEmpty);
+    assertTestErrors(const <ErrorCode>[]);
   }
 
   void assertTestErrors(List<ErrorCode> expected) {
@@ -176,6 +232,7 @@
     if (expectedPrefix == null) {
       var name = node.name as SimpleIdentifier;
       assertElement(name, expectedElement);
+      // TODO(scheglov) Should this be null?
       assertType(name, expectedType);
     } else {
       var name = node.name as PrefixedIdentifier;
@@ -207,10 +264,14 @@
       return node.staticElement;
     } else if (node is InstanceCreationExpression) {
       return node.staticElement;
+    } else if (node is MethodInvocation) {
+      return node.methodName.staticElement;
     } else if (node is PostfixExpression) {
       return node.staticElement;
     } else if (node is PrefixExpression) {
       return node.staticElement;
+    } else if (node is PropertyAccess) {
+      return node.propertyName.staticElement;
     } else {
       fail('Unsupported node: (${node.runtimeType}) $node');
     }
@@ -224,6 +285,8 @@
     findNode = new FindNode(result.content, result.unit);
     findElement = new FindElement(result.unit);
   }
+
+  void setAnalysisOptions({bool enableSuperMixins});
 }
 
 class TestAnalysisResult {
diff --git a/pkg/analyzer/test/src/dart/resolution/task_resolution.dart b/pkg/analyzer/test/src/dart/resolution/task_resolution.dart
index 4d8448e..4fcb693 100644
--- a/pkg/analyzer/test/src/dart/resolution/task_resolution.dart
+++ b/pkg/analyzer/test/src/dart/resolution/task_resolution.dart
@@ -23,7 +23,7 @@
   Future<TestAnalysisResult> resolveFile(String path) async {
     var file = resourceProvider.getFile(path);
     var content = file.readAsStringSync();
-    var source = file.createSource();
+    var source = file.createSource(Uri.parse('package:test/test.dart'));
 
     analysisContext.computeKindOf(source);
     List<Source> libraries = analysisContext.getLibrariesContaining(source);
@@ -35,6 +35,15 @@
     return new TestAnalysisResult(path, content, unit, errors);
   }
 
+  @override
+  void setAnalysisOptions({bool enableSuperMixins}) {
+    var analysisOptions = new AnalysisOptionsImpl();
+    if (enableSuperMixins != null) {
+      analysisOptions.enableSuperMixins = enableSuperMixins;
+    }
+    analysisContext.analysisOptions = analysisOptions;
+  }
+
   void setUp() {
     sdk = new MockSdk(resourceProvider: resourceProvider);
 
diff --git a/pkg/analyzer/test/src/dart/resolution/test_all.dart b/pkg/analyzer/test/src/dart/resolution/test_all.dart
index 6863f71..d93d42c 100644
--- a/pkg/analyzer/test/src/dart/resolution/test_all.dart
+++ b/pkg/analyzer/test/src/dart/resolution/test_all.dart
@@ -6,16 +6,26 @@
 
 import 'assignment_test.dart' as assignment_test;
 import 'class_test.dart' as class_test;
+import 'enum_test.dart' as enum_test;
 import 'for_in_test.dart' as for_in_test;
 import 'import_prefix_test.dart' as import_prefix_test;
+import 'instance_creation_test.dart' as instance_creation_test;
+import 'instance_member_inference_class_test.dart'
+    as instance_member_inference_class_test;
+import 'instance_member_inference_mixin_test.dart'
+    as instance_member_inference_mixin_test;
 import 'mixin_test.dart' as mixin_test;
 
 main() {
   defineReflectiveSuite(() {
     assignment_test.main();
     class_test.main();
+    enum_test.main();
     for_in_test.main();
     import_prefix_test.main();
+    instance_creation_test.main();
+    instance_member_inference_class_test.main();
+    instance_member_inference_mixin_test.main();
     mixin_test.main();
   }, name: 'resolution');
 }
diff --git a/pkg/analyzer/test/src/fasta/recovery/code_order_test.dart b/pkg/analyzer/test/src/fasta/recovery/code_order_test.dart
index bb6f791..17b4d06 100644
--- a/pkg/analyzer/test/src/fasta/recovery/code_order_test.dart
+++ b/pkg/analyzer/test/src/fasta/recovery/code_order_test.dart
@@ -104,18 +104,6 @@
 class A extends C with B {}
 ''');
   }
-
-  void test_withWithoutExtends() {
-    testRecovery('''
-class A with B, C {}
-''', [ParserErrorCode.WITH_WITHOUT_EXTENDS], '''
-class A extends Object with B, C {}
-''', adjustValidUnitBeforeComparison: (CompilationUnit unit) {
-      ClassDeclaration declaration = unit.declarations[0];
-      declaration.extendsClause = null;
-      return unit;
-    });
-  }
 }
 
 /**
diff --git a/pkg/analyzer/test/src/fasta/recovery/partial_code/index_statement_test.dart b/pkg/analyzer/test/src/fasta/recovery/partial_code/index_statement_test.dart
new file mode 100644
index 0000000..1391a1e
--- /dev/null
+++ b/pkg/analyzer/test/src/fasta/recovery/partial_code/index_statement_test.dart
@@ -0,0 +1,89 @@
+import 'package:analyzer/src/dart/error/syntactic_errors.dart';
+
+import 'partial_code_support.dart';
+
+main() {
+  new IndexStatementTest().buildAll();
+}
+
+class IndexStatementTest extends PartialCodeTest {
+  buildAll() {
+    buildTests(
+      'index_assignment',
+      [
+        new TestDescriptor(
+          'missing_index_no_space',
+          'intList[] = 0;',
+          [ParserErrorCode.MISSING_IDENTIFIER],
+          'intList[_s_] = 0;',
+        ),
+        new TestDescriptor(
+          'missing_index_with_space',
+          'intList[ ] = 0;',
+          [ParserErrorCode.MISSING_IDENTIFIER],
+          'intList[_s_] = 0;',
+        ),
+        new TestDescriptor(
+          'trailing_comma',
+          'intList[x,] = 0;',
+          [ParserErrorCode.EXPECTED_TOKEN],
+          'intList[x] = 0;',
+        ),
+        new TestDescriptor(
+          'trailing_comma_and_identifier',
+          'intList[x,y] = 0;',
+          [ParserErrorCode.EXPECTED_TOKEN],
+          'intList[x] = 0;',
+        ),
+        new TestDescriptor(
+          'trailing_identifier_no_comma',
+          'intList[x y] = 0;',
+          [ParserErrorCode.EXPECTED_TOKEN],
+          'intList[x] = 0;',
+        ),
+      ],
+      [], //PartialCodeTest.statementSuffixes,
+      head: 'f() { ',
+      tail: ' }',
+    );
+    buildTests(
+      'index_partial',
+      [
+        new TestDescriptor(
+          'open',
+          'intList[',
+          [
+            ParserErrorCode.MISSING_IDENTIFIER,
+            ScannerErrorCode.EXPECTED_TOKEN,
+            ParserErrorCode.EXPECTED_TOKEN,
+            ParserErrorCode.EXPECTED_TOKEN,
+          ],
+          'intList[_s_];',
+          failing: [
+            'eof',
+            'assert',
+            'block',
+            'labeled',
+            'localFunctionNonVoid',
+            'localFunctionVoid',
+            'return'
+          ],
+        ),
+        new TestDescriptor(
+          'identifier',
+          'intList[x',
+          [
+            ScannerErrorCode.EXPECTED_TOKEN,
+            ParserErrorCode.EXPECTED_TOKEN,
+            ParserErrorCode.EXPECTED_TOKEN,
+          ],
+          'intList[x];',
+          failing: ['eof'],
+        ),
+      ],
+      PartialCodeTest.statementSuffixes,
+      head: 'f() { ',
+      tail: ' }',
+    );
+  }
+}
diff --git a/pkg/analyzer/test/src/fasta/recovery/partial_code/test_all.dart b/pkg/analyzer/test/src/fasta/recovery/partial_code/test_all.dart
index e5abf74..316e1bb 100644
--- a/pkg/analyzer/test/src/fasta/recovery/partial_code/test_all.dart
+++ b/pkg/analyzer/test/src/fasta/recovery/partial_code/test_all.dart
@@ -19,6 +19,7 @@
 import 'for_statement_test.dart' as for_statement;
 import 'if_statement_test.dart' as if_statement;
 import 'import_directive_test.dart' as import_directive;
+import 'index_statement_test.dart' as index_statement;
 import 'instance_creation_test.dart' as instance_creation;
 import 'library_directive_test.dart' as library_directive;
 import 'local_variable_test.dart' as local_variable;
@@ -50,6 +51,7 @@
     forEach_statement.main();
     if_statement.main();
     import_directive.main();
+    index_statement.main();
     instance_creation.main();
     library_directive.main();
     local_variable.main();
diff --git a/pkg/analyzer/test/src/lint/pub_test.dart b/pkg/analyzer/test/src/lint/pub_test.dart
index 5a7f721..aa3412e 100644
--- a/pkg/analyzer/test/src/lint/pub_test.dart
+++ b/pkg/analyzer/test/src/lint/pub_test.dart
@@ -39,6 +39,8 @@
 dev_dependencies:
   markdown: '>=0.7.1+2 <0.8.0'
   unittest: '>=0.11.0 <0.12.0'
+dependency_overrides:
+  foo: 1.2.0
 """;
 
   Pubspec ps = new Pubspec.parse(src);
@@ -83,6 +85,10 @@
         {'markdown': '>=0.7.1+2 <0.8.0'}
       ]);
 
+      testDepListContains('dependency_overrides', ps.dependencyOverrides, [
+        {'foo': '1.2.0'}
+      ]);
+
       group('hosted', () {
         PSDependency dep =
             findDependency(ps.dependencies, name: 'transmogrify');
diff --git a/pkg/analyzer/test/src/summary/expr_builder_test.dart b/pkg/analyzer/test/src/summary/expr_builder_test.dart
index ef991be..c17d7f8 100644
--- a/pkg/analyzer/test/src/summary/expr_builder_test.dart
+++ b/pkg/analyzer/test/src/summary/expr_builder_test.dart
@@ -11,9 +11,8 @@
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
-import '../abstract_single_unit.dart';
-import 'resynthesize_ast_test.dart';
 import 'resynthesize_common.dart';
+import 'test_strategies.dart';
 
 main() {
   defineReflectiveSuite(() {
@@ -22,100 +21,13 @@
 }
 
 @reflectiveTest
-class ExprBuilderTest extends AbstractSingleUnitTest
-    with AstSerializeTestMixin {
-  @override
-  bool get allowMissingFiles => false;
+class ExprBuilderTest extends ResynthesizeTestStrategyTwoPhase
+    with ExprBuilderTestCases, ExprBuilderTestHelpers {}
 
-  Expression buildConstructorInitializer(String sourceText,
-      {String className: 'C',
-      String initializerName: 'x',
-      bool requireValidConst: false}) {
-    var resynthesizer = encodeSource(sourceText);
-    var library = resynthesizer.getLibraryElement(testSource.uri.toString());
-    var c = library.getType(className);
-    var constructor = c.unnamedConstructor as ConstructorElementImpl;
-    var serializedExecutable = constructor.serializedExecutable;
-    var x = serializedExecutable.constantInitializers
-        .singleWhere((i) => i.name == initializerName);
-    return buildExpression(resynthesizer, constructor, x.expression,
-        serializedExecutable.localFunctions,
-        requireValidConst: requireValidConst);
-  }
-
-  Expression buildExpression(
-      TestSummaryResynthesizer resynthesizer,
-      ElementImpl context,
-      UnlinkedExpr unlinkedExpr,
-      List<UnlinkedExecutable> localFunctions,
-      {bool requireValidConst: false}) {
-    var library = resynthesizer.getLibraryElement(testSource.uri.toString());
-    var unit = library.definingCompilationUnit as CompilationUnitElementImpl;
-    var unitResynthesizerContext =
-        unit.resynthesizerContext as SummaryResynthesizerContext;
-    var unitResynthesizer = unitResynthesizerContext.unitResynthesizer;
-    var exprBuilder = new ExprBuilder(unitResynthesizer, context, unlinkedExpr,
-        requireValidConst: requireValidConst, localFunctions: localFunctions);
-    return exprBuilder.build();
-  }
-
-  Expression buildTopLevelVariable(String sourceText,
-      {String variableName: 'x', bool requireValidConst: false}) {
-    var resynthesizer = encodeSource(sourceText);
-    var library = resynthesizer.getLibraryElement(testSource.uri.toString());
-    var unit = library.definingCompilationUnit as CompilationUnitElementImpl;
-    TopLevelVariableElementImpl x =
-        unit.topLevelVariables.singleWhere((e) => e.name == variableName);
-    return buildExpression(
-        resynthesizer,
-        x,
-        x.unlinkedVariableForTesting.initializer.bodyExpr,
-        x.unlinkedVariableForTesting.initializer.localFunctions,
-        requireValidConst: requireValidConst);
-  }
-
-  void checkCompoundAssignment(String exprText) {
-    checkSimpleExpression(exprText, extraDeclarations: 'var y;');
-  }
-
-  void checkConstructorInitializer(String sourceText, String expectedText,
-      {String className: 'C',
-      String initializerName: 'x',
-      bool requireValidConst: false}) {
-    Expression expr = buildConstructorInitializer(sourceText,
-        className: className,
-        initializerName: initializerName,
-        requireValidConst: requireValidConst);
-    expect(expr.toString(), expectedText);
-  }
-
-  void checkInvalidConst(String expressionText) {
-    checkTopLevelVariable('var x = $expressionText;', 'null',
-        requireValidConst: true);
-  }
-
-  Expression checkSimpleExpression(String expressionText,
-      {String expectedText,
-      String extraDeclarations: '',
-      bool requireValidConst: false}) {
-    return checkTopLevelVariable('var x = $expressionText;\n$extraDeclarations',
-        expectedText ?? expressionText,
-        requireValidConst: requireValidConst);
-  }
-
-  Expression checkTopLevelVariable(String sourceText, String expectedText,
-      {String variableName: 'x', bool requireValidConst: false}) {
-    Expression expr = buildTopLevelVariable(sourceText,
-        variableName: variableName, requireValidConst: requireValidConst);
-    expect(expr.toString(), expectedText);
-    return expr;
-  }
-
-  TestSummaryResynthesizer encodeSource(String text) {
-    var source = addTestSource(text);
-    return encodeLibrary(source);
-  }
-
+/// Mixin containing test cases exercising the [ExprBuilder].  Intended to be
+/// applied to a class implementing [ResynthesizeTestStrategy], along with the
+/// mixin [ExprBuilderTestHelpers].
+abstract class ExprBuilderTestCases implements ExprBuilderTestHelpers {
   void test_add() {
     checkSimpleExpression('0 + 1');
   }
@@ -565,3 +477,96 @@
     checkSimpleExpression('0 is! num', expectedText: '!(0 is num)');
   }
 }
+
+/// Mixin containing helper methods for testing the [ExprBuilder].  Intended to
+/// be applied to a class implementing [ResynthesizeTestStrategy].
+abstract class ExprBuilderTestHelpers implements ResynthesizeTestStrategy {
+  Expression buildConstructorInitializer(String sourceText,
+      {String className: 'C',
+      String initializerName: 'x',
+      bool requireValidConst: false}) {
+    var resynthesizer = encodeSource(sourceText);
+    var library = resynthesizer.getLibraryElement(testSource.uri.toString());
+    var c = library.getType(className);
+    var constructor = c.unnamedConstructor as ConstructorElementImpl;
+    var serializedExecutable = constructor.serializedExecutable;
+    var x = serializedExecutable.constantInitializers
+        .singleWhere((i) => i.name == initializerName);
+    return buildExpression(resynthesizer, constructor, x.expression,
+        serializedExecutable.localFunctions,
+        requireValidConst: requireValidConst);
+  }
+
+  Expression buildExpression(
+      TestSummaryResynthesizer resynthesizer,
+      ElementImpl context,
+      UnlinkedExpr unlinkedExpr,
+      List<UnlinkedExecutable> localFunctions,
+      {bool requireValidConst: false}) {
+    var library = resynthesizer.getLibraryElement(testSource.uri.toString());
+    var unit = library.definingCompilationUnit as CompilationUnitElementImpl;
+    var unitResynthesizerContext =
+        unit.resynthesizerContext as SummaryResynthesizerContext;
+    var unitResynthesizer = unitResynthesizerContext.unitResynthesizer;
+    var exprBuilder = new ExprBuilder(unitResynthesizer, context, unlinkedExpr,
+        requireValidConst: requireValidConst, localFunctions: localFunctions);
+    return exprBuilder.build();
+  }
+
+  Expression buildTopLevelVariable(String sourceText,
+      {String variableName: 'x', bool requireValidConst: false}) {
+    var resynthesizer = encodeSource(sourceText);
+    var library = resynthesizer.getLibraryElement(testSource.uri.toString());
+    var unit = library.definingCompilationUnit as CompilationUnitElementImpl;
+    TopLevelVariableElementImpl x =
+        unit.topLevelVariables.singleWhere((e) => e.name == variableName);
+    return buildExpression(
+        resynthesizer,
+        x,
+        x.unlinkedVariableForTesting.initializer.bodyExpr,
+        x.unlinkedVariableForTesting.initializer.localFunctions,
+        requireValidConst: requireValidConst);
+  }
+
+  void checkCompoundAssignment(String exprText) {
+    checkSimpleExpression(exprText, extraDeclarations: 'var y;');
+  }
+
+  void checkConstructorInitializer(String sourceText, String expectedText,
+      {String className: 'C',
+      String initializerName: 'x',
+      bool requireValidConst: false}) {
+    Expression expr = buildConstructorInitializer(sourceText,
+        className: className,
+        initializerName: initializerName,
+        requireValidConst: requireValidConst);
+    expect(expr.toString(), expectedText);
+  }
+
+  void checkInvalidConst(String expressionText) {
+    checkTopLevelVariable('var x = $expressionText;', 'null',
+        requireValidConst: true);
+  }
+
+  Expression checkSimpleExpression(String expressionText,
+      {String expectedText,
+      String extraDeclarations: '',
+      bool requireValidConst: false}) {
+    return checkTopLevelVariable('var x = $expressionText;\n$extraDeclarations',
+        expectedText ?? expressionText,
+        requireValidConst: requireValidConst);
+  }
+
+  Expression checkTopLevelVariable(String sourceText, String expectedText,
+      {String variableName: 'x', bool requireValidConst: false}) {
+    Expression expr = buildTopLevelVariable(sourceText,
+        variableName: variableName, requireValidConst: requireValidConst);
+    expect(expr.toString(), expectedText);
+    return expr;
+  }
+
+  TestSummaryResynthesizer encodeSource(String text) {
+    var source = addTestSource(text);
+    return encodeLibrary(source);
+  }
+}
diff --git a/pkg/analyzer/test/src/summary/linker_test.dart b/pkg/analyzer/test/src/summary/linker_test.dart
index 12b8e8c..9568a0b 100644
--- a/pkg/analyzer/test/src/summary/linker_test.dart
+++ b/pkg/analyzer/test/src/summary/linker_test.dart
@@ -893,36 +893,36 @@
     expect(x.variable.isStatic, true);
   }
 
-  void test_typeParameter_isTypeParameterInScope_direct() {
+  void test_typeParameter_computeDeBruijnIndex_direct() {
     createLinker('class C<T, U> {}');
     ClassElementForLink_Class c = testLibrary.getContainedName('C');
     TypeParameterElementImpl t = c.typeParameters[0];
     TypeParameterElementImpl u = c.typeParameters[1];
-    expect(c.isTypeParameterInScope(t), true);
-    expect(c.isTypeParameterInScope(u), true);
+    expect(c.computeDeBruijnIndex(t), 2);
+    expect(c.computeDeBruijnIndex(u), 1);
   }
 
-  void test_typeParameter_isTypeParameterInScope_indirect() {
+  void test_typeParameter_computeDeBruijnIndex_indirect() {
     createLinker('class C<T, U> { f<V, W>() {} }');
     ClassElementForLink_Class c = testLibrary.getContainedName('C');
     MethodElementForLink f = c.methods[0];
     TypeParameterElementImpl t = c.typeParameters[0];
     TypeParameterElementImpl u = c.typeParameters[1];
-    expect(f.isTypeParameterInScope(t), true);
-    expect(f.isTypeParameterInScope(u), true);
+    expect(f.computeDeBruijnIndex(t), 4);
+    expect(f.computeDeBruijnIndex(u), 3);
   }
 
-  void test_typeParameter_isTypeParameterInScope_reversed() {
+  void test_typeParameter_computeDeBruijnIndex_reversed() {
     createLinker('class C<T, U> { f<V, W>() {} }');
     ClassElementForLink_Class c = testLibrary.getContainedName('C');
     MethodElementForLink f = c.methods[0];
     TypeParameterElementImpl v = f.typeParameters[0];
     TypeParameterElementImpl w = f.typeParameters[1];
-    expect(c.isTypeParameterInScope(v), false);
-    expect(c.isTypeParameterInScope(w), false);
+    expect(c.computeDeBruijnIndex(v), isNull);
+    expect(c.computeDeBruijnIndex(w), isNull);
   }
 
-  void test_typeParameter_isTypeParameterInScope_unrelated() {
+  void test_typeParameter_computeDeBruijnIndex_unrelated() {
     createLinker('class C<T, U> {} class D<V, W> {}');
     ClassElementForLink_Class c = testLibrary.getContainedName('C');
     ClassElementForLink_Class d = testLibrary.getContainedName('D');
@@ -930,10 +930,10 @@
     TypeParameterElementImpl u = c.typeParameters[1];
     TypeParameterElementImpl v = d.typeParameters[0];
     TypeParameterElementImpl w = d.typeParameters[1];
-    expect(c.isTypeParameterInScope(v), false);
-    expect(c.isTypeParameterInScope(w), false);
-    expect(d.isTypeParameterInScope(t), false);
-    expect(d.isTypeParameterInScope(u), false);
+    expect(c.computeDeBruijnIndex(v), isNull);
+    expect(c.computeDeBruijnIndex(w), isNull);
+    expect(d.computeDeBruijnIndex(t), isNull);
+    expect(d.computeDeBruijnIndex(u), isNull);
   }
 
   void test_variable_initializer_presence() {
diff --git a/pkg/analyzer/test/src/summary/resynthesize_ast_test.dart b/pkg/analyzer/test/src/summary/resynthesize_ast_test.dart
index c103ef5..c15af1e 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_ast_test.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_ast_test.dart
@@ -2,30 +2,8 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-import 'dart:async';
-
-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;
-import 'package:analyzer/src/generated/sdk.dart';
-import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer/src/summary/format.dart';
-import 'package:analyzer/src/summary/idl.dart';
-import 'package:analyzer/src/summary/link.dart';
-import 'package:analyzer/src/summary/prelink.dart';
-import 'package:analyzer/src/summary/resynthesize.dart';
-import 'package:analyzer/src/summary/summarize_ast.dart';
-import 'package:analyzer/src/summary/summarize_elements.dart'
-    show PackageBundleAssembler;
-import 'package:analyzer/src/task/api/dart.dart' show PARSED_UNIT;
-import 'package:analyzer/src/task/api/general.dart';
-import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
-import '../context/abstract_context.dart';
 import 'element_text.dart';
 import 'resynthesize_common.dart';
 import 'test_strategies.dart';
@@ -44,129 +22,9 @@
   }
 }
 
-/// Mixin for serializing ASTs during testing.
-abstract class AstSerializeTestMixin
-    implements _AstSerializeTestMixinInterface {
-  final Set<Source> serializedSources = new Set<Source>();
-  PackageBundleAssembler bundleAssembler = new PackageBundleAssembler();
-  final Map<String, UnlinkedUnitBuilder> uriToUnit =
-      <String, UnlinkedUnitBuilder>{};
-
-  AnalysisContext get context;
-
-  TestSummaryResynthesizer encodeLibrary(Source source) {
-    _serializeLibrary(source);
-
-    PackageBundle bundle =
-        new PackageBundle.fromBuffer(bundleAssembler.assemble().toBuffer());
-
-    Map<String, UnlinkedUnit> unlinkedSummaries = <String, UnlinkedUnit>{};
-    for (int i = 0; i < bundle.unlinkedUnitUris.length; i++) {
-      String uri = bundle.unlinkedUnitUris[i];
-      unlinkedSummaries[uri] = bundle.unlinkedUnits[i];
-    }
-
-    LinkedLibrary getDependency(String absoluteUri) {
-      Map<String, LinkedLibrary> sdkLibraries =
-          SerializedMockSdk.instance.uriToLinkedLibrary;
-      LinkedLibrary linkedLibrary = sdkLibraries[absoluteUri];
-      if (linkedLibrary == null && !allowMissingFiles) {
-        fail('Linker unexpectedly requested LinkedLibrary for "$absoluteUri".'
-            '  Libraries available: ${sdkLibraries.keys}');
-      }
-      return linkedLibrary;
-    }
-
-    UnlinkedUnit getUnit(String absoluteUri) {
-      UnlinkedUnit unit = uriToUnit[absoluteUri] ??
-          SerializedMockSdk.instance.uriToUnlinkedUnit[absoluteUri];
-      if (unit == null && !allowMissingFiles) {
-        fail('Linker unexpectedly requested unit for "$absoluteUri".');
-      }
-      return unit;
-    }
-
-    Set<String> nonSdkLibraryUris = serializedSources
-        .where((Source source) =>
-            !source.isInSystemLibrary &&
-            context.computeKindOf(source) == SourceKind.LIBRARY)
-        .map((Source source) => source.uri.toString())
-        .toSet();
-
-    Map<String, LinkedLibrary> linkedSummaries = link(nonSdkLibraryUris,
-        getDependency, getUnit, context.declaredVariables.get);
-
-    return new TestSummaryResynthesizer(
-        context,
-        new Map<String, UnlinkedUnit>()
-          ..addAll(SerializedMockSdk.instance.uriToUnlinkedUnit)
-          ..addAll(unlinkedSummaries),
-        new Map<String, LinkedLibrary>()
-          ..addAll(SerializedMockSdk.instance.uriToLinkedLibrary)
-          ..addAll(linkedSummaries),
-        allowMissingFiles);
-  }
-
-  UnlinkedUnit _getUnlinkedUnit(Source source) {
-    if (source == null) {
-      return new UnlinkedUnitBuilder();
-    }
-
-    String uriStr = source.uri.toString();
-    {
-      UnlinkedUnit unlinkedUnitInSdk =
-          SerializedMockSdk.instance.uriToUnlinkedUnit[uriStr];
-      if (unlinkedUnitInSdk != null) {
-        return unlinkedUnitInSdk;
-      }
-    }
-    return uriToUnit.putIfAbsent(uriStr, () {
-      int modificationTime = context.computeResult(source, MODIFICATION_TIME);
-      if (modificationTime < 0) {
-        // Source does not exist.
-        if (!allowMissingFiles) {
-          fail('Unexpectedly tried to get unlinked summary for $source');
-        }
-        return null;
-      }
-      CompilationUnit unit = context.computeResult(source, PARSED_UNIT);
-      UnlinkedUnitBuilder unlinkedUnit = serializeAstUnlinked(unit);
-      bundleAssembler.addUnlinkedUnit(source, unlinkedUnit);
-      return unlinkedUnit;
-    });
-  }
-
-  void _serializeLibrary(Source librarySource) {
-    if (librarySource == null || librarySource.isInSystemLibrary) {
-      return;
-    }
-    if (!serializedSources.add(librarySource)) {
-      return;
-    }
-
-    UnlinkedUnit getPart(String absoluteUri) {
-      Source source = context.sourceFactory.forUri(absoluteUri);
-      return _getUnlinkedUnit(source);
-    }
-
-    UnlinkedPublicNamespace getImport(String relativeUri) {
-      return getPart(relativeUri)?.publicNamespace;
-    }
-
-    UnlinkedUnit definingUnit = _getUnlinkedUnit(librarySource);
-    if (definingUnit != null) {
-      LinkedLibraryBuilder linkedLibrary = prelink(librarySource.uri.toString(),
-          definingUnit, getPart, getImport, context.declaredVariables.get);
-      linkedLibrary.dependencies.skip(1).forEach((LinkedDependency d) {
-        Source source = context.sourceFactory.forUri(d.uri);
-        _serializeLibrary(source);
-      });
-    }
-  }
-}
-
 @reflectiveTest
-class ResynthesizeAstStrongTest extends _ResynthesizeAstTest {
+class ResynthesizeAstStrongTest extends ResynthesizeTestStrategyTwoPhase
+    with ResynthesizeTestCases, ResynthesizeTestHelpers {
   @failingTest // See dartbug.com/32290
   test_const_constructor_inferred_args() =>
       super.test_const_constructor_inferred_args();
@@ -201,168 +59,3 @@
     await super.test_syntheticFunctionType_withArguments();
   }
 }
-
-/**
- * Abstract mixin for serializing ASTs and resynthesizing elements from it.
- */
-abstract class _AstResynthesizeTestMixin
-    implements _AstSerializeTestMixinInterface {
-  AnalysisContext get context;
-
-  TestSummaryResynthesizer encodeLibrary(Source source);
-
-  LibraryElementImpl _encodeDecodeLibraryElement(Source source) {
-    SummaryResynthesizer resynthesizer = encodeLibrary(source);
-    return resynthesizer.getLibraryElement(source.uri.toString());
-  }
-}
-
-/**
- * Interface that [_AstSerializeTestMixin] requires of classes it's mixed
- * into.  We can't place the getter below into [_AstSerializeTestMixin]
- * directly, because then it would be overriding a field at the site where the
- * mixin is instantiated.
- */
-abstract class _AstSerializeTestMixinInterface {
-  /**
-   * A test should return `true` to indicate that a missing file at the time of
-   * summary resynthesis shouldn't trigger an error.
-   */
-  bool get allowMissingFiles;
-}
-
-abstract class _ResynthesizeAstTest extends ResynthesizeTest
-    with _AstResynthesizeTestMixin, AstSerializeTestMixin {
-  bool get shouldCompareLibraryElements;
-
-  @override
-  Future<LibraryElementImpl> checkLibrary(String text,
-      {bool allowErrors: false, bool dumpSummaries: false}) async {
-    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');
-      }
-    }
-    if (shouldCompareLibraryElements) {
-      checkLibraryElements(original, resynthesized);
-    }
-    return resynthesized;
-  }
-
-  @override
-  DartSdk createDartSdk() => AbstractContextTest.SHARED_MOCK_SDK;
-
-  @override
-  AnalysisOptionsImpl createOptions() {
-    if (isStrongMode) {
-      return super.createOptions()
-        ..previewDart2 = true
-        ..isMixinSupportEnabled = true;
-    } else {
-      return super.createOptions()..previewDart2 = false;
-    }
-  }
-
-  test_getElement_constructor_named() async {
-    String text = 'class C { C.named(); }';
-    Source source = addLibrarySource('/test.dart', text);
-    ConstructorElement original = context
-        .computeLibraryElement(source)
-        .getType('C')
-        .getNamedConstructor('named');
-    expect(original, isNotNull);
-    ConstructorElement resynthesized = _validateGetElement(text, original);
-    compareConstructorElements(resynthesized, original, 'C.constructor named');
-  }
-
-  test_getElement_constructor_unnamed() async {
-    String text = 'class C { C(); }';
-    Source source = addLibrarySource('/test.dart', text);
-    ConstructorElement original =
-        context.computeLibraryElement(source).getType('C').unnamedConstructor;
-    expect(original, isNotNull);
-    ConstructorElement resynthesized = _validateGetElement(text, original);
-    compareConstructorElements(resynthesized, original, 'C.constructor');
-  }
-
-  test_getElement_field() async {
-    String text = 'class C { var f; }';
-    Source source = addLibrarySource('/test.dart', text);
-    FieldElement original =
-        context.computeLibraryElement(source).getType('C').getField('f');
-    expect(original, isNotNull);
-    FieldElement resynthesized = _validateGetElement(text, original);
-    compareFieldElements(resynthesized, original, 'C.field f');
-  }
-
-  test_getElement_getter() async {
-    String text = 'class C { get f => null; }';
-    Source source = addLibrarySource('/test.dart', text);
-    PropertyAccessorElement original =
-        context.computeLibraryElement(source).getType('C').getGetter('f');
-    expect(original, isNotNull);
-    PropertyAccessorElement resynthesized = _validateGetElement(text, original);
-    comparePropertyAccessorElements(resynthesized, original, 'C.getter f');
-  }
-
-  test_getElement_method() async {
-    String text = 'class C { f() {} }';
-    Source source = addLibrarySource('/test.dart', text);
-    MethodElement original =
-        context.computeLibraryElement(source).getType('C').getMethod('f');
-    expect(original, isNotNull);
-    MethodElement resynthesized = _validateGetElement(text, original);
-    compareMethodElements(resynthesized, original, 'C.method f');
-  }
-
-  test_getElement_operator() async {
-    String text = 'class C { operator+(x) => null; }';
-    Source source = addLibrarySource('/test.dart', text);
-    MethodElement original =
-        context.computeLibraryElement(source).getType('C').getMethod('+');
-    expect(original, isNotNull);
-    MethodElement resynthesized = _validateGetElement(text, original);
-    compareMethodElements(resynthesized, original, 'C.operator+');
-  }
-
-  test_getElement_setter() async {
-    String text = 'class C { void set f(value) {} }';
-    Source source = addLibrarySource('/test.dart', text);
-    PropertyAccessorElement original =
-        context.computeLibraryElement(source).getType('C').getSetter('f');
-    expect(original, isNotNull);
-    PropertyAccessorElement resynthesized = _validateGetElement(text, original);
-    comparePropertyAccessorElements(resynthesized, original, 'C.setter f');
-  }
-
-  test_getElement_unit() async {
-    String text = 'class C { f() {} }';
-    Source source = addLibrarySource('/test.dart', text);
-    CompilationUnitElement original =
-        context.computeLibraryElement(source).definingCompilationUnit;
-    expect(original, isNotNull);
-    CompilationUnitElement resynthesized = _validateGetElement(text, original);
-    compareCompilationUnitElements(resynthesized, original);
-  }
-
-  /**
-   * Encode the library containing [original] into a summary and then use
-   * [TestSummaryResynthesizer.getElement] to retrieve just the original
-   * element from the resynthesized summary.
-   */
-  Element _validateGetElement(String text, Element original) {
-    SummaryResynthesizer resynthesizer = encodeLibrary(original.library.source);
-    ElementLocationImpl location = original.location;
-    Element result = resynthesizer.getElement(location);
-    checkMinimalResynthesisWork(resynthesizer, original.library);
-    // Check that no other summaries needed to be resynthesized to resynthesize
-    // the library element.
-    expect(resynthesizer.resynthesisCount, 3);
-    expect(result.location, location);
-    return result;
-  }
-}
diff --git a/pkg/analyzer/test/src/summary/resynthesize_common.dart b/pkg/analyzer/test/src/summary/resynthesize_common.dart
index ccf3ed2..ab472d5 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_common.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_common.dart
@@ -34,6 +34,7 @@
 import '../abstract_single_unit.dart';
 import '../context/abstract_context.dart';
 import 'element_text.dart';
+import 'test_strategies.dart';
 
 /**
  * Abstract base class for resynthesizing and comparing elements.
@@ -44,40 +45,11 @@
   Set<Source> otherLibrarySources = new Set<Source>();
 
   /**
-   * Names of variables which have initializers that are not valid constants,
-   * so they are not resynthesized.
-   */
-  Set<String> variablesWithNotConstInitializers = new Set<String>();
-
-  /**
-   * Names that cannot be resolved, e.g. because of duplicate declaration.
-   */
-  Set<String> namesThatCannotBeResolved = new Set<String>();
-
-  /**
    * Tests may set this to `true` to indicate that a missing file at the time of
    * summary resynthesis shouldn't trigger an error.
    */
   bool allowMissingFiles = false;
 
-  /**
-   * Tests may set this to `false` to indicate that resynthesized elements
-   * should not be compare with elements created using AnalysisContext.
-   */
-  bool shouldCompareLibraryElements = true;
-
-  /**
-   * Return `true` if shared front-end is used.
-   */
-  bool get isSharedFrontEnd => false;
-
-  /**
-   * Return `true` if resynthesizing should be done in strong mode.
-   *
-   * Deprecated - remove this getter.
-   */
-  bool get isStrongMode => true;
-
   void addLibrary(String uri) {
     otherLibrarySources.add(context.sourceFactory.forUri(uri));
   }
@@ -108,6 +80,8653 @@
   }
 
   /**
+   * Verify that the [resynthesizer] didn't do any unnecessary work when
+   * resynthesizing [library].
+   */
+  void checkMinimalResynthesisWork(
+      TestSummaryResynthesizer resynthesizer, LibraryElement library) {
+    // Check that no other summaries needed to be resynthesized to resynthesize
+    // the library element.
+    expect(resynthesizer.resynthesisCount, 3);
+    // Check that the only linked summary consulted was that for [uri].
+    expect(resynthesizer.linkedSummariesRequested, hasLength(1));
+    expect(resynthesizer.linkedSummariesRequested.first,
+        library.source.uri.toString());
+    // Check that the only unlinked summaries consulted were those for the
+    // library in question.
+    Set<String> expectedCompilationUnitUris = library.units
+        .map((CompilationUnitElement unit) => unit.source.uri.toString())
+        .toSet();
+    for (String requestedUri in resynthesizer.unlinkedSummariesRequested) {
+      expect(expectedCompilationUnitUris, contains(requestedUri));
+    }
+  }
+
+  DartSdk createDartSdk() => AbstractContextTest.SHARED_MOCK_SDK;
+
+  /**
+   * Create the analysis options that should be used for this test.
+   */
+  AnalysisOptionsImpl createOptions() => new AnalysisOptionsImpl();
+
+  @override
+  void setUp() {
+    super.setUp();
+    prepareAnalysisContext(createOptions());
+  }
+}
+
+/// Mixin containing test cases exercising summary resynthesis.  Intended to be
+/// applied to a class implementing [ResynthesizeTestStrategy], along with the
+/// mixin [ResynthesizeTestHelpers].
+abstract class ResynthesizeTestCases implements ResynthesizeTestHelpers {
+  test_class_abstract() async {
+    var library = await checkLibrary('abstract class C {}');
+    checkElementText(library, r'''
+abstract class C {
+}
+''');
+  }
+
+  test_class_alias() async {
+    var library = await checkLibrary('''
+class C = D with E, F, G;
+class D {}
+class E {}
+class F {}
+class G {}
+''');
+    checkElementText(library, r'''
+class alias C extends D with E, F, G {
+  synthetic C() = D;
+}
+class D {
+}
+class E {
+}
+class F {
+}
+class G {
+}
+''');
+  }
+
+  test_class_alias_abstract() async {
+    var library = await checkLibrary('''
+abstract class C = D with E;
+class D {}
+class E {}
+''');
+    checkElementText(library, r'''
+abstract class alias C extends D with E {
+  synthetic C() = D;
+}
+class D {
+}
+class E {
+}
+''');
+  }
+
+  test_class_alias_documented() async {
+    var library = await checkLibrary('''
+/**
+ * Docs
+ */
+class C = D with E;
+
+class D {}
+class E {}
+''');
+    checkElementText(library, r'''
+/**
+ * Docs
+ */
+class alias C extends D with E {
+  synthetic C() = D;
+}
+class D {
+}
+class E {
+}
+''');
+  }
+
+  test_class_alias_documented_tripleSlash() async {
+    var library = await checkLibrary('''
+/// aaa
+/// b
+/// cc
+class C = D with E;
+
+class D {}
+class E {}
+''');
+    checkElementText(library, r'''
+/// aaa
+/// b
+/// cc
+class alias C extends D with E {
+  synthetic C() = D;
+}
+class D {
+}
+class E {
+}
+''');
+  }
+
+  test_class_alias_documented_withLeadingNonDocumentation() async {
+    var library = await checkLibrary('''
+// Extra comment so doc comment offset != 0
+/**
+ * Docs
+ */
+class C = D with E;
+
+class D {}
+class E {}''');
+    checkElementText(library, r'''
+/**
+ * Docs
+ */
+class alias C extends D with E {
+  synthetic C() = D;
+}
+class D {
+}
+class E {
+}
+''');
+  }
+
+  test_class_alias_generic() async {
+    var library = await checkLibrary('''
+class Z = A with B<int>, C<double>;
+class A {}
+class B<B1> {}
+class C<C1> {}
+''');
+    checkElementText(library, r'''
+class alias Z extends A with B<int>, C<double> {
+  synthetic Z() = A;
+}
+class A {
+}
+class B<B1> {
+}
+class C<C1> {
+}
+''');
+  }
+
+  test_class_alias_with_forwarding_constructors() async {
+    addLibrarySource('/a.dart', '''
+class Base {
+  Base._priv();
+  Base();
+  Base.noArgs();
+  Base.requiredArg(x);
+  Base.positionalArg([x]);
+  Base.namedArg({x});
+  factory Base.fact() => null;
+  factory Base.fact2() = Base.noArgs;
+}
+''');
+    var library = await checkLibrary('''
+import "a.dart";
+class M {}
+class MixinApp = Base with M;
+''');
+    checkElementText(library, r'''
+import 'a.dart';
+class M {
+}
+class alias MixinApp extends Base with M {
+  synthetic MixinApp() = Base;
+  synthetic MixinApp.noArgs() = Base.noArgs;
+  synthetic MixinApp.requiredArg(dynamic x) = Base.requiredArg;
+  synthetic MixinApp.fact() = Base.fact;
+  synthetic MixinApp.fact2() = Base.fact2;
+}
+''');
+  }
+
+  test_class_alias_with_forwarding_constructors_type_substitution() async {
+    var library = await checkLibrary('''
+class Base<T> {
+  Base.ctor(T t, List<T> l);
+}
+class M {}
+class MixinApp = Base with M;
+''');
+    checkElementText(library, r'''
+class Base<T> {
+  Base.ctor(T t, List<T> l);
+}
+class M {
+}
+class alias MixinApp extends Base<dynamic> with M {
+  synthetic MixinApp.ctor(dynamic t, List<dynamic> l) = Base<T>.ctor;
+}
+''');
+  }
+
+  test_class_alias_with_forwarding_constructors_type_substitution_complex() async {
+    var library = await checkLibrary('''
+class Base<T> {
+  Base.ctor(T t, List<T> l);
+}
+class M {}
+class MixinApp<U> = Base<List<U>> with M;
+''');
+    checkElementText(library, r'''
+class Base<T> {
+  Base.ctor(T t, List<T> l);
+}
+class M {
+}
+class alias MixinApp<U> extends Base<List<U>> with M {
+  synthetic MixinApp.ctor(List<U> t, List<List<U>> l) = Base<T>.ctor;
+}
+''');
+  }
+
+  test_class_alias_with_mixin_members() async {
+    var library = await checkLibrary('''
+class C = D with E;
+class D {}
+class E {
+  int get a => null;
+  void set b(int i) {}
+  void f() {}
+  int x;
+}''');
+    checkElementText(library, r'''
+class alias C extends D with E {
+  synthetic C() = D;
+}
+class D {
+}
+class E {
+  int x;
+  int get a {}
+  void set b(int i) {}
+  void f() {}
+}
+''');
+  }
+
+  test_class_constructor_const() async {
+    var library = await checkLibrary('class C { const C(); }');
+    checkElementText(library, r'''
+class C {
+  const C();
+}
+''');
+  }
+
+  test_class_constructor_const_external() async {
+    var library = await checkLibrary('class C { external const C(); }');
+    checkElementText(library, r'''
+class C {
+  external const C();
+}
+''');
+  }
+
+  test_class_constructor_explicit_named() async {
+    var library = await checkLibrary('class C { C.foo(); }');
+    checkElementText(library, r'''
+class C {
+  C.foo();
+}
+''');
+  }
+
+  test_class_constructor_explicit_type_params() async {
+    var library = await checkLibrary('class C<T, U> { C(); }');
+    checkElementText(library, r'''
+class C<T, U> {
+  C();
+}
+''');
+  }
+
+  test_class_constructor_explicit_unnamed() async {
+    var library = await checkLibrary('class C { C(); }');
+    checkElementText(library, r'''
+class C {
+  C();
+}
+''');
+  }
+
+  test_class_constructor_external() async {
+    var library = await checkLibrary('class C { external C(); }');
+    checkElementText(library, r'''
+class C {
+  external C();
+}
+''');
+  }
+
+  test_class_constructor_factory() async {
+    var library = await checkLibrary('class C { factory C() => null; }');
+    checkElementText(library, r'''
+class C {
+  factory C();
+}
+''');
+  }
+
+  test_class_constructor_field_formal_dynamic_dynamic() async {
+    var library =
+        await checkLibrary('class C { dynamic x; C(dynamic this.x); }');
+    checkElementText(library, r'''
+class C {
+  dynamic x;
+  C(dynamic this.x);
+}
+''');
+  }
+
+  test_class_constructor_field_formal_dynamic_typed() async {
+    var library = await checkLibrary('class C { dynamic x; C(int this.x); }');
+    checkElementText(library, r'''
+class C {
+  dynamic x;
+  C(int this.x);
+}
+''');
+  }
+
+  test_class_constructor_field_formal_dynamic_untyped() async {
+    var library = await checkLibrary('class C { dynamic x; C(this.x); }');
+    checkElementText(library, r'''
+class C {
+  dynamic x;
+  C(dynamic this.x);
+}
+''');
+  }
+
+  test_class_constructor_field_formal_multiple_matching_fields() async {
+    // This is a compile-time error but it should still analyze consistently.
+    var library = await checkLibrary('class C { C(this.x); int x; String x; }',
+        allowErrors: true);
+    checkElementText(library, r'''
+class C {
+  int x;
+  String x;
+  C(int this.x);
+}
+''');
+  }
+
+  test_class_constructor_field_formal_no_matching_field() async {
+    // This is a compile-time error but it should still analyze consistently.
+    var library =
+        await checkLibrary('class C { C(this.x); }', allowErrors: true);
+    checkElementText(library, r'''
+class C {
+  C(dynamic this.x);
+}
+''');
+  }
+
+  test_class_constructor_field_formal_typed_dynamic() async {
+    var library = await checkLibrary('class C { num x; C(dynamic this.x); }',
+        allowErrors: true);
+    checkElementText(library, r'''
+class C {
+  num x;
+  C(dynamic this.x);
+}
+''');
+  }
+
+  test_class_constructor_field_formal_typed_typed() async {
+    var library = await checkLibrary('class C { num x; C(int this.x); }');
+    checkElementText(library, r'''
+class C {
+  num x;
+  C(int this.x);
+}
+''');
+  }
+
+  test_class_constructor_field_formal_typed_untyped() async {
+    var library = await checkLibrary('class C { num x; C(this.x); }');
+    checkElementText(library, r'''
+class C {
+  num x;
+  C(num this.x);
+}
+''');
+  }
+
+  test_class_constructor_field_formal_untyped_dynamic() async {
+    var library = await checkLibrary('class C { var x; C(dynamic this.x); }');
+    checkElementText(library, r'''
+class C {
+  dynamic x;
+  C(dynamic this.x);
+}
+''');
+  }
+
+  test_class_constructor_field_formal_untyped_typed() async {
+    var library = await checkLibrary('class C { var x; C(int this.x); }');
+    checkElementText(library, r'''
+class C {
+  dynamic x;
+  C(int this.x);
+}
+''');
+  }
+
+  test_class_constructor_field_formal_untyped_untyped() async {
+    var library = await checkLibrary('class C { var x; C(this.x); }');
+    checkElementText(library, r'''
+class C {
+  dynamic x;
+  C(dynamic this.x);
+}
+''');
+  }
+
+  test_class_constructor_fieldFormal_named_noDefault() async {
+    var library = await checkLibrary('class C { int x; C({this.x}); }');
+    checkElementText(library, r'''
+class C {
+  int x;
+  C({int this.x});
+}
+''');
+  }
+
+  test_class_constructor_fieldFormal_named_withDefault() async {
+    var library = await checkLibrary('class C { int x; C({this.x: 42}); }');
+    checkElementText(library, r'''
+class C {
+  int x;
+  C({int this.x: 42});
+}
+''');
+  }
+
+  test_class_constructor_fieldFormal_optional_noDefault() async {
+    var library = await checkLibrary('class C { int x; C([this.x]); }');
+    checkElementText(library, r'''
+class C {
+  int x;
+  C([int this.x]);
+}
+''');
+  }
+
+  test_class_constructor_fieldFormal_optional_withDefault() async {
+    var library = await checkLibrary('class C { int x; C([this.x = 42]); }');
+    checkElementText(library, r'''
+class C {
+  int x;
+  C([int this.x = 42]);
+}
+''');
+  }
+
+  test_class_constructor_implicit() async {
+    var library = await checkLibrary('class C {}');
+    checkElementText(library, r'''
+class C {
+}
+''');
+  }
+
+  test_class_constructor_implicit_type_params() async {
+    var library = await checkLibrary('class C<T, U> {}');
+    checkElementText(library, r'''
+class C<T, U> {
+}
+''');
+  }
+
+  test_class_constructor_params() async {
+    var library = await checkLibrary('class C { C(x, int y); }');
+    checkElementText(library, r'''
+class C {
+  C(dynamic x, int y);
+}
+''');
+  }
+
+  test_class_constructors() async {
+    var library = await checkLibrary('class C { C.foo(); C.bar(); }');
+    checkElementText(library, r'''
+class C {
+  C.foo();
+  C.bar();
+}
+''');
+  }
+
+  test_class_documented() async {
+    var library = await checkLibrary('''
+/**
+ * Docs
+ */
+class C {}''');
+    checkElementText(library, r'''
+/**
+ * Docs
+ */
+class C {
+}
+''');
+  }
+
+  test_class_documented_mix() async {
+    var library = await checkLibrary('''
+/**
+ * aaa
+ */
+/**
+ * bbb
+ */
+class A {}
+
+/**
+ * aaa
+ */
+/// bbb
+/// ccc
+class B {}
+
+/// aaa
+/// bbb
+/**
+ * ccc
+ */
+class C {}
+
+/// aaa
+/// bbb
+/**
+ * ccc
+ */
+/// ddd
+class D {}
+
+/**
+ * aaa
+ */
+// bbb
+class E {}
+''');
+    checkElementText(library, r'''
+/**
+ * bbb
+ */
+class A {
+}
+/// bbb
+/// ccc
+class B {
+}
+/**
+ * ccc
+ */
+class C {
+}
+/// ddd
+class D {
+}
+/**
+ * aaa
+ */
+class E {
+}
+''');
+  }
+
+  test_class_documented_tripleSlash() async {
+    var library = await checkLibrary('''
+/// aaa
+/// bbbb
+/// cc
+class C {}''');
+    checkElementText(library, r'''
+/// aaa
+/// bbbb
+/// cc
+class C {
+}
+''');
+  }
+
+  test_class_documented_with_references() async {
+    var library = await checkLibrary('''
+/**
+ * Docs referring to [D] and [E]
+ */
+class C {}
+
+class D {}
+class E {}''');
+    checkElementText(library, r'''
+/**
+ * Docs referring to [D] and [E]
+ */
+class C {
+}
+class D {
+}
+class E {
+}
+''');
+  }
+
+  test_class_documented_with_windows_line_endings() async {
+    var library = await checkLibrary('/**\r\n * Docs\r\n */\r\nclass C {}');
+    checkElementText(library, r'''
+/**
+ * Docs
+ */
+class C {
+}
+''');
+  }
+
+  test_class_documented_withLeadingNotDocumentation() async {
+    var library = await checkLibrary('''
+// Extra comment so doc comment offset != 0
+/**
+ * Docs
+ */
+class C {}''');
+    checkElementText(library, r'''
+/**
+ * Docs
+ */
+class C {
+}
+''');
+  }
+
+  test_class_documented_withMetadata() async {
+    var library = await checkLibrary('''
+/// Comment 1
+/// Comment 2
+@Annotation()
+class BeforeMeta {}
+
+/// Comment 1
+/// Comment 2
+@Annotation.named()
+class BeforeMetaNamed {}
+
+@Annotation()
+/// Comment 1
+/// Comment 2
+class AfterMeta {}
+
+/// Comment 1
+@Annotation()
+/// Comment 2
+class AroundMeta {}
+
+/// Doc comment.
+@Annotation()
+// Not doc comment.
+class DocBeforeMetaNotDocAfter {}
+
+class Annotation {
+  const Annotation();
+  const Annotation.named();
+}
+''');
+    checkElementText(
+        library,
+        r'''
+/// Comment 1
+/// Comment 2
+@Annotation()
+class BeforeMeta {
+}
+/// Comment 1
+/// Comment 2
+@Annotation.named()
+class BeforeMetaNamed {
+}
+/// Comment 1
+/// Comment 2
+@Annotation()
+class AfterMeta {
+}
+/// Comment 2
+@Annotation()
+class AroundMeta {
+}
+/// Doc comment.
+@Annotation()
+class DocBeforeMetaNotDocAfter {
+}
+class Annotation {
+  const Annotation();
+  const Annotation.named();
+}
+''',
+        withConstElements: false);
+  }
+
+  test_class_field_const() async {
+    var library = await checkLibrary('class C { static const int i = 0; }');
+    checkElementText(library, r'''
+class C {
+  static const int i = 0;
+}
+''');
+  }
+
+  test_class_field_implicit_type() async {
+    var library = await checkLibrary('class C { var x; }');
+    checkElementText(library, r'''
+class C {
+  dynamic x;
+}
+''');
+  }
+
+  test_class_field_static() async {
+    var library = await checkLibrary('class C { static int i; }');
+    checkElementText(library, r'''
+class C {
+  static int i;
+}
+''');
+  }
+
+  test_class_fields() async {
+    var library = await checkLibrary('class C { int i; int j; }');
+    checkElementText(library, r'''
+class C {
+  int i;
+  int j;
+}
+''');
+  }
+
+  test_class_getter_abstract() async {
+    var library = await checkLibrary('abstract class C { int get x; }');
+    checkElementText(library, r'''
+abstract class C {
+  int get x;
+}
+''');
+  }
+
+  test_class_getter_external() async {
+    var library = await checkLibrary('class C { external int get x; }');
+    checkElementText(library, r'''
+class C {
+  external int get x;
+}
+''');
+  }
+
+  test_class_getter_implicit_return_type() async {
+    var library = await checkLibrary('class C { get x => null; }');
+    checkElementText(library, r'''
+class C {
+  dynamic get x {}
+}
+''');
+  }
+
+  test_class_getter_static() async {
+    var library = await checkLibrary('class C { static int get x => null; }');
+    checkElementText(library, r'''
+class C {
+  static int get x {}
+}
+''');
+  }
+
+  test_class_getters() async {
+    var library =
+        await checkLibrary('class C { int get x => null; get y => null; }');
+    checkElementText(library, r'''
+class C {
+  int get x {}
+  dynamic get y {}
+}
+''');
+  }
+
+  test_class_implicitField_getterFirst() async {
+    var library = await checkLibrary('''
+class C {
+  int get x => 0;
+  void set x(int value) {} 
+}
+''');
+    checkElementText(library, r'''
+class C {
+  int get x {}
+  void set x(int value) {}
+}
+''');
+  }
+
+  test_class_implicitField_setterFirst() async {
+    var library = await checkLibrary('''
+class C {
+  void set x(int value) {}
+  int get x => 0;
+}
+''');
+    checkElementText(library, r'''
+class C {
+  void set x(int value) {}
+  int get x {}
+}
+''');
+  }
+
+  test_class_interfaces() async {
+    var library = await checkLibrary('''
+class C implements D, E {}
+class D {}
+class E {}
+''');
+    checkElementText(library, r'''
+class C implements D, E {
+}
+class D {
+}
+class E {
+}
+''');
+  }
+
+  test_class_interfaces_unresolved() async {
+    var library = await checkLibrary(
+        'class C implements X, Y, Z {} class X {} class Z {}',
+        allowErrors: true);
+    checkElementText(library, r'''
+class C implements X, Z {
+}
+class X {
+}
+class Z {
+}
+''');
+  }
+
+  test_class_method_abstract() async {
+    var library = await checkLibrary('abstract class C { f(); }');
+    checkElementText(library, r'''
+abstract class C {
+  dynamic f();
+}
+''');
+  }
+
+  test_class_method_external() async {
+    var library = await checkLibrary('class C { external f(); }');
+    checkElementText(library, r'''
+class C {
+  external dynamic f() {}
+}
+''');
+  }
+
+  test_class_method_params() async {
+    var library = await checkLibrary('class C { f(x, y) {} }');
+    checkElementText(library, r'''
+class C {
+  dynamic f(dynamic x, dynamic y) {}
+}
+''');
+  }
+
+  test_class_method_static() async {
+    var library = await checkLibrary('class C { static f() {} }');
+    checkElementText(library, r'''
+class C {
+  static dynamic f() {}
+}
+''');
+  }
+
+  test_class_methods() async {
+    var library = await checkLibrary('class C { f() {} g() {} }');
+    checkElementText(library, r'''
+class C {
+  dynamic f() {}
+  dynamic g() {}
+}
+''');
+  }
+
+  test_class_mixins() async {
+    var library = await checkLibrary('''
+class C extends D with E, F, G {}
+class D {}
+class E {}
+class F {}
+class G {}
+''');
+    checkElementText(library, r'''
+class C extends D with E, F, G {
+  synthetic C();
+}
+class D {
+}
+class E {
+}
+class F {
+}
+class G {
+}
+''');
+  }
+
+  test_class_mixins_generic() async {
+    var library = await checkLibrary('''
+class Z extends A with B<int>, C<double> {}
+class A {}
+class B<B1> {}
+class C<C1> {}
+''');
+    checkElementText(library, r'''
+class Z extends A with B<int>, C<double> {
+  synthetic Z();
+}
+class A {
+}
+class B<B1> {
+}
+class C<C1> {
+}
+''');
+  }
+
+  test_class_mixins_unresolved() async {
+    var library = await checkLibrary(
+        'class C extends Object with X, Y, Z {} class X {} class Z {}',
+        allowErrors: true);
+    checkElementText(library, r'''
+class C extends Object with X, Z {
+  synthetic C();
+}
+class X {
+}
+class Z {
+}
+''');
+  }
+
+  test_class_setter_abstract() async {
+    var library =
+        await checkLibrary('abstract class C { void set x(int value); }');
+    checkElementText(library, r'''
+abstract class C {
+  void set x(int value);
+}
+''');
+  }
+
+  test_class_setter_external() async {
+    var library =
+        await checkLibrary('class C { external void set x(int value); }');
+    checkElementText(library, r'''
+class C {
+  external void set x(int value);
+}
+''');
+  }
+
+  test_class_setter_implicit_param_type() async {
+    var library = await checkLibrary('class C { void set x(value) {} }');
+    checkElementText(library, r'''
+class C {
+  void set x(dynamic value) {}
+}
+''');
+  }
+
+  test_class_setter_implicit_return_type() async {
+    var library = await checkLibrary('class C { set x(int value) {} }');
+    checkElementText(library, r'''
+class C {
+  void set x(int value) {}
+}
+''');
+  }
+
+  test_class_setter_invalid_named_parameter() async {
+    var library = await checkLibrary('class C { void set x({a}) {} }');
+    checkElementText(library, r'''
+class C {
+  void set x({dynamic a}) {}
+}
+''');
+  }
+
+  test_class_setter_invalid_no_parameter() async {
+    var library = await checkLibrary('class C { void set x() {} }');
+    checkElementText(library, r'''
+class C {
+  void set x() {}
+}
+''');
+  }
+
+  test_class_setter_invalid_optional_parameter() async {
+    var library = await checkLibrary('class C { void set x([a]) {} }');
+    checkElementText(library, r'''
+class C {
+  void set x([dynamic a]) {}
+}
+''');
+  }
+
+  test_class_setter_invalid_too_many_parameters() async {
+    var library = await checkLibrary('class C { void set x(a, b) {} }');
+    checkElementText(library, r'''
+class C {
+  void set x(dynamic a, dynamic b) {}
+}
+''');
+  }
+
+  test_class_setter_static() async {
+    var library =
+        await checkLibrary('class C { static void set x(int value) {} }');
+    checkElementText(library, r'''
+class C {
+  static void set x(int value) {}
+}
+''');
+  }
+
+  test_class_setters() async {
+    var library = await checkLibrary('''
+class C {
+  void set x(int value) {}
+  set y(value) {}
+}
+''');
+    checkElementText(library, r'''
+class C {
+  void set x(int value) {}
+  void set y(dynamic value) {}
+}
+''');
+  }
+
+  test_class_supertype() async {
+    var library = await checkLibrary('''
+class C extends D {}
+class D {}
+''');
+    checkElementText(library, r'''
+class C extends D {
+}
+class D {
+}
+''');
+  }
+
+  test_class_supertype_typeArguments() async {
+    var library = await checkLibrary('''
+class C extends D<int, double> {}
+class D<T1, T2> {}
+''');
+    checkElementText(library, r'''
+class C extends D<int, double> {
+}
+class D<T1, T2> {
+}
+''');
+  }
+
+  test_class_supertype_unresolved() async {
+    var library = await checkLibrary('class C extends D {}', allowErrors: true);
+    checkElementText(library, r'''
+class C {
+}
+''');
+  }
+
+  test_class_type_parameters() async {
+    var library = await checkLibrary('class C<T, U> {}');
+    checkElementText(library, r'''
+class C<T, U> {
+}
+''');
+  }
+
+  test_class_type_parameters_bound() async {
+    var library = await checkLibrary('''
+class C<T extends Object, U extends D> {}
+class D {}
+''');
+    checkElementText(library, r'''
+class C<T, U extends D> {
+}
+class D {
+}
+''');
+  }
+
+  test_class_type_parameters_f_bound_complex() async {
+    var library = await checkLibrary('class C<T extends List<U>, U> {}');
+    checkElementText(library, r'''
+class C<T extends List<U>, U> {
+}
+''');
+  }
+
+  test_class_type_parameters_f_bound_simple() async {
+    var library = await checkLibrary('class C<T extends U, U> {}');
+    checkElementText(library, r'''
+class C<T extends U, U> {
+}
+''');
+  }
+
+  test_classes() async {
+    var library = await checkLibrary('class C {} class D {}');
+    checkElementText(library, r'''
+class C {
+}
+class D {
+}
+''');
+  }
+
+  test_closure_executable_with_return_type_from_closure() async {
+    var library = await checkLibrary('''
+f() {
+  print(() {});
+  print(() => () => 0);
+}
+''');
+    checkElementText(library, r'''
+dynamic f() {}
+''');
+  }
+
+  test_closure_generic() async {
+    var library = await checkLibrary(r'''
+final f = <U, V>(U x, V y) => y;
+''');
+    checkElementText(library, r'''
+final <U,V>(U, V) → V f;
+''');
+  }
+
+  test_closure_in_variable_declaration_in_part() async {
+    addSource('/a.dart', 'part of lib; final f = (int i) => i.toDouble();');
+    var library = await checkLibrary('''
+library lib;
+part "a.dart";
+''');
+    checkElementText(library, r'''
+library lib;
+part 'a.dart';
+--------------------
+unit: a.dart
+
+final (int) → double f;
+''');
+  }
+
+  test_codeRange_class() async {
+    var library = await checkLibrary('''
+class Raw {}
+
+/// Comment 1.
+/// Comment 2.
+class HasDocComment {}
+
+@Object()
+class HasAnnotation {}
+
+@Object()
+/// Comment 1.
+/// Comment 2.
+class AnnotationThenComment {}
+
+/// Comment 1.
+/// Comment 2.
+@Object()
+class CommentThenAnnotation {}
+
+/// Comment 1.
+@Object()
+/// Comment 2.
+class CommentAroundAnnotation {}
+''');
+    checkElementText(
+        library,
+        r'''
+class Raw/*codeOffset=0, codeLength=12*/ {
+}
+/// Comment 1.
+/// Comment 2.
+class HasDocComment/*codeOffset=14, codeLength=52*/ {
+}
+@Object()
+class HasAnnotation/*codeOffset=68, codeLength=32*/ {
+}
+/// Comment 1.
+/// Comment 2.
+@Object()
+class AnnotationThenComment/*codeOffset=102, codeLength=70*/ {
+}
+/// Comment 1.
+/// Comment 2.
+@Object()
+class CommentThenAnnotation/*codeOffset=174, codeLength=70*/ {
+}
+/// Comment 2.
+@Object()
+class CommentAroundAnnotation/*codeOffset=261, codeLength=57*/ {
+}
+''',
+        withCodeRanges: true,
+        withConstElements: false);
+  }
+
+  test_codeRange_class_namedMixin() async {
+    var library = await checkLibrary('''
+class A {}
+
+class B {}
+    
+class Raw = Object with A, B;
+
+/// Comment 1.
+/// Comment 2.
+class HasDocComment = Object with A, B;
+
+@Object()
+class HasAnnotation = Object with A, B;
+
+@Object()
+/// Comment 1.
+/// Comment 2.
+class AnnotationThenComment = Object with A, B;
+
+/// Comment 1.
+/// Comment 2.
+@Object()
+class CommentThenAnnotation = Object with A, B;
+
+/// Comment 1.
+@Object()
+/// Comment 2.
+class CommentAroundAnnotation = Object with A, B;
+''');
+    checkElementText(
+        library,
+        r'''
+class A/*codeOffset=0, codeLength=10*/ {
+}
+class B/*codeOffset=12, codeLength=10*/ {
+}
+class alias Raw/*codeOffset=28, codeLength=29*/ extends Object with A, B {
+  synthetic Raw() = Object;
+}
+/// Comment 1.
+/// Comment 2.
+class alias HasDocComment/*codeOffset=59, codeLength=69*/ extends Object with A, B {
+  synthetic HasDocComment() = Object;
+}
+@Object()
+class alias HasAnnotation/*codeOffset=130, codeLength=49*/ extends Object with A, B {
+  synthetic HasAnnotation() = Object;
+}
+/// Comment 1.
+/// Comment 2.
+@Object()
+class alias AnnotationThenComment/*codeOffset=181, codeLength=87*/ extends Object with A, B {
+  synthetic AnnotationThenComment() = Object;
+}
+/// Comment 1.
+/// Comment 2.
+@Object()
+class alias CommentThenAnnotation/*codeOffset=270, codeLength=87*/ extends Object with A, B {
+  synthetic CommentThenAnnotation() = Object;
+}
+/// Comment 2.
+@Object()
+class alias CommentAroundAnnotation/*codeOffset=374, codeLength=74*/ extends Object with A, B {
+  synthetic CommentAroundAnnotation() = Object;
+}
+''',
+        withCodeRanges: true,
+        withConstElements: false);
+  }
+
+  test_codeRange_constructor() async {
+    var library = await checkLibrary('''
+class C {
+  C();
+
+  C.raw() {}
+
+  /// Comment 1.
+  /// Comment 2.
+  C.hasDocComment() {}
+
+  @Object()
+  C.hasAnnotation() {}
+
+  @Object()
+  /// Comment 1.
+  /// Comment 2.
+  C.annotationThenComment() {}
+
+  /// Comment 1.
+  /// Comment 2.
+  @Object()
+  C.commentThenAnnotation() {}
+
+  /// Comment 1.
+  @Object()
+  /// Comment 2.
+  C.commentAroundAnnotation() {}
+}
+''');
+    checkElementText(
+        library,
+        r'''
+class C/*codeOffset=0, codeLength=362*/ {
+  C/*codeOffset=12, codeLength=4*/();
+  C.raw/*codeOffset=20, codeLength=10*/();
+  /// Comment 1.
+  /// Comment 2.
+  C.hasDocComment/*codeOffset=34, codeLength=54*/();
+  @Object()
+  C.hasAnnotation/*codeOffset=92, codeLength=32*/();
+  /// Comment 1.
+  /// Comment 2.
+  @Object()
+  C.annotationThenComment/*codeOffset=128, codeLength=74*/();
+  /// Comment 1.
+  /// Comment 2.
+  @Object()
+  C.commentThenAnnotation/*codeOffset=206, codeLength=74*/();
+  /// Comment 2.
+  @Object()
+  C.commentAroundAnnotation/*codeOffset=301, codeLength=59*/();
+}
+''',
+        withCodeRanges: true,
+        withConstElements: false);
+  }
+
+  test_codeRange_constructor_factory() async {
+    var library = await checkLibrary('''
+class C {
+  factory C() => null;
+
+  factory C.raw() => null;
+
+  /// Comment 1.
+  /// Comment 2.
+  factory C.hasDocComment() => null;
+
+  @Object()
+  factory C.hasAnnotation() => null;
+
+  @Object()
+  /// Comment 1.
+  /// Comment 2.
+  factory C.annotationThenComment() => null;
+
+  /// Comment 1.
+  /// Comment 2.
+  @Object()
+  factory C.commentThenAnnotation() => null;
+
+  /// Comment 1.
+  @Object()
+  /// Comment 2.
+  factory C.commentAroundAnnotation() => null;
+}
+''');
+    checkElementText(
+        library,
+        r'''
+class C/*codeOffset=0, codeLength=462*/ {
+  factory C/*codeOffset=12, codeLength=20*/();
+  factory C.raw/*codeOffset=36, codeLength=24*/();
+  /// Comment 1.
+  /// Comment 2.
+  factory C.hasDocComment/*codeOffset=64, codeLength=68*/();
+  @Object()
+  factory C.hasAnnotation/*codeOffset=136, codeLength=46*/();
+  /// Comment 1.
+  /// Comment 2.
+  @Object()
+  factory C.annotationThenComment/*codeOffset=186, codeLength=88*/();
+  /// Comment 1.
+  /// Comment 2.
+  @Object()
+  factory C.commentThenAnnotation/*codeOffset=278, codeLength=88*/();
+  /// Comment 2.
+  @Object()
+  factory C.commentAroundAnnotation/*codeOffset=387, codeLength=73*/();
+}
+''',
+        withCodeRanges: true,
+        withConstElements: false);
+  }
+
+  test_codeRange_field() async {
+    var library = await checkLibrary('''
+class C {
+  int withInit = 1;
+
+  int withoutInit;
+
+  int multiWithInit = 2, multiWithoutInit, multiWithInit2 = 3; 
+}
+''');
+    checkElementText(
+        library,
+        r'''
+class C/*codeOffset=0, codeLength=116*/ {
+  int withInit/*codeOffset=12, codeLength=16*/;
+  int withoutInit/*codeOffset=33, codeLength=15*/;
+  int multiWithInit/*codeOffset=53, codeLength=21*/;
+  int multiWithoutInit/*codeOffset=76, codeLength=16*/;
+  int multiWithInit2/*codeOffset=94, codeLength=18*/;
+}
+''',
+        withCodeRanges: true,
+        withConstElements: false);
+  }
+
+  test_codeRange_field_annotations() async {
+    var library = await checkLibrary('''
+class C {
+  /// Comment 1.
+  /// Comment 2.
+  int hasDocComment, hasDocComment2;
+
+  @Object()
+  int hasAnnotation, hasAnnotation2;
+
+  @Object()
+  /// Comment 1.
+  /// Comment 2.
+  int annotationThenComment, annotationThenComment2;
+
+  /// Comment 1.
+  /// Comment 2.
+  @Object()
+  int commentThenAnnotation, commentThenAnnotation2;
+
+  /// Comment 1.
+  @Object()
+  /// Comment 2.
+  int commentAroundAnnotation, commentAroundAnnotation2;
+}
+''');
+    checkElementText(
+        library,
+        r'''
+class C/*codeOffset=0, codeLength=436*/ {
+  /// Comment 1.
+  /// Comment 2.
+  int hasDocComment/*codeOffset=12, codeLength=51*/;
+  /// Comment 1.
+  /// Comment 2.
+  int hasDocComment2/*codeOffset=65, codeLength=14*/;
+  @Object()
+  int hasAnnotation/*codeOffset=84, codeLength=29*/;
+  @Object()
+  int hasAnnotation2/*codeOffset=115, codeLength=14*/;
+  /// Comment 1.
+  /// Comment 2.
+  @Object()
+  int annotationThenComment/*codeOffset=134, codeLength=71*/;
+  /// Comment 1.
+  /// Comment 2.
+  @Object()
+  int annotationThenComment2/*codeOffset=207, codeLength=22*/;
+  /// Comment 1.
+  /// Comment 2.
+  @Object()
+  int commentThenAnnotation/*codeOffset=234, codeLength=71*/;
+  /// Comment 1.
+  /// Comment 2.
+  @Object()
+  int commentThenAnnotation2/*codeOffset=307, codeLength=22*/;
+  /// Comment 2.
+  @Object()
+  int commentAroundAnnotation/*codeOffset=351, codeLength=56*/;
+  /// Comment 2.
+  @Object()
+  int commentAroundAnnotation2/*codeOffset=409, codeLength=24*/;
+}
+''',
+        withCodeRanges: true,
+        withConstElements: false);
+  }
+
+  test_codeRange_function() async {
+    var library = await checkLibrary('''
+void raw() {}
+
+/// Comment 1.
+/// Comment 2.
+void hasDocComment() {}
+
+@Object()
+void hasAnnotation() {}
+
+@Object()
+/// Comment 1.
+/// Comment 2.
+void annotationThenComment() {}
+
+/// Comment 1.
+/// Comment 2.
+@Object()
+void commentThenAnnotation() {}
+
+/// Comment 1.
+@Object()
+/// Comment 2.
+void commentAroundAnnotation() {}
+''');
+    checkElementText(
+        library,
+        r'''
+void raw/*codeOffset=0, codeLength=13*/() {}
+/// Comment 1.
+/// Comment 2.
+void hasDocComment/*codeOffset=15, codeLength=53*/() {}
+@Object()
+void hasAnnotation/*codeOffset=70, codeLength=33*/() {}
+/// Comment 1.
+/// Comment 2.
+@Object()
+void annotationThenComment/*codeOffset=105, codeLength=71*/() {}
+/// Comment 1.
+/// Comment 2.
+@Object()
+void commentThenAnnotation/*codeOffset=178, codeLength=71*/() {}
+/// Comment 2.
+@Object()
+void commentAroundAnnotation/*codeOffset=266, codeLength=58*/() {}
+''',
+        withCodeRanges: true,
+        withConstElements: false);
+  }
+
+  test_codeRange_method() async {
+    var library = await checkLibrary('''
+class C {
+  void raw() {}
+
+  /// Comment 1.
+  /// Comment 2.
+  void hasDocComment() {}
+
+  @Object()
+  void hasAnnotation() {}
+
+  @Object()
+  /// Comment 1.
+  /// Comment 2.
+  void annotationThenComment() {}
+
+  /// Comment 1.
+  /// Comment 2.
+  @Object()
+  void commentThenAnnotation() {}
+
+  /// Comment 1.
+  @Object()
+  /// Comment 2.
+  void commentAroundAnnotation() {}
+}
+''');
+    checkElementText(
+        library,
+        r'''
+class C/*codeOffset=0, codeLength=372*/ {
+  void raw/*codeOffset=12, codeLength=13*/() {}
+  /// Comment 1.
+  /// Comment 2.
+  void hasDocComment/*codeOffset=29, codeLength=57*/() {}
+  @Object()
+  void hasAnnotation/*codeOffset=90, codeLength=35*/() {}
+  /// Comment 1.
+  /// Comment 2.
+  @Object()
+  void annotationThenComment/*codeOffset=129, codeLength=77*/() {}
+  /// Comment 1.
+  /// Comment 2.
+  @Object()
+  void commentThenAnnotation/*codeOffset=210, codeLength=77*/() {}
+  /// Comment 2.
+  @Object()
+  void commentAroundAnnotation/*codeOffset=308, codeLength=62*/() {}
+}
+''',
+        withCodeRanges: true,
+        withConstElements: false);
+  }
+
+  test_codeRange_parameter() async {
+    var library = await checkLibrary('''
+main({int a = 1, int b, int c = 2}) {}
+''');
+    checkElementText(
+        library,
+        'dynamic main/*codeOffset=0, codeLength=38*/('
+        '{int a/*codeOffset=6, codeLength=9*/: 1}, '
+        '{int b/*codeOffset=17, codeLength=5*/}, '
+        '{int c/*codeOffset=24, codeLength=9*/: 2}) {}\n',
+        withCodeRanges: true,
+        withConstElements: false);
+  }
+
+  test_codeRange_parameter_annotations() async {
+    var library = await checkLibrary('''
+main(@Object() int a, int b, @Object() int c) {}
+''');
+    checkElementText(
+        library,
+        'dynamic main/*codeOffset=0, codeLength=48*/('
+        '@Object() int a/*codeOffset=5, codeLength=15*/, '
+        'int b/*codeOffset=22, codeLength=5*/, '
+        '@Object() int c/*codeOffset=29, codeLength=15*/) {}\n',
+        withCodeRanges: true,
+        withConstElements: false);
+  }
+
+  test_codeRange_topLevelVariable() async {
+    var library = await checkLibrary('''
+int withInit = 1 + 2 * 3;
+
+int withoutInit;
+
+int multiWithInit = 2, multiWithoutInit, multiWithInit2 = 3; 
+''');
+    checkElementText(
+        library,
+        r'''
+int withInit/*codeOffset=0, codeLength=24*/;
+int withoutInit/*codeOffset=27, codeLength=15*/;
+int multiWithInit/*codeOffset=45, codeLength=21*/;
+int multiWithoutInit/*codeOffset=68, codeLength=16*/;
+int multiWithInit2/*codeOffset=86, codeLength=18*/;
+''',
+        withCodeRanges: true,
+        withConstElements: false);
+  }
+
+  test_codeRange_topLevelVariable_annotations() async {
+    var library = await checkLibrary('''
+/// Comment 1.
+/// Comment 2.
+int hasDocComment, hasDocComment2;
+
+@Object()
+int hasAnnotation, hasAnnotation2;
+
+@Object()
+/// Comment 1.
+/// Comment 2.
+int annotationThenComment, annotationThenComment2;
+
+/// Comment 1.
+/// Comment 2.
+@Object()
+int commentThenAnnotation, commentThenAnnotation2;
+
+/// Comment 1.
+@Object()
+/// Comment 2.
+int commentAroundAnnotation, commentAroundAnnotation2;
+''');
+    checkElementText(
+        library,
+        r'''
+/// Comment 1.
+/// Comment 2.
+int hasDocComment/*codeOffset=0, codeLength=47*/;
+/// Comment 1.
+/// Comment 2.
+int hasDocComment2/*codeOffset=49, codeLength=14*/;
+@Object()
+int hasAnnotation/*codeOffset=66, codeLength=27*/;
+@Object()
+int hasAnnotation2/*codeOffset=95, codeLength=14*/;
+/// Comment 1.
+/// Comment 2.
+@Object()
+int annotationThenComment/*codeOffset=112, codeLength=65*/;
+/// Comment 1.
+/// Comment 2.
+@Object()
+int annotationThenComment2/*codeOffset=179, codeLength=22*/;
+/// Comment 1.
+/// Comment 2.
+@Object()
+int commentThenAnnotation/*codeOffset=204, codeLength=65*/;
+/// Comment 1.
+/// Comment 2.
+@Object()
+int commentThenAnnotation2/*codeOffset=271, codeLength=22*/;
+/// Comment 2.
+@Object()
+int commentAroundAnnotation/*codeOffset=311, codeLength=52*/;
+/// Comment 2.
+@Object()
+int commentAroundAnnotation2/*codeOffset=365, codeLength=24*/;
+''',
+        withCodeRanges: true,
+        withConstElements: false);
+  }
+
+  test_const_constructor_inferred_args() async {
+    var library = await checkLibrary('''
+class C<T> {
+  final T t;
+  const C(this.t);
+  const C.named(this.t);
+}
+const Object x = const C(0);
+const Object y = const C.named(0);
+''');
+    checkElementText(library, '''
+class C<T> {
+  final T t;
+  const C(T this.t);
+  const C.named(T this.t);
+}
+const Object x = const
+        C/*location: test.dart;C*/(0);
+const Object y = const
+        C/*location: test.dart;C*/.
+        named/*location: test.dart;C;named*/(0);
+''');
+    TopLevelVariableElementImpl x =
+        library.definingCompilationUnit.topLevelVariables[0];
+    InstanceCreationExpression xExpr = x.constantInitializer;
+    var xType = xExpr.constructorName.staticElement.returnType;
+    expect(xType.toString(), 'C<int>');
+    TopLevelVariableElementImpl y =
+        library.definingCompilationUnit.topLevelVariables[0];
+    InstanceCreationExpression yExpr = y.constantInitializer;
+    var yType = yExpr.constructorName.staticElement.returnType;
+    expect(yType.toString(), 'C<int>');
+  }
+
+  test_const_finalField_hasConstConstructor() async {
+    var library = await checkLibrary(r'''
+class C {
+  final int f = 42;
+  const C();
+}
+''');
+    checkElementText(library, r'''
+class C {
+  final int f = 42;
+  const C();
+}
+''');
+  }
+
+  test_const_invalid_field_const() async {
+    shouldCompareLibraryElements = false;
+    var library = await checkLibrary(r'''
+class C {
+  static const f = 1 + foo();
+}
+int foo() => 42;
+''', allowErrors: true);
+    checkElementText(library, r'''
+class C {
+  static const int f = 1 +
+        foo/*location: test.dart;foo*/();
+}
+int foo() {}
+''');
+  }
+
+  test_const_invalid_field_final() async {
+    variablesWithNotConstInitializers.add('f');
+    var library = await checkLibrary(r'''
+class C {
+  final f = 1 + foo();
+}
+int foo() => 42;
+''', allowErrors: true);
+    checkElementText(library, r'''
+class C {
+  final int f;
+}
+int foo() {}
+''');
+  }
+
+  test_const_invalid_intLiteral() async {
+    var library = await checkLibrary(r'''
+const int x = 0x;
+''', allowErrors: true);
+    checkElementText(library, r'''
+const int x = 0;
+''');
+  }
+
+  test_const_invalid_topLevel() async {
+    shouldCompareLibraryElements = false;
+    var library = await checkLibrary(r'''
+const v = 1 + foo();
+int foo() => 42;
+''', allowErrors: true);
+    checkElementText(library, r'''
+const int v = 1 +
+        foo/*location: test.dart;foo*/();
+int foo() {}
+''');
+  }
+
+  test_const_invalid_typeMismatch() async {
+    var library = await checkLibrary(r'''
+const int a = 0;
+const bool b = a + 5;
+''', allowErrors: true);
+    checkElementText(library, r'''
+const int a = 0;
+const bool b =
+        a/*location: test.dart;a?*/ + 5;
+''');
+  }
+
+  test_const_invokeConstructor_generic_named() async {
+    var library = await checkLibrary(r'''
+class C<K, V> {
+  const C.named(K k, V v);
+}
+const V = const C<int, String>.named(1, '222');
+''');
+    checkElementText(library, r'''
+class C<K, V> {
+  const C.named(K k, V v);
+}
+const C<int, String> V = const
+        C/*location: test.dart;C*/<
+        int/*location: dart:core;int*/,
+        String/*location: dart:core;String*/>.
+        named/*location: test.dart;C;named*/(1, '222');
+''');
+  }
+
+  test_const_invokeConstructor_generic_named_imported() async {
+    addLibrarySource('/a.dart', r'''
+class C<K, V> {
+  const C.named(K k, V v);
+}
+''');
+    var library = await checkLibrary(r'''
+import 'a.dart';
+const V = const C<int, String>.named(1, '222');
+''');
+    checkElementText(library, r'''
+import 'a.dart';
+const C<int, String> V = const
+        C/*location: a.dart;C*/<
+        int/*location: dart:core;int*/,
+        String/*location: dart:core;String*/>.
+        named/*location: a.dart;C;named*/(1, '222');
+''');
+  }
+
+  test_const_invokeConstructor_generic_named_imported_withPrefix() async {
+    addLibrarySource('/a.dart', r'''
+class C<K, V> {
+  const C.named(K k, V v);
+}
+''');
+    var library = await checkLibrary(r'''
+import 'a.dart' as p;
+const V = const p.C<int, String>.named(1, '222');
+''');
+    checkElementText(library, r'''
+import 'a.dart' as p;
+const C<int, String> V = const
+        C/*location: a.dart;C*/<
+        int/*location: dart:core;int*/,
+        String/*location: dart:core;String*/>.
+        named/*location: a.dart;C;named*/(1, '222');
+''');
+  }
+
+  test_const_invokeConstructor_generic_noTypeArguments() async {
+    var library = await checkLibrary(r'''
+class C<K, V> {
+  const C();
+}
+const V = const C();
+''');
+    checkElementText(library, r'''
+class C<K, V> {
+  const C();
+}
+const C<dynamic, dynamic> V = const
+        C/*location: test.dart;C*/();
+''');
+  }
+
+  test_const_invokeConstructor_generic_unnamed() async {
+    var library = await checkLibrary(r'''
+class C<K, V> {
+  const C();
+}
+const V = const C<int, String>();
+''');
+    checkElementText(library, r'''
+class C<K, V> {
+  const C();
+}
+const C<int, String> V = const
+        C/*location: test.dart;C*/<
+        int/*location: dart:core;int*/,
+        String/*location: dart:core;String*/>();
+''');
+  }
+
+  test_const_invokeConstructor_generic_unnamed_imported() async {
+    addLibrarySource('/a.dart', r'''
+class C<K, V> {
+  const C();
+}
+''');
+    var library = await checkLibrary(r'''
+import 'a.dart';
+const V = const C<int, String>();
+''');
+    checkElementText(library, r'''
+import 'a.dart';
+const C<int, String> V = const
+        C/*location: a.dart;C*/<
+        int/*location: dart:core;int*/,
+        String/*location: dart:core;String*/>();
+''');
+  }
+
+  test_const_invokeConstructor_generic_unnamed_imported_withPrefix() async {
+    addLibrarySource('/a.dart', r'''
+class C<K, V> {
+  const C();
+}
+''');
+    var library = await checkLibrary(r'''
+import 'a.dart' as p;
+const V = const p.C<int, String>();
+''');
+    checkElementText(library, r'''
+import 'a.dart' as p;
+const C<int, String> V = const
+        C/*location: a.dart;C*/<
+        int/*location: dart:core;int*/,
+        String/*location: dart:core;String*/>();
+''');
+  }
+
+  test_const_invokeConstructor_named() async {
+    var library = await checkLibrary(r'''
+class C {
+  const C.named(bool a, int b, int c, {String d, double e});
+}
+const V = const C.named(true, 1, 2, d: 'ccc', e: 3.4);
+''');
+    checkElementText(library, r'''
+class C {
+  const C.named(bool a, int b, int c, {String d}, {double e});
+}
+const C V = const
+        C/*location: test.dart;C*/.
+        named/*location: test.dart;C;named*/(true, 1, 2,
+        d/*location: null*/: 'ccc',
+        e/*location: null*/: 3.4);
+''');
+  }
+
+  test_const_invokeConstructor_named_imported() async {
+    addLibrarySource('/a.dart', r'''
+class C {
+  const C.named();
+}
+''');
+    var library = await checkLibrary(r'''
+import 'a.dart';
+const V = const C.named();
+''');
+    checkElementText(library, r'''
+import 'a.dart';
+const C V = const
+        C/*location: a.dart;C*/.
+        named/*location: a.dart;C;named*/();
+''');
+  }
+
+  test_const_invokeConstructor_named_imported_withPrefix() async {
+    addLibrarySource('/a.dart', r'''
+class C {
+  const C.named();
+}
+''');
+    var library = await checkLibrary(r'''
+import 'a.dart' as p;
+const V = const p.C.named();
+''');
+    checkElementText(library, r'''
+import 'a.dart' as p;
+const C V = const
+        C/*location: a.dart;C*/.
+        named/*location: a.dart;C;named*/();
+''');
+  }
+
+  test_const_invokeConstructor_named_unresolved() async {
+    shouldCompareLibraryElements = false;
+    var library = await checkLibrary(r'''
+class C {}
+const V = const C.named();
+''', allowErrors: true);
+    checkElementText(library, r'''
+class C {
+}
+const dynamic V = #invalidConst;
+''');
+  }
+
+  test_const_invokeConstructor_named_unresolved2() async {
+    shouldCompareLibraryElements = false;
+    var library = await checkLibrary(r'''
+const V = const C.named();
+''', allowErrors: true);
+    checkElementText(library, r'''
+const dynamic V = #invalidConst;
+''');
+  }
+
+  test_const_invokeConstructor_named_unresolved3() async {
+    shouldCompareLibraryElements = false;
+    addLibrarySource('/a.dart', r'''
+class C {
+}
+''');
+    var library = await checkLibrary(r'''
+import 'a.dart' as p;
+const V = const p.C.named();
+''', allowErrors: true);
+    checkElementText(library, r'''
+import 'a.dart' as p;
+const dynamic V = #invalidConst;
+''');
+  }
+
+  test_const_invokeConstructor_named_unresolved4() async {
+    shouldCompareLibraryElements = false;
+    addLibrarySource('/a.dart', '');
+    var library = await checkLibrary(r'''
+import 'a.dart' as p;
+const V = const p.C.named();
+''', allowErrors: true);
+    checkElementText(library, r'''
+import 'a.dart' as p;
+const dynamic V = #invalidConst;
+''');
+  }
+
+  test_const_invokeConstructor_named_unresolved5() async {
+    shouldCompareLibraryElements = false;
+    var library = await checkLibrary(r'''
+const V = const p.C.named();
+''', allowErrors: true);
+    checkElementText(library, r'''
+const dynamic V = #invalidConst;
+''');
+  }
+
+  test_const_invokeConstructor_named_unresolved6() async {
+    shouldCompareLibraryElements = false;
+    var library = await checkLibrary(r'''
+class C<T> {}
+const V = const C.named();
+''', allowErrors: true);
+    checkElementText(library, r'''
+class C<T> {
+}
+const dynamic V = #invalidConst;
+''');
+  }
+
+  test_const_invokeConstructor_unnamed() async {
+    var library = await checkLibrary(r'''
+class C {
+  const C();
+}
+const V = const C();
+''');
+    checkElementText(library, r'''
+class C {
+  const C();
+}
+const C V = const
+        C/*location: test.dart;C*/();
+''');
+  }
+
+  test_const_invokeConstructor_unnamed_imported() async {
+    addLibrarySource('/a.dart', r'''
+class C {
+  const C();
+}
+''');
+    var library = await checkLibrary(r'''
+import 'a.dart';
+const V = const C();
+''');
+    checkElementText(library, r'''
+import 'a.dart';
+const C V = const
+        C/*location: a.dart;C*/();
+''');
+  }
+
+  test_const_invokeConstructor_unnamed_imported_withPrefix() async {
+    addLibrarySource('/a.dart', r'''
+class C {
+  const C();
+}
+''');
+    var library = await checkLibrary(r'''
+import 'a.dart' as p;
+const V = const p.C();
+''');
+    checkElementText(library, r'''
+import 'a.dart' as p;
+const C V = const
+        C/*location: a.dart;C*/();
+''');
+  }
+
+  test_const_invokeConstructor_unnamed_unresolved() async {
+    shouldCompareLibraryElements = false;
+    var library = await checkLibrary(r'''
+const V = const C();
+''', allowErrors: true);
+    checkElementText(library, r'''
+const dynamic V = #invalidConst;
+''');
+  }
+
+  test_const_invokeConstructor_unnamed_unresolved2() async {
+    shouldCompareLibraryElements = false;
+    addLibrarySource('/a.dart', '');
+    var library = await checkLibrary(r'''
+import 'a.dart' as p;
+const V = const p.C();
+''', allowErrors: true);
+    checkElementText(library, r'''
+import 'a.dart' as p;
+const dynamic V = #invalidConst;
+''');
+  }
+
+  test_const_invokeConstructor_unnamed_unresolved3() async {
+    shouldCompareLibraryElements = false;
+    var library = await checkLibrary(r'''
+const V = const p.C();
+''', allowErrors: true);
+    checkElementText(library, r'''
+const dynamic V = #invalidConst;
+''');
+  }
+
+  test_const_length_ofClassConstField() async {
+    var library = await checkLibrary(r'''
+class C {
+  static const String F = '';
+}
+const int v = C.F.length;
+''');
+    checkElementText(library, r'''
+class C {
+  static const String F = '';
+}
+const int v =
+        C/*location: test.dart;C*/.
+        F/*location: test.dart;C;F?*/.
+        length/*location: dart:core;String;length?*/;
+''');
+  }
+
+  test_const_length_ofClassConstField_imported() async {
+    addLibrarySource('/a.dart', r'''
+class C {
+  static const String F = '';
+}
+''');
+    var library = await checkLibrary(r'''
+import 'a.dart';
+const int v = C.F.length;
+''');
+    checkElementText(library, r'''
+import 'a.dart';
+const int v =
+        C/*location: a.dart;C*/.
+        F/*location: a.dart;C;F?*/.
+        length/*location: dart:core;String;length?*/;
+''');
+  }
+
+  test_const_length_ofClassConstField_imported_withPrefix() async {
+    addLibrarySource('/a.dart', r'''
+class C {
+  static const String F = '';
+}
+''');
+    var library = await checkLibrary(r'''
+import 'a.dart' as p;
+const int v = p.C.F.length;
+''');
+    checkElementText(library, r'''
+import 'a.dart' as p;
+const int v =
+        p/*location: test.dart;p*/.
+        C/*location: a.dart;C*/.
+        F/*location: a.dart;C;F?*/.
+        length/*location: dart:core;String;length?*/;
+''');
+  }
+
+  test_const_length_ofStringLiteral() async {
+    var library = await checkLibrary(r'''
+const v = 'abc'.length;
+''');
+    checkElementText(library, r'''
+const int v = 'abc'.
+        length/*location: dart:core;String;length?*/;
+''');
+  }
+
+  test_const_length_ofTopLevelVariable() async {
+    var library = await checkLibrary(r'''
+const String S = 'abc';
+const v = S.length;
+''');
+    checkElementText(library, r'''
+const String S = 'abc';
+const int v =
+        S/*location: test.dart;S?*/.
+        length/*location: dart:core;String;length?*/;
+''');
+  }
+
+  test_const_length_ofTopLevelVariable_imported() async {
+    addLibrarySource('/a.dart', r'''
+const String S = 'abc';
+''');
+    var library = await checkLibrary(r'''
+import 'a.dart';
+const v = S.length;
+''');
+    checkElementText(library, r'''
+import 'a.dart';
+const int v =
+        S/*location: a.dart;S?*/.
+        length/*location: dart:core;String;length?*/;
+''');
+  }
+
+  test_const_length_ofTopLevelVariable_imported_withPrefix() async {
+    addLibrarySource('/a.dart', r'''
+const String S = 'abc';
+''');
+    var library = await checkLibrary(r'''
+import 'a.dart' as p;
+const v = p.S.length;
+''');
+    checkElementText(library, r'''
+import 'a.dart' as p;
+const int v =
+        p/*location: test.dart;p*/.
+        S/*location: a.dart;S?*/.
+        length/*location: dart:core;String;length?*/;
+''');
+  }
+
+  test_const_length_staticMethod() async {
+    var library = await checkLibrary(r'''
+class C {
+  static int length() => 42;
+}
+const v = C.length;
+''');
+    checkElementText(library, r'''
+class C {
+  static int length() {}
+}
+const () → int v =
+        C/*location: test.dart;C*/.
+        length/*location: test.dart;C;length*/;
+''');
+  }
+
+  test_const_list_inferredType() async {
+    // The summary needs to contain enough information so that when the constant
+    // is resynthesized, the constant value can get the type that was computed
+    // by type inference.
+    var library = await checkLibrary('''
+const Object x = const [1];
+''');
+    checkElementText(library, '''
+const Object x = const <
+        int/*location: dart:core;int*/>[1];
+''');
+  }
+
+  test_const_map_inferredType() async {
+    // The summary needs to contain enough information so that when the constant
+    // is resynthesized, the constant value can get the type that was computed
+    // by type inference.
+    var library = await checkLibrary('''
+const Object x = const {1: 1.0};
+''');
+    checkElementText(library, '''
+const Object x = const <
+        int/*location: dart:core;int*/,
+        double/*location: dart:core;double*/>{1: 1.0};
+''');
+  }
+
+  test_const_parameterDefaultValue_initializingFormal_functionTyped() async {
+    var library = await checkLibrary(r'''
+class C {
+  final x;
+  const C({this.x: foo});
+}
+int foo() => 42;
+''');
+    checkElementText(library, r'''
+class C {
+  final dynamic x;
+  const C({dynamic this.x:
+        foo/*location: test.dart;foo*/});
+}
+int foo() {}
+''');
+  }
+
+  test_const_parameterDefaultValue_initializingFormal_named() async {
+    var library = await checkLibrary(r'''
+class C {
+  final x;
+  const C({this.x: 1 + 2});
+}
+''');
+    checkElementText(library, r'''
+class C {
+  final dynamic x;
+  const C({dynamic this.x: 1 + 2});
+}
+''');
+  }
+
+  test_const_parameterDefaultValue_initializingFormal_positional() async {
+    var library = await checkLibrary(r'''
+class C {
+  final x;
+  const C([this.x = 1 + 2]);
+}
+''');
+    checkElementText(library, r'''
+class C {
+  final dynamic x;
+  const C([dynamic this.x = 1 + 2]);
+}
+''');
+  }
+
+  test_const_parameterDefaultValue_normal() async {
+    var library = await checkLibrary(r'''
+class C {
+  const C.positional([p = 1 + 2]);
+  const C.named({p: 1 + 2});
+  void methodPositional([p = 1 + 2]) {}
+  void methodPositionalWithoutDefault([p]) {}
+  void methodNamed({p: 1 + 2}) {}
+  void methodNamedWithoutDefault({p}) {}
+}
+''');
+    checkElementText(library, r'''
+class C {
+  const C.positional([dynamic p = 1 + 2]);
+  const C.named({dynamic p: 1 + 2});
+  void methodPositional([dynamic p = 1 + 2]) {}
+  void methodPositionalWithoutDefault([dynamic p]) {}
+  void methodNamed({dynamic p: 1 + 2}) {}
+  void methodNamedWithoutDefault({dynamic p}) {}
+}
+''');
+  }
+
+  test_const_reference_staticField() async {
+    var library = await checkLibrary(r'''
+class C {
+  static const int F = 42;
+}
+const V = C.F;
+''');
+    checkElementText(library, r'''
+class C {
+  static const int F = 42;
+}
+const int V =
+        C/*location: test.dart;C*/.
+        F/*location: test.dart;C;F?*/;
+''');
+  }
+
+  test_const_reference_staticField_imported() async {
+    addLibrarySource('/a.dart', r'''
+class C {
+  static const int F = 42;
+}
+''');
+    var library = await checkLibrary(r'''
+import 'a.dart';
+const V = C.F;
+''');
+    checkElementText(library, r'''
+import 'a.dart';
+const int V =
+        C/*location: a.dart;C*/.
+        F/*location: a.dart;C;F?*/;
+''');
+  }
+
+  test_const_reference_staticField_imported_withPrefix() async {
+    addLibrarySource('/a.dart', r'''
+class C {
+  static const int F = 42;
+}
+''');
+    var library = await checkLibrary(r'''
+import 'a.dart' as p;
+const V = p.C.F;
+''');
+    checkElementText(library, r'''
+import 'a.dart' as p;
+const int V =
+        p/*location: test.dart;p*/.
+        C/*location: a.dart;C*/.
+        F/*location: a.dart;C;F?*/;
+''');
+  }
+
+  test_const_reference_staticMethod() async {
+    var library = await checkLibrary(r'''
+class C {
+  static int m(int a, String b) => 42;
+}
+const V = C.m;
+''');
+    checkElementText(library, r'''
+class C {
+  static int m(int a, String b) {}
+}
+const (int, String) → int V =
+        C/*location: test.dart;C*/.
+        m/*location: test.dart;C;m*/;
+''');
+  }
+
+  test_const_reference_staticMethod_imported() async {
+    addLibrarySource('/a.dart', r'''
+class C {
+  static int m(int a, String b) => 42;
+}
+''');
+    var library = await checkLibrary(r'''
+import 'a.dart';
+const V = C.m;
+''');
+    checkElementText(library, r'''
+import 'a.dart';
+const (int, String) → int V =
+        C/*location: a.dart;C*/.
+        m/*location: a.dart;C;m*/;
+''');
+  }
+
+  test_const_reference_staticMethod_imported_withPrefix() async {
+    addLibrarySource('/a.dart', r'''
+class C {
+  static int m(int a, String b) => 42;
+}
+''');
+    var library = await checkLibrary(r'''
+import 'a.dart' as p;
+const V = p.C.m;
+''');
+    checkElementText(library, r'''
+import 'a.dart' as p;
+const (int, String) → int V =
+        p/*location: test.dart;p*/.
+        C/*location: a.dart;C*/.
+        m/*location: a.dart;C;m*/;
+''');
+  }
+
+  test_const_reference_topLevelFunction() async {
+    var library = await checkLibrary(r'''
+foo() {}
+const V = foo;
+''');
+    checkElementText(library, r'''
+const () → dynamic V =
+        foo/*location: test.dart;foo*/;
+dynamic foo() {}
+''');
+  }
+
+  test_const_reference_topLevelFunction_generic() async {
+    var library = await checkLibrary(r'''
+R foo<P, R>(P p) {}
+const V = foo;
+''');
+    checkElementText(library, r'''
+const <P,R>(P) → R V =
+        foo/*location: test.dart;foo*/;
+R foo<P, R>(P p) {}
+''');
+  }
+
+  test_const_reference_topLevelFunction_imported() async {
+    addLibrarySource('/a.dart', r'''
+foo() {}
+''');
+    var library = await checkLibrary(r'''
+import 'a.dart';
+const V = foo;
+''');
+    checkElementText(library, r'''
+import 'a.dart';
+const () → dynamic V =
+        foo/*location: a.dart;foo*/;
+''');
+  }
+
+  test_const_reference_topLevelFunction_imported_withPrefix() async {
+    addLibrarySource('/a.dart', r'''
+foo() {}
+''');
+    var library = await checkLibrary(r'''
+import 'a.dart' as p;
+const V = p.foo;
+''');
+    checkElementText(library, r'''
+import 'a.dart' as p;
+const () → dynamic V =
+        p/*location: test.dart;p*/.
+        foo/*location: a.dart;foo*/;
+''');
+  }
+
+  test_const_reference_topLevelVariable() async {
+    var library = await checkLibrary(r'''
+const A = 1;
+const B = A + 2;
+''');
+    checkElementText(library, r'''
+const int A = 1;
+const int B =
+        A/*location: test.dart;A?*/ + 2;
+''');
+  }
+
+  test_const_reference_topLevelVariable_imported() async {
+    addLibrarySource('/a.dart', r'''
+const A = 1;
+''');
+    var library = await checkLibrary(r'''
+import 'a.dart';
+const B = A + 2;
+''');
+    checkElementText(library, r'''
+import 'a.dart';
+const int B =
+        A/*location: a.dart;A?*/ + 2;
+''');
+  }
+
+  test_const_reference_topLevelVariable_imported_withPrefix() async {
+    addLibrarySource('/a.dart', r'''
+const A = 1;
+''');
+    var library = await checkLibrary(r'''
+import 'a.dart' as p;
+const B = p.A + 2;
+''');
+    checkElementText(library, r'''
+import 'a.dart' as p;
+const int B =
+        p/*location: test.dart;p*/.
+        A/*location: a.dart;A?*/ + 2;
+''');
+  }
+
+  test_const_reference_type() async {
+    var library = await checkLibrary(r'''
+class C {}
+class D<T> {}
+enum E {a, b, c}
+typedef F(int a, String b);
+const vDynamic = dynamic;
+const vNull = Null;
+const vObject = Object;
+const vClass = C;
+const vGenericClass = D;
+const vEnum = E;
+const vFunctionTypeAlias = F;
+''');
+    checkElementText(library, r'''
+typedef F = dynamic Function(int a, String b);
+enum E {
+  synthetic final int index;
+  synthetic static const List<E> values;
+  static const E a;
+  static const E b;
+  static const E c;
+  String toString() {}
+}
+class C {
+}
+class D<T> {
+}
+const Type vDynamic =
+        dynamic/*location: dynamic*/;
+const Type vNull =
+        Null/*location: dart:core;Null*/;
+const Type vObject =
+        Object/*location: dart:core;Object*/;
+const Type vClass =
+        C/*location: test.dart;C*/;
+const Type vGenericClass =
+        D/*location: test.dart;D*/;
+const Type vEnum =
+        E/*location: test.dart;E*/;
+const Type vFunctionTypeAlias =
+        F/*location: test.dart;F*/;
+''');
+  }
+
+  test_const_reference_type_functionType() async {
+    var library = await checkLibrary(r'''
+typedef F();
+class C {
+  final f = <F>[];
+}
+''');
+    checkElementText(library, r'''
+typedef F = dynamic Function();
+class C {
+  final List<() → dynamic> f;
+}
+''');
+  }
+
+  test_const_reference_type_imported() async {
+    addLibrarySource('/a.dart', r'''
+class C {}
+enum E {a, b, c}
+typedef F(int a, String b);
+''');
+    var library = await checkLibrary(r'''
+import 'a.dart';
+const vClass = C;
+const vEnum = E;
+const vFunctionTypeAlias = F;
+''');
+    checkElementText(library, r'''
+import 'a.dart';
+const Type vClass =
+        C/*location: a.dart;C*/;
+const Type vEnum =
+        E/*location: a.dart;E*/;
+const Type vFunctionTypeAlias =
+        F/*location: a.dart;F*/;
+''');
+  }
+
+  test_const_reference_type_imported_withPrefix() async {
+    addLibrarySource('/a.dart', r'''
+class C {}
+enum E {a, b, c}
+typedef F(int a, String b);
+''');
+    var library = await checkLibrary(r'''
+import 'a.dart' as p;
+const vClass = p.C;
+const vEnum = p.E;
+const vFunctionTypeAlias = p.F;
+''');
+    checkElementText(library, r'''
+import 'a.dart' as p;
+const Type vClass =
+        p/*location: test.dart;p*/.
+        C/*location: a.dart;C*/;
+const Type vEnum =
+        p/*location: test.dart;p*/.
+        E/*location: a.dart;E*/;
+const Type vFunctionTypeAlias =
+        p/*location: test.dart;p*/.
+        F/*location: a.dart;F*/;
+''');
+  }
+
+  test_const_reference_type_typeParameter() async {
+    var library = await checkLibrary(r'''
+class C<T> {
+  final f = <T>[];
+}
+''');
+    checkElementText(library, r'''
+class C<T> {
+  final List<T> f;
+}
+''');
+  }
+
+  test_const_reference_unresolved_prefix0() async {
+    shouldCompareLibraryElements = false;
+    var library = await checkLibrary(r'''
+const V = foo;
+''', allowErrors: true);
+    checkElementText(library, r'''
+const dynamic V = #invalidConst;
+''');
+  }
+
+  test_const_reference_unresolved_prefix1() async {
+    shouldCompareLibraryElements = false;
+    var library = await checkLibrary(r'''
+class C {}
+const V = C.foo;
+''', allowErrors: true);
+    checkElementText(library, r'''
+class C {
+}
+const dynamic V = #invalidConst;
+''');
+  }
+
+  test_const_reference_unresolved_prefix2() async {
+    shouldCompareLibraryElements = false;
+    addLibrarySource('/foo.dart', '''
+class C {}
+''');
+    var library = await checkLibrary(r'''
+import 'foo.dart' as p;
+const V = p.C.foo;
+''', allowErrors: true);
+    checkElementText(library, r'''
+import 'foo.dart' as p;
+const dynamic V = #invalidConst;
+''');
+  }
+
+  test_const_topLevel_binary() async {
+    var library = await checkLibrary(r'''
+const vEqual = 1 == 2;
+const vAnd = true && false;
+const vOr = false || true;
+const vBitXor = 1 ^ 2;
+const vBitAnd = 1 & 2;
+const vBitOr = 1 | 2;
+const vBitShiftLeft = 1 << 2;
+const vBitShiftRight = 1 >> 2;
+const vAdd = 1 + 2;
+const vSubtract = 1 - 2;
+const vMiltiply = 1 * 2;
+const vDivide = 1 / 2;
+const vFloorDivide = 1 ~/ 2;
+const vModulo = 1 % 2;
+const vGreater = 1 > 2;
+const vGreaterEqual = 1 >= 2;
+const vLess = 1 < 2;
+const vLessEqual = 1 <= 2;
+''');
+    checkElementText(library, r'''
+const bool vEqual = 1 == 2;
+const bool vAnd = true && false;
+const bool vOr = false || true;
+const int vBitXor = 1 ^ 2;
+const int vBitAnd = 1 & 2;
+const int vBitOr = 1 | 2;
+const int vBitShiftLeft = 1 << 2;
+const int vBitShiftRight = 1 >> 2;
+const int vAdd = 1 + 2;
+const int vSubtract = 1 - 2;
+const int vMiltiply = 1 * 2;
+const double vDivide = 1 / 2;
+const int vFloorDivide = 1 ~/ 2;
+const int vModulo = 1 % 2;
+const bool vGreater = 1 > 2;
+const bool vGreaterEqual = 1 >= 2;
+const bool vLess = 1 < 2;
+const bool vLessEqual = 1 <= 2;
+''');
+  }
+
+  test_const_topLevel_conditional() async {
+    var library = await checkLibrary(r'''
+const vConditional = (1 == 2) ? 11 : 22;
+''');
+    checkElementText(library, r'''
+const int vConditional = 1 == 2 ? 11 : 22;
+''');
+  }
+
+  test_const_topLevel_identical() async {
+    var library = await checkLibrary(r'''
+const vIdentical = (1 == 2) ? 11 : 22;
+''');
+    checkElementText(library, r'''
+const int vIdentical = 1 == 2 ? 11 : 22;
+''');
+  }
+
+  test_const_topLevel_ifNull() async {
+    var library = await checkLibrary(r'''
+const vIfNull = 1 ?? 2.0;
+''');
+    checkElementText(library, r'''
+const num vIfNull = 1 ?? 2.0;
+''');
+  }
+
+  test_const_topLevel_literal() async {
+    var library = await checkLibrary(r'''
+const vNull = null;
+const vBoolFalse = false;
+const vBoolTrue = true;
+const vInt = 1;
+const vIntLong1 = 0x7FFFFFFFFFFFFFFF;
+const vIntLong2 = 0xFFFFFFFFFFFFFFFF;
+const vDouble = 2.3;
+const vString = 'abc';
+const vStringConcat = 'aaa' 'bbb';
+const vStringInterpolation = 'aaa ${true} ${42} bbb';
+const vSymbol = #aaa.bbb.ccc;
+''');
+    checkElementText(library, r'''
+const dynamic vNull = null;
+const bool vBoolFalse = false;
+const bool vBoolTrue = true;
+const int vInt = 1;
+const int vIntLong1 = 9223372036854775807;
+const int vIntLong2 = -1;
+const double vDouble = 2.3;
+const String vString = 'abc';
+const String vStringConcat = 'aaabbb';
+const String vStringInterpolation = 'aaa ${true} ${42} bbb';
+const Symbol vSymbol = #aaa.bbb.ccc;
+''');
+  }
+
+  test_const_topLevel_parenthesis() async {
+    var library = await checkLibrary(r'''
+const int v1 = (1 + 2) * 3;
+const int v2 = -(1 + 2);
+const int v3 = ('aaa' + 'bbb').length;
+''');
+    checkElementText(library, r'''
+const int v1 = (1 + 2) * 3;
+const int v2 = -(1 + 2);
+const int v3 = ('aaa' + 'bbb').
+        length/*location: dart:core;String;length?*/;
+''');
+  }
+
+  test_const_topLevel_prefix() async {
+    var library = await checkLibrary(r'''
+const vNotEqual = 1 != 2;
+const vNot = !true;
+const vNegate = -1;
+const vComplement = ~1;
+''');
+    checkElementText(library, r'''
+const bool vNotEqual = 1 != 2;
+const bool vNot = !true;
+const int vNegate = -1;
+const int vComplement = ~1;
+''');
+  }
+
+  test_const_topLevel_super() async {
+    shouldCompareLibraryElements = false;
+    var library = await checkLibrary(r'''
+const vSuper = super;
+''');
+    checkElementText(library, r'''
+const dynamic vSuper = #invalidConst;
+''');
+  }
+
+  test_const_topLevel_this() async {
+    shouldCompareLibraryElements = false;
+    var library = await checkLibrary(r'''
+const vThis = this;
+''');
+    checkElementText(library, r'''
+const dynamic vThis = #invalidConst;
+''');
+  }
+
+  test_const_topLevel_throw() async {
+    shouldCompareLibraryElements = false;
+    var library = await checkLibrary(r'''
+const c = throw 42;
+''');
+    // This is a bug.
+    checkElementText(library, r'''
+const dynamic c;
+''');
+  }
+
+  test_const_topLevel_typedList() async {
+    var library = await checkLibrary(r'''
+const vNull = const <Null>[];
+const vDynamic = const <dynamic>[1, 2, 3];
+const vInterfaceNoTypeParameters = const <int>[1, 2, 3];
+const vInterfaceNoTypeArguments = const <List>[];
+const vInterfaceWithTypeArguments = const <List<String>>[];
+const vInterfaceWithTypeArguments2 = const <Map<int, List<String>>>[];
+''');
+    checkElementText(library, r'''
+const List<Null> vNull = const <
+        Null/*location: dart:core;Null*/>[];
+const List<dynamic> vDynamic = const <
+        dynamic/*location: dynamic*/>[1, 2, 3];
+const List<int> vInterfaceNoTypeParameters = const <
+        int/*location: dart:core;int*/>[1, 2, 3];
+const List<List<dynamic>> vInterfaceNoTypeArguments = const <
+        List/*location: dart:core;List*/>[];
+const List<List<String>> vInterfaceWithTypeArguments = const <
+        List/*location: dart:core;List*/<
+        String/*location: dart:core;String*/>>[];
+const List<Map<int, List<String>>> vInterfaceWithTypeArguments2 = const <
+        Map/*location: dart:core;Map*/<
+        int/*location: dart:core;int*/,
+        List/*location: dart:core;List*/<
+        String/*location: dart:core;String*/>>>[];
+''');
+  }
+
+  test_const_topLevel_typedList_imported() async {
+    addLibrarySource('/a.dart', 'class C {}');
+    var library = await checkLibrary(r'''
+import 'a.dart';
+const v = const <C>[];
+''');
+    checkElementText(library, r'''
+import 'a.dart';
+const List<C> v = const <
+        C/*location: a.dart;C*/>[];
+''');
+  }
+
+  test_const_topLevel_typedList_importedWithPrefix() async {
+    addLibrarySource('/a.dart', 'class C {}');
+    var library = await checkLibrary(r'''
+import 'a.dart' as p;
+const v = const <p.C>[];
+''');
+    checkElementText(library, r'''
+import 'a.dart' as p;
+const List<C> v = const <
+        C/*location: a.dart;C*/>[];
+''');
+  }
+
+  test_const_topLevel_typedList_typedefArgument() async {
+    shouldCompareLibraryElements = false;
+    var library = await checkLibrary(r'''
+typedef int F(String id);
+const v = const <F>[];
+''');
+    checkElementText(library, r'''
+typedef F = int Function(String id);
+const List<(String) → int> v = const <
+        null/*location: test.dart;F;-*/>[];
+''');
+  }
+
+  test_const_topLevel_typedMap() async {
+    var library = await checkLibrary(r'''
+const vDynamic1 = const <dynamic, int>{};
+const vDynamic2 = const <int, dynamic>{};
+const vInterface = const <int, String>{};
+const vInterfaceWithTypeArguments = const <int, List<String>>{};
+''');
+    checkElementText(library, r'''
+const Map<dynamic, int> vDynamic1 = const <
+        dynamic/*location: dynamic*/,
+        int/*location: dart:core;int*/>{};
+const Map<int, dynamic> vDynamic2 = const <
+        int/*location: dart:core;int*/,
+        dynamic/*location: dynamic*/>{};
+const Map<int, String> vInterface = const <
+        int/*location: dart:core;int*/,
+        String/*location: dart:core;String*/>{};
+const Map<int, List<String>> vInterfaceWithTypeArguments = const <
+        int/*location: dart:core;int*/,
+        List/*location: dart:core;List*/<
+        String/*location: dart:core;String*/>>{};
+''');
+  }
+
+  test_const_topLevel_untypedList() async {
+    var library = await checkLibrary(r'''
+const v = const [1, 2, 3];
+''');
+    checkElementText(library, r'''
+const List<int> v = const [1, 2, 3];
+''');
+  }
+
+  test_const_topLevel_untypedMap() async {
+    var library = await checkLibrary(r'''
+const v = const {0: 'aaa', 1: 'bbb', 2: 'ccc'};
+''');
+    checkElementText(library, r'''
+const Map<int, String> v = const {0: 'aaa', 1: 'bbb', 2: 'ccc'};
+''');
+  }
+
+  test_constExpr_pushReference_enum_field() async {
+    var library = await checkLibrary('''
+enum E {a, b, c}
+final vValue = E.a;
+final vValues = E.values;
+final vIndex = E.a.index;
+''');
+    checkElementText(library, r'''
+enum E {
+  synthetic final int index;
+  synthetic static const List<E> values;
+  static const E a;
+  static const E b;
+  static const E c;
+  String toString() {}
+}
+final E vValue;
+final List<E> vValues;
+final int vIndex;
+''');
+  }
+
+  test_constExpr_pushReference_enum_method() async {
+    var library = await checkLibrary('''
+enum E {a}
+final vToString = E.a.toString();
+''');
+    checkElementText(library, r'''
+enum E {
+  synthetic final int index;
+  synthetic static const List<E> values;
+  static const E a;
+  String toString() {}
+}
+final String vToString;
+''');
+  }
+
+  test_constExpr_pushReference_field_simpleIdentifier() async {
+    var library = await checkLibrary('''
+class C {
+  static const a = b;
+  static const b = null;
+}
+''');
+    checkElementText(library, r'''
+class C {
+  static const dynamic a =
+        C/*location: test.dart;C*/.
+        b/*location: test.dart;C;b?*/;
+  static const dynamic b = null;
+}
+''');
+  }
+
+  test_constExpr_pushReference_staticMethod_simpleIdentifier() async {
+    var library = await checkLibrary('''
+class C {
+  static const a = m;
+  static m() {}
+}
+''');
+    checkElementText(library, r'''
+class C {
+  static const () → dynamic a =
+        C/*location: test.dart;C*/.
+        m/*location: test.dart;C;m*/;
+  static dynamic m() {}
+}
+''');
+  }
+
+  test_constructor_documented() async {
+    var library = await checkLibrary('''
+class C {
+  /**
+   * Docs
+   */
+  C();
+}''');
+    checkElementText(library, r'''
+class C {
+  /**
+   * Docs
+   */
+  C();
+}
+''');
+  }
+
+  test_constructor_initializers_assertInvocation() async {
+    var library = await checkLibrary('''
+class C {
+  const C(int x) : assert(x >= 42);
+}
+''');
+    checkElementText(library, r'''
+class C {
+  const C(int x) : assert(
+        x/*location: test.dart;C;;x*/ >= 42);
+}
+''');
+  }
+
+  test_constructor_initializers_assertInvocation_message() async {
+    var library = await checkLibrary('''
+class C {
+  const C(int x) : assert(x >= 42, 'foo');
+}
+''');
+    checkElementText(library, r'''
+class C {
+  const C(int x) : assert(
+        x/*location: test.dart;C;;x*/ >= 42, 'foo');
+}
+''');
+  }
+
+  test_constructor_initializers_field() async {
+    var library = await checkLibrary('''
+class C {
+  final x;
+  const C() : x = 42;
+}
+''');
+    checkElementText(library, r'''
+class C {
+  final dynamic x;
+  const C() :
+        x/*location: test.dart;C;x*/ = 42;
+}
+''');
+  }
+
+  test_constructor_initializers_field_notConst() async {
+    shouldCompareLibraryElements = false;
+    var library = await checkLibrary('''
+class C {
+  final x;
+  const C() : x = foo();
+}
+int foo() => 42;
+''', allowErrors: true);
+    // It is OK to keep non-constant initializers.
+    checkElementText(library, r'''
+class C {
+  final dynamic x;
+  const C() :
+        x/*location: test.dart;C;x*/ =
+        foo/*location: test.dart;foo*/();
+}
+int foo() {}
+''');
+  }
+
+  test_constructor_initializers_field_withParameter() async {
+    var library = await checkLibrary('''
+class C {
+  final x;
+  const C(int p) : x = 1 + p;
+}
+''');
+    checkElementText(library, r'''
+class C {
+  final dynamic x;
+  const C(int p) :
+        x/*location: test.dart;C;x*/ = 1 +
+        p/*location: test.dart;C;;p*/;
+}
+''');
+  }
+
+  test_constructor_initializers_superInvocation_named() async {
+    var library = await checkLibrary('''
+class A {
+  const A.aaa(int p);
+}
+class C extends A {
+  const C() : super.aaa(42);
+}
+''');
+    checkElementText(library, r'''
+class A {
+  const A.aaa(int p);
+}
+class C extends A {
+  const C() : super.
+        aaa/*location: test.dart;A;aaa*/(42);
+}
+''');
+  }
+
+  test_constructor_initializers_superInvocation_named_underscore() async {
+    var library = await checkLibrary('''
+class A {
+  const A._();
+}
+class B extends A {
+  const B() : super._();
+}
+''');
+    checkElementText(library, r'''
+class A {
+  const A._();
+}
+class B extends A {
+  const B() : super.
+        _/*location: test.dart;A;_*/();
+}
+''');
+  }
+
+  test_constructor_initializers_superInvocation_namedExpression() async {
+    var library = await checkLibrary('''
+class A {
+  const A.aaa(a, {int b});
+}
+class C extends A {
+  const C() : super.aaa(1, b: 2);
+}
+''');
+    checkElementText(library, r'''
+class A {
+  const A.aaa(dynamic a, {int b});
+}
+class C extends A {
+  const C() : super.
+        aaa/*location: test.dart;A;aaa*/(1,
+        b/*location: null*/: 2);
+}
+''');
+  }
+
+  test_constructor_initializers_superInvocation_unnamed() async {
+    var library = await checkLibrary('''
+class A {
+  const A(int p);
+}
+class C extends A {
+  const C.ccc() : super(42);
+}
+''');
+    checkElementText(library, r'''
+class A {
+  const A(int p);
+}
+class C extends A {
+  const C.ccc() : super(42);
+}
+''');
+  }
+
+  test_constructor_initializers_thisInvocation_named() async {
+    var library = await checkLibrary('''
+class C {
+  const C() : this.named(1, 'bbb');
+  const C.named(int a, String b);
+}
+''');
+    checkElementText(library, r'''
+class C {
+  const C() = C.named : this.
+        named/*location: test.dart;C;named*/(1, 'bbb');
+  const C.named(int a, String b);
+}
+''');
+  }
+
+  test_constructor_initializers_thisInvocation_namedExpression() async {
+    var library = await checkLibrary('''
+class C {
+  const C() : this.named(1, b: 2);
+  const C.named(a, {int b});
+}
+''');
+    checkElementText(library, r'''
+class C {
+  const C() = C.named : this.
+        named/*location: test.dart;C;named*/(1,
+        b/*location: null*/: 2);
+  const C.named(dynamic a, {int b});
+}
+''');
+  }
+
+  test_constructor_initializers_thisInvocation_unnamed() async {
+    var library = await checkLibrary('''
+class C {
+  const C.named() : this(1, 'bbb');
+  const C(int a, String b);
+}
+''');
+    checkElementText(library, r'''
+class C {
+  const C.named() = C : this(1, 'bbb');
+  const C(int a, String b);
+}
+''');
+  }
+
+  test_constructor_redirected_factory_named() async {
+    var library = await checkLibrary('''
+class C {
+  factory C() = D.named;
+  C._();
+}
+class D extends C {
+  D.named() : super._();
+}
+''');
+    checkElementText(library, r'''
+class C {
+  factory C() = D.named;
+  C._();
+}
+class D extends C {
+  D.named();
+}
+''');
+  }
+
+  test_constructor_redirected_factory_named_generic() async {
+    var library = await checkLibrary('''
+class C<T, U> {
+  factory C() = D<U, T>.named;
+  C._();
+}
+class D<T, U> extends C<U, T> {
+  D.named() : super._();
+}
+''');
+    checkElementText(library, r'''
+class C<T, U> {
+  factory C() = D<U, T>.named;
+  C._();
+}
+class D<T, U> extends C<U, T> {
+  D.named();
+}
+''');
+  }
+
+  test_constructor_redirected_factory_named_imported() async {
+    addLibrarySource('/foo.dart', '''
+import 'test.dart';
+class D extends C {
+  D.named() : super._();
+}
+''');
+    var library = await checkLibrary('''
+import 'foo.dart';
+class C {
+  factory C() = D.named;
+  C._();
+}
+''');
+    checkElementText(library, r'''
+import 'foo.dart';
+class C {
+  factory C() = D.named;
+  C._();
+}
+''');
+  }
+
+  test_constructor_redirected_factory_named_imported_generic() async {
+    addLibrarySource('/foo.dart', '''
+import 'test.dart';
+class D<T, U> extends C<U, T> {
+  D.named() : super._();
+}
+''');
+    var library = await checkLibrary('''
+import 'foo.dart';
+class C<T, U> {
+  factory C() = D<U, T>.named;
+  C._();
+}
+''');
+    checkElementText(library, r'''
+import 'foo.dart';
+class C<T, U> {
+  factory C() = D<U, T>.named;
+  C._();
+}
+''');
+  }
+
+  test_constructor_redirected_factory_named_prefixed() async {
+    addLibrarySource('/foo.dart', '''
+import 'test.dart';
+class D extends C {
+  D.named() : super._();
+}
+''');
+    var library = await checkLibrary('''
+import 'foo.dart' as foo;
+class C {
+  factory C() = foo.D.named;
+  C._();
+}
+''');
+    checkElementText(library, r'''
+import 'foo.dart' as foo;
+class C {
+  factory C() = D.named;
+  C._();
+}
+''');
+  }
+
+  test_constructor_redirected_factory_named_prefixed_generic() async {
+    addLibrarySource('/foo.dart', '''
+import 'test.dart';
+class D<T, U> extends C<U, T> {
+  D.named() : super._();
+}
+''');
+    var library = await checkLibrary('''
+import 'foo.dart' as foo;
+class C<T, U> {
+  factory C() = foo.D<U, T>.named;
+  C._();
+}
+''');
+    checkElementText(library, r'''
+import 'foo.dart' as foo;
+class C<T, U> {
+  factory C() = D<U, T>.named;
+  C._();
+}
+''');
+  }
+
+  test_constructor_redirected_factory_named_unresolved_class() async {
+    var library = await checkLibrary('''
+class C<E> {
+  factory C() = D.named<E>;
+}
+''', allowErrors: true);
+    checkElementText(library, r'''
+class C<E> {
+  factory C();
+}
+''');
+  }
+
+  test_constructor_redirected_factory_named_unresolved_constructor() async {
+    var library = await checkLibrary('''
+class D {}
+class C<E> {
+  factory C() = D.named<E>;
+}
+''', allowErrors: true);
+    checkElementText(library, r'''
+class D {
+}
+class C<E> {
+  factory C();
+}
+''');
+  }
+
+  test_constructor_redirected_factory_unnamed() async {
+    var library = await checkLibrary('''
+class C {
+  factory C() = D;
+  C._();
+}
+class D extends C {
+  D() : super._();
+}
+''');
+    checkElementText(library, r'''
+class C {
+  factory C() = D;
+  C._();
+}
+class D extends C {
+  D();
+}
+''');
+  }
+
+  test_constructor_redirected_factory_unnamed_generic() async {
+    var library = await checkLibrary('''
+class C<T, U> {
+  factory C() = D<U, T>;
+  C._();
+}
+class D<T, U> extends C<U, T> {
+  D() : super._();
+}
+''');
+    checkElementText(library, r'''
+class C<T, U> {
+  factory C() = D<U, T>;
+  C._();
+}
+class D<T, U> extends C<U, T> {
+  D();
+}
+''');
+  }
+
+  test_constructor_redirected_factory_unnamed_imported() async {
+    addLibrarySource('/foo.dart', '''
+import 'test.dart';
+class D extends C {
+  D() : super._();
+}
+''');
+    var library = await checkLibrary('''
+import 'foo.dart';
+class C {
+  factory C() = D;
+  C._();
+}
+''');
+    checkElementText(library, r'''
+import 'foo.dart';
+class C {
+  factory C() = D;
+  C._();
+}
+''');
+  }
+
+  test_constructor_redirected_factory_unnamed_imported_generic() async {
+    addLibrarySource('/foo.dart', '''
+import 'test.dart';
+class D<T, U> extends C<U, T> {
+  D() : super._();
+}
+''');
+    var library = await checkLibrary('''
+import 'foo.dart';
+class C<T, U> {
+  factory C() = D<U, T>;
+  C._();
+}
+''');
+    checkElementText(library, r'''
+import 'foo.dart';
+class C<T, U> {
+  factory C() = D<U, T>;
+  C._();
+}
+''');
+  }
+
+  test_constructor_redirected_factory_unnamed_prefixed() async {
+    addLibrarySource('/foo.dart', '''
+import 'test.dart';
+class D extends C {
+  D() : super._();
+}
+''');
+    var library = await checkLibrary('''
+import 'foo.dart' as foo;
+class C {
+  factory C() = foo.D;
+  C._();
+}
+''');
+    checkElementText(library, r'''
+import 'foo.dart' as foo;
+class C {
+  factory C() = D;
+  C._();
+}
+''');
+  }
+
+  test_constructor_redirected_factory_unnamed_prefixed_generic() async {
+    addLibrarySource('/foo.dart', '''
+import 'test.dart';
+class D<T, U> extends C<U, T> {
+  D() : super._();
+}
+''');
+    var library = await checkLibrary('''
+import 'foo.dart' as foo;
+class C<T, U> {
+  factory C() = foo.D<U, T>;
+  C._();
+}
+''');
+    checkElementText(library, r'''
+import 'foo.dart' as foo;
+class C<T, U> {
+  factory C() = D<U, T>;
+  C._();
+}
+''');
+  }
+
+  test_constructor_redirected_factory_unnamed_unresolved() async {
+    var library = await checkLibrary('''
+class C<E> {
+  factory C() = D<E>;
+}
+''', allowErrors: true);
+    checkElementText(library, r'''
+class C<E> {
+  factory C();
+}
+''');
+  }
+
+  test_constructor_redirected_thisInvocation_named() async {
+    var library = await checkLibrary('''
+class C {
+  C.named();
+  C() : this.named();
+}
+''');
+    checkElementText(library, r'''
+class C {
+  C.named();
+  C() = C.named;
+}
+''');
+  }
+
+  test_constructor_redirected_thisInvocation_named_generic() async {
+    var library = await checkLibrary('''
+class C<T> {
+  C.named();
+  C() : this.named();
+}
+''');
+    checkElementText(library, r'''
+class C<T> {
+  C.named();
+  C() = C<T>.named;
+}
+''');
+  }
+
+  test_constructor_redirected_thisInvocation_unnamed() async {
+    var library = await checkLibrary('''
+class C {
+  C();
+  C.named() : this();
+}
+''');
+    checkElementText(library, r'''
+class C {
+  C();
+  C.named() = C;
+}
+''');
+  }
+
+  test_constructor_redirected_thisInvocation_unnamed_generic() async {
+    var library = await checkLibrary('''
+class C<T> {
+  C();
+  C.named() : this();
+}
+''');
+    checkElementText(library, r'''
+class C<T> {
+  C();
+  C.named() = C<T>;
+}
+''');
+  }
+
+  test_constructor_withCycles_const() async {
+    var library = await checkLibrary('''
+class C {
+  final x;
+  const C() : x = const D();
+}
+class D {
+  final x;
+  const D() : x = const C();
+}
+''');
+    checkElementText(library, r'''
+class C {
+  final dynamic x;
+  const C() :
+        x/*location: test.dart;C;x*/ = const
+        D/*location: test.dart;D*/();
+}
+class D {
+  final dynamic x;
+  const D() :
+        x/*location: test.dart;D;x*/ = const
+        C/*location: test.dart;C*/();
+}
+''');
+  }
+
+  test_constructor_withCycles_nonConst() async {
+    var library = await checkLibrary('''
+class C {
+  final x;
+  C() : x = new D();
+}
+class D {
+  final x;
+  D() : x = new C();
+}
+''');
+    checkElementText(library, r'''
+class C {
+  final dynamic x;
+  C();
+}
+class D {
+  final dynamic x;
+  D();
+}
+''');
+  }
+
+  test_defaultValue_genericFunction() async {
+    var library = await checkLibrary('''
+typedef void F<T>(T v);
+
+void defaultF<T>(T v) {}
+
+class X {
+  final F f;
+  const X({this.f: defaultF});
+}
+''');
+    checkElementText(library, r'''
+typedef F<T> = void Function(T v);
+class X {
+  final (dynamic) → void f;
+  const X({(dynamic) → void this.f:
+        defaultF/*location: test.dart;defaultF*/});
+}
+void defaultF<T>(T v) {}
+''');
+  }
+
+  test_defaultValue_refersToGenericClass_constructor() async {
+    var library = await checkLibrary('''
+class B<T> {
+  const B();
+}
+class C<T> {
+  const C([B<T> b = const B()]);
+}
+''');
+    checkElementText(library, r'''
+class B<T> {
+  const B();
+}
+class C<T> {
+  const C([B<T> b = const
+        B/*location: test.dart;B*/()]);
+}
+''');
+  }
+
+  test_defaultValue_refersToGenericClass_constructor2() async {
+    var library = await checkLibrary('''
+abstract class A<T> {}
+class B<T> implements A<T> {
+  const B();
+}
+class C<T> implements A<Iterable<T>> {
+  const C([A<T> a = const B()]);
+}
+''');
+    checkElementText(library, r'''
+abstract class A<T> {
+}
+class B<T> implements A<T> {
+  const B();
+}
+class C<T> implements A<Iterable<T>> {
+  const C([A<T> a = const
+        B/*location: test.dart;B*/()]);
+}
+''');
+  }
+
+  test_defaultValue_refersToGenericClass_functionG() async {
+    var library = await checkLibrary('''
+class B<T> {
+  const B();
+}
+void foo<T>([B<T> b = const B()]) {}
+''');
+    checkElementText(library, r'''
+class B<T> {
+  const B();
+}
+void foo<T>([B<T> b = const
+        B/*location: test.dart;B*/()]) {}
+''');
+  }
+
+  test_defaultValue_refersToGenericClass_methodG() async {
+    var library = await checkLibrary('''
+class B<T> {
+  const B();
+}
+class C {
+  void foo<T>([B<T> b = const B()]) {}
+}
+''');
+    checkElementText(library, r'''
+class B<T> {
+  const B();
+}
+class C {
+  void foo<T>([B<T> b = const
+        B/*location: test.dart;B*/()]) {}
+}
+''');
+  }
+
+  test_defaultValue_refersToGenericClass_methodG_classG() async {
+    var library = await checkLibrary('''
+class B<T1, T2> {
+  const B();
+}
+class C<E1> {
+  void foo<E2>([B<E1, E2> b = const B()]) {}
+}
+''');
+    checkElementText(library, r'''
+class B<T1, T2> {
+  const B();
+}
+class C<E1> {
+  void foo<E2>([B<E1, E2> b = const
+        B/*location: test.dart;B*/()]) {}
+}
+''');
+  }
+
+  test_defaultValue_refersToGenericClass_methodNG() async {
+    var library = await checkLibrary('''
+class B<T> {
+  const B();
+}
+class C<T> {
+  void foo([B<T> b = const B()]) {}
+}
+''');
+    checkElementText(library, r'''
+class B<T> {
+  const B();
+}
+class C<T> {
+  void foo([B<T> b = const
+        B/*location: test.dart;B*/()]) {}
+}
+''');
+  }
+
+  test_enum_documented() async {
+    var library = await checkLibrary('''
+// Extra comment so doc comment offset != 0
+/**
+ * Docs
+ */
+enum E { v }''');
+    checkElementText(library, r'''
+/**
+ * Docs
+ */
+enum E {
+  synthetic final int index;
+  synthetic static const List<E> values;
+  static const E v;
+  String toString() {}
+}
+''');
+  }
+
+  test_enum_value_documented() async {
+    var library = await checkLibrary('''
+enum E {
+  /**
+   * aaa
+   */
+  a,
+  /// bbb
+  b
+}''');
+    checkElementText(library, r'''
+enum E {
+  synthetic final int index;
+  synthetic static const List<E> values;
+  /**
+   * aaa
+   */
+  static const E a;
+  /// bbb
+  static const E b;
+  String toString() {}
+}
+''');
+  }
+
+  test_enum_values() async {
+    var library = await checkLibrary('enum E { v1, v2 }');
+    checkElementText(library, r'''
+enum E {
+  synthetic final int index;
+  synthetic static const List<E> values;
+  static const E v1;
+  static const E v2;
+  String toString() {}
+}
+''');
+  }
+
+  test_enums() async {
+    var library = await checkLibrary('enum E1 { v1 } enum E2 { v2 }');
+    checkElementText(library, r'''
+enum E1 {
+  synthetic final int index;
+  synthetic static const List<E1> values;
+  static const E1 v1;
+  String toString() {}
+}
+enum E2 {
+  synthetic final int index;
+  synthetic static const List<E2> values;
+  static const E2 v2;
+  String toString() {}
+}
+''');
+  }
+
+  test_error_extendsEnum() async {
+    var library = await checkLibrary('''
+enum E {a, b, c}
+
+class M {}
+
+class A extends E {
+  foo() {}
+}
+
+class B implements E, M {
+  foo() {}
+}
+
+class C extends Object with E, M {
+  foo() {}
+}
+
+class D = Object with M, E;
+''');
+    checkElementText(library, r'''
+enum E {
+  synthetic final int index;
+  synthetic static const List<E> values;
+  static const E a;
+  static const E b;
+  static const E c;
+  String toString() {}
+}
+class M {
+}
+class A {
+  dynamic foo() {}
+}
+class B implements M {
+  dynamic foo() {}
+}
+class C extends Object with M {
+  synthetic C();
+  dynamic foo() {}
+}
+class alias D extends Object with M {
+  synthetic D() = Object;
+}
+''');
+  }
+
+  test_executable_parameter_type_typedef() async {
+    var library = await checkLibrary(r'''
+typedef F(int p);
+main(F f) {}
+''');
+    checkElementText(library, r'''
+typedef F = dynamic Function(int p);
+dynamic main((int) → dynamic f) {}
+''');
+  }
+
+  test_export_class() async {
+    addLibrarySource('/a.dart', 'class C {}');
+    var library = await checkLibrary('export "a.dart";');
+    checkElementText(library, r'''
+export 'a.dart';
+''');
+  }
+
+  test_export_class_type_alias() async {
+    addLibrarySource('/a.dart', r'''
+class C = _D with _E;
+class _D {}
+class _E {}
+''');
+    var library = await checkLibrary('export "a.dart";');
+    checkElementText(library, r'''
+export 'a.dart';
+''');
+  }
+
+  test_export_configurations_useDefault() async {
+    context.declaredVariables =
+        new DeclaredVariables.fromMap({'dart.library.io': 'false'});
+    addLibrarySource('/foo.dart', 'class A {}');
+    addLibrarySource('/foo_io.dart', 'class A {}');
+    addLibrarySource('/foo_html.dart', 'class A {}');
+    var library = await checkLibrary(r'''
+export 'foo.dart'
+  if (dart.library.io) 'foo_io.dart'
+  if (dart.library.html) 'foo_html.dart';
+''');
+    checkElementText(library, r'''
+export 'foo.dart';
+''');
+    expect(library.exports[0].exportedLibrary.source.shortName, 'foo.dart');
+  }
+
+  test_export_configurations_useFirst() async {
+    context.declaredVariables = new DeclaredVariables.fromMap(
+        {'dart.library.io': 'true', 'dart.library.html': 'true'});
+    addLibrarySource('/foo.dart', 'class A {}');
+    addLibrarySource('/foo_io.dart', 'class A {}');
+    addLibrarySource('/foo_html.dart', 'class A {}');
+    var library = await checkLibrary(r'''
+export 'foo.dart'
+  if (dart.library.io) 'foo_io.dart'
+  if (dart.library.html) 'foo_html.dart';
+''');
+    checkElementText(library, r'''
+export 'foo_io.dart';
+''');
+    expect(library.exports[0].exportedLibrary.source.shortName, 'foo_io.dart');
+  }
+
+  test_export_configurations_useSecond() async {
+    context.declaredVariables = new DeclaredVariables.fromMap(
+        {'dart.library.io': 'false', 'dart.library.html': 'true'});
+    addLibrarySource('/foo.dart', 'class A {}');
+    addLibrarySource('/foo_io.dart', 'class A {}');
+    addLibrarySource('/foo_html.dart', 'class A {}');
+    var library = await checkLibrary(r'''
+export 'foo.dart'
+  if (dart.library.io) 'foo_io.dart'
+  if (dart.library.html) 'foo_html.dart';
+''');
+    checkElementText(library, r'''
+export 'foo_html.dart';
+''');
+    ExportElement export = library.exports[0];
+    expect(export.exportedLibrary.source.shortName, 'foo_html.dart');
+  }
+
+  test_export_function() async {
+    addLibrarySource('/a.dart', 'f() {}');
+    var library = await checkLibrary('export "a.dart";');
+    checkElementText(library, r'''
+export 'a.dart';
+''');
+  }
+
+  test_export_getter() async {
+    addLibrarySource('/a.dart', 'get f() => null;');
+    var library = await checkLibrary('export "a.dart";');
+    checkElementText(library, r'''
+export 'a.dart';
+''');
+  }
+
+  test_export_hide() async {
+    addLibrary('dart:async');
+    var library =
+        await checkLibrary('export "dart:async" hide Stream, Future;');
+    checkElementText(library, r'''
+export 'dart:async' hide Stream, Future;
+''');
+  }
+
+  test_export_multiple_combinators() async {
+    addLibrary('dart:async');
+    var library =
+        await checkLibrary('export "dart:async" hide Stream show Future;');
+    checkElementText(library, r'''
+export 'dart:async' hide Stream show Future;
+''');
+  }
+
+  test_export_setter() async {
+    addLibrarySource('/a.dart', 'void set f(value) {}');
+    var library = await checkLibrary('export "a.dart";');
+    checkElementText(library, r'''
+export 'a.dart';
+''');
+  }
+
+  test_export_show() async {
+    addLibrary('dart:async');
+    var library =
+        await checkLibrary('export "dart:async" show Future, Stream;');
+    checkElementText(library, r'''
+export 'dart:async' show Future, Stream;
+''');
+  }
+
+  test_export_typedef() async {
+    addLibrarySource('/a.dart', 'typedef F();');
+    var library = await checkLibrary('export "a.dart";');
+    checkElementText(library, r'''
+export 'a.dart';
+''');
+  }
+
+  test_export_variable() async {
+    addLibrarySource('/a.dart', 'var x;');
+    var library = await checkLibrary('export "a.dart";');
+    checkElementText(library, r'''
+export 'a.dart';
+''');
+  }
+
+  test_export_variable_const() async {
+    addLibrarySource('/a.dart', 'const x = 0;');
+    var library = await checkLibrary('export "a.dart";');
+    checkElementText(library, r'''
+export 'a.dart';
+''');
+  }
+
+  test_export_variable_final() async {
+    addLibrarySource('/a.dart', 'final x = 0;');
+    var library = await checkLibrary('export "a.dart";');
+    checkElementText(library, r'''
+export 'a.dart';
+''');
+  }
+
+  test_exportImport_configurations_useDefault() async {
+    context.declaredVariables =
+        new DeclaredVariables.fromMap({'dart.library.io': 'false'});
+    addLibrarySource('/foo.dart', 'class A {}');
+    addLibrarySource('/foo_io.dart', 'class A {}');
+    addLibrarySource('/foo_html.dart', 'class A {}');
+    addLibrarySource('/bar.dart', r'''
+export 'foo.dart'
+  if (dart.library.io) 'foo_io.dart'
+  if (dart.library.html) 'foo_html.dart';
+''');
+    var library = await checkLibrary(r'''
+import 'bar.dart';
+class B extends A {}
+''');
+    checkElementText(library, r'''
+import 'bar.dart';
+class B extends A {
+}
+''');
+    var typeA = library.definingCompilationUnit.getType('B').supertype;
+    expect(typeA.element.source.shortName, 'foo.dart');
+  }
+
+  test_exportImport_configurations_useFirst() async {
+    context.declaredVariables = new DeclaredVariables.fromMap(
+        {'dart.library.io': 'true', 'dart.library.html': 'true'});
+    addLibrarySource('/foo.dart', 'class A {}');
+    addLibrarySource('/foo_io.dart', 'class A {}');
+    addLibrarySource('/foo_html.dart', 'class A {}');
+    addLibrarySource('/bar.dart', r'''
+export 'foo.dart'
+  if (dart.library.io) 'foo_io.dart'
+  if (dart.library.html) 'foo_html.dart';
+''');
+    var library = await checkLibrary(r'''
+import 'bar.dart';
+class B extends A {}
+''');
+    checkElementText(library, r'''
+import 'bar.dart';
+class B extends A {
+}
+''');
+    var typeA = library.definingCompilationUnit.getType('B').supertype;
+    expect(typeA.element.source.shortName, 'foo_io.dart');
+  }
+
+  test_exports() async {
+    addLibrarySource('/a.dart', 'library a;');
+    addLibrarySource('/b.dart', 'library b;');
+    var library = await checkLibrary('export "a.dart"; export "b.dart";');
+    checkElementText(library, r'''
+export 'a.dart';
+export 'b.dart';
+''');
+  }
+
+  test_expr_invalid_typeParameter_asPrefix() async {
+    variablesWithNotConstInitializers.add('f');
+    var library = await checkLibrary('''
+class C<T> {
+  final f = T.k;
+}
+''');
+    checkElementText(library, r'''
+class C<T> {
+  final dynamic f;
+}
+''');
+  }
+
+  test_field_covariant() async {
+    var library = await checkLibrary('''
+class C {
+  covariant int x;
+}''');
+    checkElementText(library, r'''
+class C {
+  covariant int x;
+}
+''');
+  }
+
+  test_field_documented() async {
+    var library = await checkLibrary('''
+class C {
+  /**
+   * Docs
+   */
+  var x;
+}''');
+    checkElementText(library, r'''
+class C {
+  /**
+   * Docs
+   */
+  dynamic x;
+}
+''');
+  }
+
+  test_field_formal_param_inferred_type_implicit() async {
+    var library = await checkLibrary('class C extends D { var v; C(this.v); }'
+        ' abstract class D { int get v; }');
+    checkElementText(library, r'''
+class C extends D {
+  int v;
+  C(int this.v);
+}
+abstract class D {
+  int get v;
+}
+''');
+  }
+
+  test_field_inferred_type_nonStatic_explicit_initialized() async {
+    var library = await checkLibrary('class C { num v = 0; }');
+    checkElementText(library, r'''
+class C {
+  num v;
+}
+''');
+  }
+
+  test_field_inferred_type_nonStatic_implicit_initialized() async {
+    var library = await checkLibrary('class C { var v = 0; }');
+    checkElementText(library, r'''
+class C {
+  int v;
+}
+''');
+  }
+
+  test_field_inferred_type_nonStatic_implicit_uninitialized() async {
+    var library = await checkLibrary(
+        'class C extends D { var v; } abstract class D { int get v; }');
+    checkElementText(library, r'''
+class C extends D {
+  int v;
+}
+abstract class D {
+  int get v;
+}
+''');
+  }
+
+  test_field_inferred_type_static_implicit_initialized() async {
+    var library = await checkLibrary('class C { static var v = 0; }');
+    checkElementText(library, r'''
+class C {
+  static int v;
+}
+''');
+  }
+
+  test_field_propagatedType_const_noDep() async {
+    var library = await checkLibrary('''
+class C {
+  static const x = 0;
+}''');
+    checkElementText(library, r'''
+class C {
+  static const int x = 0;
+}
+''');
+  }
+
+  test_field_propagatedType_final_dep_inLib() async {
+    addLibrarySource('/a.dart', 'final a = 1;');
+    var library = await checkLibrary('''
+import "a.dart";
+class C {
+  final b = a / 2;
+}''');
+    checkElementText(library, r'''
+import 'a.dart';
+class C {
+  final double b;
+}
+''');
+  }
+
+  test_field_propagatedType_final_dep_inPart() async {
+    addSource('/a.dart', 'part of lib; final a = 1;');
+    var library = await checkLibrary('''
+library lib;
+part "a.dart";
+class C {
+  final b = a / 2;
+}''');
+    checkElementText(library, r'''
+library lib;
+part 'a.dart';
+class C {
+  final double b;
+}
+--------------------
+unit: a.dart
+
+final int a;
+''');
+  }
+
+  test_field_propagatedType_final_noDep_instance() async {
+    var library = await checkLibrary('''
+class C {
+  final x = 0;
+}''');
+    checkElementText(library, r'''
+class C {
+  final int x;
+}
+''');
+  }
+
+  test_field_propagatedType_final_noDep_static() async {
+    var library = await checkLibrary('''
+class C {
+  static final x = 0;
+}''');
+    checkElementText(library, r'''
+class C {
+  static final int x;
+}
+''');
+  }
+
+  test_field_static_final_untyped() async {
+    var library = await checkLibrary('class C { static final x = 0; }');
+    checkElementText(library, r'''
+class C {
+  static final int x;
+}
+''');
+  }
+
+  test_field_untyped() async {
+    var library = await checkLibrary('class C { var x = 0; }');
+    checkElementText(library, r'''
+class C {
+  int x;
+}
+''');
+  }
+
+  test_function_async() async {
+    var library = await checkLibrary(r'''
+import 'dart:async';
+Future f() async {}
+''');
+    checkElementText(library, r'''
+import 'dart:async';
+Future<dynamic> f() async {}
+''');
+  }
+
+  test_function_asyncStar() async {
+    var library = await checkLibrary(r'''
+import 'dart:async';
+Stream f() async* {}
+''');
+    checkElementText(library, r'''
+import 'dart:async';
+Stream<dynamic> f() async* {}
+''');
+  }
+
+  test_function_documented() async {
+    var library = await checkLibrary('''
+// Extra comment so doc comment offset != 0
+/**
+ * Docs
+ */
+f() {}''');
+    checkElementText(library, r'''
+/**
+ * Docs
+ */
+dynamic f() {}
+''');
+  }
+
+  test_function_entry_point() async {
+    var library = await checkLibrary('main() {}');
+    checkElementText(library, r'''
+dynamic main() {}
+''');
+  }
+
+  test_function_entry_point_in_export() async {
+    addLibrarySource('/a.dart', 'library a; main() {}');
+    var library = await checkLibrary('export "a.dart";');
+    checkElementText(library, r'''
+export 'a.dart';
+''');
+  }
+
+  test_function_entry_point_in_export_hidden() async {
+    addLibrarySource('/a.dart', 'library a; main() {}');
+    var library = await checkLibrary('export "a.dart" hide main;');
+    checkElementText(library, r'''
+export 'a.dart' hide main;
+''');
+  }
+
+  test_function_entry_point_in_part() async {
+    addSource('/a.dart', 'part of my.lib; main() {}');
+    var library = await checkLibrary('library my.lib; part "a.dart";');
+    checkElementText(library, r'''
+library my.lib;
+part 'a.dart';
+--------------------
+unit: a.dart
+
+dynamic main() {}
+''');
+  }
+
+  test_function_external() async {
+    var library = await checkLibrary('external f();');
+    checkElementText(library, r'''
+external dynamic f() {}
+''');
+  }
+
+  test_function_parameter_final() async {
+    var library = await checkLibrary('f(final x) {}');
+    checkElementText(library, r'''
+dynamic f(final dynamic x) {}
+''');
+  }
+
+  test_function_parameter_kind_named() async {
+    var library = await checkLibrary('f({x}) {}');
+    checkElementText(library, r'''
+dynamic f({dynamic x}) {}
+''');
+  }
+
+  test_function_parameter_kind_positional() async {
+    var library = await checkLibrary('f([x]) {}');
+    checkElementText(library, r'''
+dynamic f([dynamic x]) {}
+''');
+  }
+
+  test_function_parameter_kind_required() async {
+    var library = await checkLibrary('f(x) {}');
+    checkElementText(library, r'''
+dynamic f(dynamic x) {}
+''');
+  }
+
+  test_function_parameter_parameters() async {
+    var library = await checkLibrary('f(g(x, y)) {}');
+    checkElementText(library, r'''
+dynamic f((dynamic, dynamic) → dynamic g) {}
+''');
+  }
+
+  test_function_parameter_return_type() async {
+    var library = await checkLibrary('f(int g()) {}');
+    checkElementText(library, r'''
+dynamic f(() → int g) {}
+''');
+  }
+
+  test_function_parameter_return_type_void() async {
+    var library = await checkLibrary('f(void g()) {}');
+    checkElementText(library, r'''
+dynamic f(() → void g) {}
+''');
+  }
+
+  test_function_parameter_type() async {
+    var library = await checkLibrary('f(int i) {}');
+    checkElementText(library, r'''
+dynamic f(int i) {}
+''');
+  }
+
+  test_function_parameters() async {
+    var library = await checkLibrary('f(x, y) {}');
+    checkElementText(library, r'''
+dynamic f(dynamic x, dynamic y) {}
+''');
+  }
+
+  test_function_return_type() async {
+    var library = await checkLibrary('int f() => null;');
+    checkElementText(library, r'''
+int f() {}
+''');
+  }
+
+  test_function_return_type_implicit() async {
+    var library = await checkLibrary('f() => null;');
+    checkElementText(library, r'''
+dynamic f() {}
+''');
+  }
+
+  test_function_return_type_void() async {
+    var library = await checkLibrary('void f() {}');
+    checkElementText(library, r'''
+void f() {}
+''');
+  }
+
+  test_function_type_parameter() async {
+    var library = await checkLibrary('T f<T, U>(U u) => null;');
+    checkElementText(library, r'''
+T f<T, U>(U u) {}
+''');
+  }
+
+  test_function_type_parameter_with_function_typed_parameter() async {
+    var library = await checkLibrary('void f<T, U>(T x(U u)) {}');
+    checkElementText(library, r'''
+void f<T, U>((U) → T x) {}
+''');
+  }
+
+  test_function_typed_parameter_implicit() async {
+    var library = await checkLibrary('f(g()) => null;');
+    expect(
+        library
+            .definingCompilationUnit.functions[0].parameters[0].hasImplicitType,
+        isFalse);
+  }
+
+  test_functions() async {
+    var library = await checkLibrary('f() {} g() {}');
+    checkElementText(library, r'''
+dynamic f() {}
+dynamic g() {}
+''');
+  }
+
+  test_futureOr() async {
+    var library = await checkLibrary('import "dart:async"; FutureOr<int> x;');
+    checkElementText(library, r'''
+import 'dart:async';
+FutureOr<int> x;
+''');
+    var variables = library.definingCompilationUnit.topLevelVariables;
+    expect(variables, hasLength(1));
+    expect(variables[0].type.toString(), 'FutureOr<int>');
+  }
+
+  test_futureOr_const() async {
+    var library =
+        await checkLibrary('import "dart:async"; const x = FutureOr;');
+    checkElementText(library, r'''
+import 'dart:async';
+const Type x =
+        FutureOr/*location: dart:async;FutureOr*/;
+''');
+    var variables = library.definingCompilationUnit.topLevelVariables;
+    expect(variables, hasLength(1));
+    var x = variables[0] as ConstTopLevelVariableElementImpl;
+    expect(x.type.toString(), 'Type');
+    expect(x.constantInitializer.toString(), 'FutureOr');
+  }
+
+  test_futureOr_inferred() async {
+    var library = await checkLibrary('''
+import "dart:async";
+FutureOr<int> f() => null;
+var x = f();
+var y = x.then((z) => z.asDouble());
+''');
+    checkElementText(library, r'''
+import 'dart:async';
+FutureOr<int> x;
+dynamic y;
+FutureOr<int> f() {}
+''');
+    var variables = library.definingCompilationUnit.topLevelVariables;
+    expect(variables, hasLength(2));
+    var x = variables[0];
+    expect(x.name, 'x');
+    var y = variables[1];
+    expect(y.name, 'y');
+    expect(x.type.toString(), 'FutureOr<int>');
+    expect(y.type.toString(), 'dynamic');
+  }
+
+  test_generic_gClass_gMethodStatic() async {
+    var library = await checkLibrary('''
+class C<T, U> {
+  static void m<V, W>(V v, W w) {
+    void f<X, Y>(V v, W w, X x, Y y) {
+    }
+  }
+}
+''');
+    checkElementText(library, r'''
+class C<T, U> {
+  static void m<V, W>(V v, W w) {}
+}
+''');
+  }
+
+  test_genericFunction_asFunctionReturnType() async {
+    shouldCompareLibraryElements = false;
+    var library = await checkLibrary(r'''
+int Function(int a, String b) f() => null;
+''');
+    checkElementText(library, r'''
+(int, String) → int f() {}
+''');
+  }
+
+  test_genericFunction_asFunctionTypedParameterReturnType() async {
+    shouldCompareLibraryElements = false;
+    var library = await checkLibrary(r'''
+void f(int Function(int a, String b) p(num c)) => null;
+''');
+    checkElementText(library, r'''
+void f((num) → (int, String) → int p) {}
+''');
+  }
+
+  test_genericFunction_asGenericFunctionReturnType() async {
+    shouldCompareLibraryElements = false;
+    var library = await checkLibrary(r'''
+typedef F = void Function(String a) Function(int b);
+''');
+    checkElementText(library, r'''
+typedef F = (String) → void Function(int b);
+''');
+  }
+
+  test_genericFunction_asMethodReturnType() async {
+    shouldCompareLibraryElements = false;
+    var library = await checkLibrary(r'''
+class C {
+  int Function(int a, String b) m() => null;
+}
+''');
+    checkElementText(library, r'''
+class C {
+  (int, String) → int m() {}
+}
+''');
+  }
+
+  test_genericFunction_asParameterType() async {
+    shouldCompareLibraryElements = false;
+    var library = await checkLibrary(r'''
+void f(int Function(int a, String b) p) => null;
+''');
+    checkElementText(library, r'''
+void f((int, String) → int p) {}
+''');
+  }
+
+  test_genericFunction_asTopLevelVariableType() async {
+    shouldCompareLibraryElements = false;
+    var library = await checkLibrary(r'''
+int Function(int a, String b) v;
+''');
+    checkElementText(library, r'''
+(int, String) → int v;
+''');
+  }
+
+  test_getElement_constructor_named() async {
+    String text = 'class C { C.named(); }';
+    Source source = addLibrarySource('/test.dart', text);
+    ConstructorElement original = context
+        .computeLibraryElement(source)
+        .getType('C')
+        .getNamedConstructor('named');
+    expect(original, isNotNull);
+    ConstructorElement resynthesized = _validateGetElement(text, original);
+    compareConstructorElements(resynthesized, original, 'C.constructor named');
+  }
+
+  test_getElement_constructor_unnamed() async {
+    String text = 'class C { C(); }';
+    Source source = addLibrarySource('/test.dart', text);
+    ConstructorElement original =
+        context.computeLibraryElement(source).getType('C').unnamedConstructor;
+    expect(original, isNotNull);
+    ConstructorElement resynthesized = _validateGetElement(text, original);
+    compareConstructorElements(resynthesized, original, 'C.constructor');
+  }
+
+  test_getElement_field() async {
+    String text = 'class C { var f; }';
+    Source source = addLibrarySource('/test.dart', text);
+    FieldElement original =
+        context.computeLibraryElement(source).getType('C').getField('f');
+    expect(original, isNotNull);
+    FieldElement resynthesized = _validateGetElement(text, original);
+    compareFieldElements(resynthesized, original, 'C.field f');
+  }
+
+  test_getElement_getter() async {
+    String text = 'class C { get f => null; }';
+    Source source = addLibrarySource('/test.dart', text);
+    PropertyAccessorElement original =
+        context.computeLibraryElement(source).getType('C').getGetter('f');
+    expect(original, isNotNull);
+    PropertyAccessorElement resynthesized = _validateGetElement(text, original);
+    comparePropertyAccessorElements(resynthesized, original, 'C.getter f');
+  }
+
+  test_getElement_method() async {
+    String text = 'class C { f() {} }';
+    Source source = addLibrarySource('/test.dart', text);
+    MethodElement original =
+        context.computeLibraryElement(source).getType('C').getMethod('f');
+    expect(original, isNotNull);
+    MethodElement resynthesized = _validateGetElement(text, original);
+    compareMethodElements(resynthesized, original, 'C.method f');
+  }
+
+  test_getElement_operator() async {
+    String text = 'class C { operator+(x) => null; }';
+    Source source = addLibrarySource('/test.dart', text);
+    MethodElement original =
+        context.computeLibraryElement(source).getType('C').getMethod('+');
+    expect(original, isNotNull);
+    MethodElement resynthesized = _validateGetElement(text, original);
+    compareMethodElements(resynthesized, original, 'C.operator+');
+  }
+
+  test_getElement_setter() async {
+    String text = 'class C { void set f(value) {} }';
+    Source source = addLibrarySource('/test.dart', text);
+    PropertyAccessorElement original =
+        context.computeLibraryElement(source).getType('C').getSetter('f');
+    expect(original, isNotNull);
+    PropertyAccessorElement resynthesized = _validateGetElement(text, original);
+    comparePropertyAccessorElements(resynthesized, original, 'C.setter f');
+  }
+
+  test_getElement_unit() async {
+    String text = 'class C { f() {} }';
+    Source source = addLibrarySource('/test.dart', text);
+    CompilationUnitElement original =
+        context.computeLibraryElement(source).definingCompilationUnit;
+    expect(original, isNotNull);
+    CompilationUnitElement resynthesized = _validateGetElement(text, original);
+    compareCompilationUnitElements(resynthesized, original);
+  }
+
+  test_getter_documented() async {
+    var library = await checkLibrary('''
+// Extra comment so doc comment offset != 0
+/**
+ * Docs
+ */
+get x => null;''');
+    checkElementText(library, r'''
+/**
+ * Docs
+ */
+dynamic get x {}
+''');
+  }
+
+  test_getter_external() async {
+    var library = await checkLibrary('external int get x;');
+    checkElementText(library, r'''
+external int get x;
+''');
+  }
+
+  test_getter_inferred_type_nonStatic_implicit_return() async {
+    var library = await checkLibrary(
+        'class C extends D { get f => null; } abstract class D { int get f; }');
+    checkElementText(library, r'''
+class C extends D {
+  int get f {}
+}
+abstract class D {
+  int get f;
+}
+''');
+  }
+
+  test_getters() async {
+    var library = await checkLibrary('int get x => null; get y => null;');
+    checkElementText(library, r'''
+int get x {}
+dynamic get y {}
+''');
+  }
+
+  @failingTest
+  test_implicitConstructor_named_const() async {
+    // TODO(paulberry, scheglov): get this to pass
+    var library = await checkLibrary('''
+class C {
+  final Object x;
+  const C.named(this.x);
+}
+const x = C.named(42);
+''');
+    checkElementText(library, 'TODO(paulberry, scheglov)');
+  }
+
+  test_implicitTopLevelVariable_getterFirst() async {
+    var library =
+        await checkLibrary('int get x => 0; void set x(int value) {}');
+    checkElementText(library, r'''
+int get x {}
+void set x(int value) {}
+''');
+  }
+
+  test_implicitTopLevelVariable_setterFirst() async {
+    var library =
+        await checkLibrary('void set x(int value) {} int get x => 0;');
+    checkElementText(library, r'''
+void set x(int value) {}
+int get x {}
+''');
+  }
+
+  test_import_configurations_useDefault() async {
+    context.declaredVariables =
+        new DeclaredVariables.fromMap({'dart.library.io': 'false'});
+    addLibrarySource('/foo.dart', 'class A {}');
+    addLibrarySource('/foo_io.dart', 'class A {}');
+    addLibrarySource('/foo_html.dart', 'class A {}');
+    var library = await checkLibrary(r'''
+import 'foo.dart'
+  if (dart.library.io) 'foo_io.dart'
+  if (dart.library.html) 'foo_html.dart';
+
+class B extends A {}
+''');
+    checkElementText(library, r'''
+import 'foo.dart';
+class B extends A {
+}
+''');
+    var typeA = library.definingCompilationUnit.getType('B').supertype;
+    expect(typeA.element.source.shortName, 'foo.dart');
+  }
+
+  test_import_configurations_useFirst() async {
+    context.declaredVariables = new DeclaredVariables.fromMap(
+        {'dart.library.io': 'true', 'dart.library.html': 'true'});
+    addLibrarySource('/foo.dart', 'class A {}');
+    addLibrarySource('/foo_io.dart', 'class A {}');
+    addLibrarySource('/foo_html.dart', 'class A {}');
+    var library = await checkLibrary(r'''
+import 'foo.dart'
+  if (dart.library.io) 'foo_io.dart'
+  if (dart.library.html) 'foo_html.dart';
+
+class B extends A {}
+''');
+    checkElementText(library, r'''
+import 'foo_io.dart';
+class B extends A {
+}
+''');
+    var typeA = library.definingCompilationUnit.getType('B').supertype;
+    expect(typeA.element.source.shortName, 'foo_io.dart');
+  }
+
+  test_import_deferred() async {
+    addLibrarySource('/a.dart', 'f() {}');
+    var library = await checkLibrary('''
+import 'a.dart' deferred as p;
+main() {
+  p.f();
+  }
+''');
+    checkElementText(library, r'''
+import 'a.dart' deferred as p;
+dynamic main() {}
+''');
+  }
+
+  test_import_export() async {
+    addLibrary('dart:async');
+    var library = await checkLibrary('''
+import 'dart:async' as i1;
+export 'dart:math';
+import 'dart:async' as i2;
+export 'dart:math';
+import 'dart:async' as i3;
+export 'dart:math';
+''');
+    checkElementText(library, r'''
+import 'dart:async' as i1;
+import 'dart:async' as i2;
+import 'dart:async' as i3;
+export 'dart:math';
+export 'dart:math';
+export 'dart:math';
+''');
+  }
+
+  test_import_hide() async {
+    addLibrary('dart:async');
+    var library = await checkLibrary('''
+import 'dart:async' hide Stream, Completer; Future f;
+''');
+    checkElementText(library, r'''
+import 'dart:async' hide Stream, Completer;
+Future<dynamic> f;
+''');
+  }
+
+  test_import_invalidUri_metadata() async {
+    allowMissingFiles = true;
+    shouldCompareLibraryElements = false;
+    var library = await checkLibrary('''
+@foo
+import '';
+''');
+    checkElementText(library, r'''
+@#invalidConst
+import '<unresolved>';
+''');
+  }
+
+  test_import_multiple_combinators() async {
+    addLibrary('dart:async');
+    var library = await checkLibrary('''
+import "dart:async" hide Stream show Future;
+Future f;
+''');
+    checkElementText(library, r'''
+import 'dart:async' hide Stream show Future;
+Future<dynamic> f;
+''');
+  }
+
+  test_import_prefixed() async {
+    addLibrarySource('/a.dart', 'library a; class C {}');
+    var library = await checkLibrary('import "a.dart" as a; a.C c;');
+
+    expect(library.imports[0].prefix.nameOffset, 19);
+    expect(library.imports[0].prefix.nameLength, 1);
+
+    checkElementText(library, r'''
+import 'a.dart' as a;
+C c;
+''');
+  }
+
+  test_import_self() async {
+    var library = await checkLibrary('''
+import 'test.dart' as p;
+class C {}
+class D extends p.C {} // Prevent "unused import" warning
+''');
+    expect(library.imports, hasLength(2));
+    expect(library.imports[0].importedLibrary.location, library.location);
+    expect(library.imports[1].importedLibrary.isDartCore, true);
+    checkElementText(library, r'''
+import 'test.dart' as p;
+class C {
+}
+class D extends C {
+}
+''');
+  }
+
+  test_import_short_absolute() async {
+    testFile = '/my/project/bin/test.dart';
+    // Note: "/a.dart" resolves differently on Windows vs. Posix.
+    var destinationPath =
+        resourceProvider.pathContext.fromUri(Uri.parse('/a.dart'));
+    addLibrarySource(destinationPath, 'class C {}');
+    var library = await checkLibrary('import "/a.dart"; C c;');
+    checkElementText(library, r'''
+import 'a.dart';
+C c;
+''');
+  }
+
+  test_import_show() async {
+    addLibrary('dart:async');
+    var library = await checkLibrary('''
+import "dart:async" show Future, Stream;
+Future f;
+Stream s;
+''');
+    checkElementText(library, r'''
+import 'dart:async' show Future, Stream;
+Future<dynamic> f;
+Stream<dynamic> s;
+''');
+  }
+
+  test_imports() async {
+    addLibrarySource('/a.dart', 'library a; class C {}');
+    addLibrarySource('/b.dart', 'library b; class D {}');
+    var library =
+        await checkLibrary('import "a.dart"; import "b.dart"; C c; D d;');
+    checkElementText(library, r'''
+import 'a.dart';
+import 'b.dart';
+C c;
+D d;
+''');
+  }
+
+  @failingTest
+  void test_infer_generic_typedef_complex() async {
+    // TODO(paulberry, scheglov): get this test to pass.
+    var library = await checkLibrary('''
+typedef F<T> = D<T,U> Function<U>();
+class C<V> {
+  const C(F<V> f);
+}
+class D<T,U> {}
+D<int,U> f<U>() => null;
+const x = const C(f);
+''');
+    checkElementText(library, '''TODO(paulberry, scheglov)''');
+  }
+
+  void test_infer_generic_typedef_simple() async {
+    var library = await checkLibrary('''
+typedef F = D<T> Function<T>();
+class C {
+  const C(F f);
+}
+class D<T> {}
+D<T> f<T>() => null;
+const x = const C(f);
+''');
+    checkElementText(library, '''
+typedef F = D<T> Function<T>();
+class C {
+  const C(<T>() → D<T> f);
+}
+class D<T> {
+}
+const C x = const
+        C/*location: test.dart;C*/(
+        f/*location: test.dart;f*/);
+D<T> f<T>() {}
+''');
+  }
+
+  test_infer_instanceCreation_fromArguments() async {
+    var library = await checkLibrary('''
+class A {}
+
+class B extends A {}
+
+class S<T extends A> {
+  S(T _);
+}
+
+var s = new S(new B());
+''');
+    checkElementText(library, '''
+class A {
+}
+class B extends A {
+}
+class S<T extends A> {
+  S(T _);
+}
+S<B> s;
+''');
+  }
+
+  test_infer_property_set() async {
+    var library = await checkLibrary('''
+class A {
+  B b;
+}
+class B {
+  C get c => null;
+  void set c(C value) {}
+}
+class C {}
+class D extends C {}
+var a = new A();
+var x = a.b.c ??= new D();
+''');
+    checkElementText(library, '''
+class A {
+  B b;
+}
+class B {
+  C get c {}
+  void set c(C value) {}
+}
+class C {
+}
+class D extends C {
+}
+A a;
+C x;
+''');
+  }
+
+  test_inference_issue_32394() async {
+    // Test the type inference involed in dartbug.com/32394
+    var library = await checkLibrary('''
+var x = y.map((a) => a.toString());
+var y = [3];
+var z = x.toList();
+''');
+    checkElementText(library, '''
+Iterable<String> x;
+List<int> y;
+List<String> z;
+''');
+  }
+
+  test_inference_map() async {
+    var library = await checkLibrary('''
+class C {
+  int p;
+}
+var x = <C>[];
+var y = x.map((c) => c.p);
+''');
+    checkElementText(library, '''
+class C {
+  int p;
+}
+List<C> x;
+Iterable<int> y;
+''');
+  }
+
+  test_inferred_function_type_for_variable_in_generic_function() async {
+    // In the code below, `x` has an inferred type of `() => int`, with 2
+    // (unused) type parameters from the enclosing top level function.
+    var library = await checkLibrary('''
+f<U, V>() {
+  var x = () => 0;
+}
+''');
+    checkElementText(library, r'''
+dynamic f<U, V>() {}
+''');
+  }
+
+  test_inferred_function_type_in_generic_class_constructor() async {
+    // In the code below, `() => () => 0` has an inferred return type of
+    // `() => int`, with 2 (unused) type parameters from the enclosing class.
+    var library = await checkLibrary('''
+class C<U, V> {
+  final x;
+  C() : x = (() => () => 0);
+}
+''');
+    checkElementText(library, r'''
+class C<U, V> {
+  final dynamic x;
+  C();
+}
+''');
+  }
+
+  test_inferred_function_type_in_generic_class_getter() async {
+    // In the code below, `() => () => 0` has an inferred return type of
+    // `() => int`, with 2 (unused) type parameters from the enclosing class.
+    var library = await checkLibrary('''
+class C<U, V> {
+  get x => () => () => 0;
+}
+''');
+    checkElementText(library, r'''
+class C<U, V> {
+  dynamic get x {}
+}
+''');
+  }
+
+  test_inferred_function_type_in_generic_class_in_generic_method() async {
+    // In the code below, `() => () => 0` has an inferred return type of
+    // `() => int`, with 3 (unused) type parameters from the enclosing class
+    // and method.
+    var library = await checkLibrary('''
+class C<T> {
+  f<U, V>() {
+    print(() => () => 0);
+  }
+}
+''');
+    checkElementText(library, r'''
+class C<T> {
+  dynamic f<U, V>() {}
+}
+''');
+  }
+
+  test_inferred_function_type_in_generic_class_setter() async {
+    // In the code below, `() => () => 0` has an inferred return type of
+    // `() => int`, with 2 (unused) type parameters from the enclosing class.
+    var library = await checkLibrary('''
+class C<U, V> {
+  void set x(value) {
+    print(() => () => 0);
+  }
+}
+''');
+    checkElementText(library, r'''
+class C<U, V> {
+  void set x(dynamic value) {}
+}
+''');
+  }
+
+  test_inferred_function_type_in_generic_closure() async {
+    // In the code below, `<U, V>() => () => 0` has an inferred return type of
+    // `() => int`, with 3 (unused) type parameters.
+    var library = await checkLibrary('''
+f<T>() {
+  print(/*<U, V>*/() => () => 0);
+}
+''');
+    checkElementText(library, r'''
+dynamic f<T>() {}
+''');
+  }
+
+  test_inferred_generic_function_type_in_generic_closure() async {
+    // In the code below, `<U, V>() => <W, X, Y, Z>() => 0` has an inferred
+    // return type of `() => int`, with 7 (unused) type parameters.
+    var library = await checkLibrary('''
+f<T>() {
+  print(/*<U, V>*/() => /*<W, X, Y, Z>*/() => 0);
+}
+''');
+    checkElementText(library, r'''
+dynamic f<T>() {}
+''');
+  }
+
+  test_inferred_type_is_typedef() async {
+    var library = await checkLibrary('typedef int F(String s);'
+        ' class C extends D { var v; }'
+        ' abstract class D { F get v; }');
+    checkElementText(library, r'''
+typedef F = int Function(String s);
+class C extends D {
+  (String) → int v;
+}
+abstract class D {
+  (String) → int get v;
+}
+''');
+  }
+
+  test_inferred_type_refers_to_bound_type_param() async {
+    var library = await checkLibrary('''
+class C<T> extends D<int, T> {
+  var v;
+}
+abstract class D<U, V> {
+  Map<V, U> get v;
+}
+''');
+    checkElementText(library, r'''
+class C<T> extends D<int, T> {
+  Map<T, int> v;
+}
+abstract class D<U, V> {
+  Map<V, U> get v;
+}
+''');
+  }
+
+  test_inferred_type_refers_to_function_typed_param_of_typedef() async {
+    var library = await checkLibrary('''
+typedef void F(int g(String s));
+h(F f) => null;
+var v = h(/*info:INFERRED_TYPE_CLOSURE*/(y) {});
+''');
+    checkElementText(library, r'''
+typedef F = void Function((String) → int g);
+dynamic v;
+dynamic h(((String) → int) → void f) {}
+''');
+  }
+
+  test_inferred_type_refers_to_function_typed_parameter_type_generic_class() async {
+    var library = await checkLibrary('''
+class C<T, U> extends D<U, int> {
+  void f(int x, g) {}
+}
+abstract class D<V, W> {
+  void f(int x, W g(V s));
+}''');
+    checkElementText(library, r'''
+class C<T, U> extends D<U, int> {
+  void f(int x, (U) → int g) {}
+}
+abstract class D<V, W> {
+  void f(int x, (V) → W g);
+}
+''');
+  }
+
+  test_inferred_type_refers_to_function_typed_parameter_type_other_lib() async {
+    addLibrarySource('/a.dart', '''
+import 'b.dart';
+abstract class D extends E {}
+''');
+    addLibrarySource('/b.dart', '''
+abstract class E {
+  void f(int x, int g(String s));
+}
+''');
+    var library = await checkLibrary('''
+import 'a.dart';
+class C extends D {
+  void f(int x, g) {}
+}
+''');
+    checkElementText(library, r'''
+import 'a.dart';
+class C extends D {
+  void f(int x, (String) → int g) {}
+}
+''');
+  }
+
+  test_inferred_type_refers_to_method_function_typed_parameter_type() async {
+    var library = await checkLibrary('class C extends D { void f(int x, g) {} }'
+        ' abstract class D { void f(int x, int g(String s)); }');
+    checkElementText(library, r'''
+class C extends D {
+  void f(int x, (String) → int g) {}
+}
+abstract class D {
+  void f(int x, (String) → int g);
+}
+''');
+  }
+
+  test_inferred_type_refers_to_nested_function_typed_param() async {
+    var library = await checkLibrary('''
+f(void g(int x, void h())) => null;
+var v = f((x, y) {});
+''');
+    checkElementText(library, r'''
+dynamic v;
+dynamic f((int, () → void) → void g) {}
+''');
+  }
+
+  test_inferred_type_refers_to_nested_function_typed_param_named() async {
+    var library = await checkLibrary('''
+f({void g(int x, void h())}) => null;
+var v = f(g: (x, y) {});
+''');
+    checkElementText(library, r'''
+dynamic v;
+dynamic f({(int, () → void) → void g}) {}
+''');
+  }
+
+  test_inferred_type_refers_to_setter_function_typed_parameter_type() async {
+    var library = await checkLibrary('class C extends D { void set f(g) {} }'
+        ' abstract class D { void set f(int g(String s)); }');
+    checkElementText(library, r'''
+class C extends D {
+  void set f((String) → int g) {}
+}
+abstract class D {
+  void set f((String) → int g);
+}
+''');
+  }
+
+  test_inferredType_definedInSdkLibraryPart() async {
+    addSource('/a.dart', r'''
+import 'dart:async';
+class A {
+  m(Stream p) {}
+}
+''');
+    LibraryElement library = await checkLibrary(r'''
+import 'a.dart';
+class B extends A {
+  m(p) {}
+}
+  ''');
+    checkElementText(library, r'''
+import 'a.dart';
+class B extends A {
+  dynamic m(Stream<dynamic> p) {}
+}
+''');
+    ClassElement b = library.definingCompilationUnit.types[0];
+    ParameterElement p = b.methods[0].parameters[0];
+    // This test should verify that we correctly record inferred types,
+    // when the type is defined in a part of an SDK library. So, test that
+    // the type is actually in a part.
+    Element streamElement = p.type.element;
+    if (streamElement is ClassElement) {
+      expect(streamElement.source, isNot(streamElement.library.source));
+    }
+  }
+
+  test_inferredType_implicitCreation() async {
+    shouldCompareLibraryElements = false;
+    var library = await checkLibrary(r'''
+class A {
+  A();
+  A.named();
+}
+var a1 = A();
+var a2 = A.named();
+''');
+    checkElementText(library, r'''
+class A {
+  A();
+  A.named();
+}
+A a1;
+A a2;
+''');
+  }
+
+  test_inferredType_implicitCreation_prefixed() async {
+    shouldCompareLibraryElements = false;
+    addLibrarySource('/foo.dart', '''
+class A {
+  A();
+  A.named();
+}
+''');
+    var library = await checkLibrary('''
+import 'foo.dart' as foo;
+var a1 = foo.A();
+var a2 = foo.A.named();
+''');
+    checkElementText(library, r'''
+import 'foo.dart' as foo;
+A a1;
+A a2;
+''');
+  }
+
+  test_inferredType_usesSyntheticFunctionType_functionTypedParam() async {
+    // AnalysisContext does not set the enclosing element for the synthetic
+    // FunctionElement created for the [f, g] type argument.
+    shouldCompareLibraryElements = false;
+    var library = await checkLibrary('''
+int f(int x(String y)) => null;
+String g(int x(String y)) => null;
+var v = [f, g];
+''');
+    checkElementText(library, r'''
+List<((String) → int) → Object> v;
+int f((String) → int x) {}
+String g((String) → int x) {}
+''');
+  }
+
+  test_inheritance_errors() async {
+    var library = await checkLibrary('''
+abstract class A {
+  int m();
+}
+
+abstract class B {
+  String m();
+}
+
+abstract class C implements A, B {}
+
+abstract class D extends C {
+  var f;
+}
+''');
+    checkElementText(library, r'''
+abstract class A {
+  int m();
+}
+abstract class B {
+  String m();
+}
+abstract class C implements A, B {
+}
+abstract class D extends C {
+  dynamic f;
+}
+''');
+  }
+
+  test_initializer_executable_with_return_type_from_closure() async {
+    var library = await checkLibrary('var v = () => 0;');
+    checkElementText(library, r'''
+() → int v;
+''');
+  }
+
+  test_initializer_executable_with_return_type_from_closure_await_dynamic() async {
+    var library = await checkLibrary('var v = (f) async => await f;');
+    checkElementText(library, r'''
+(dynamic) → Future<dynamic> v;
+''');
+  }
+
+  test_initializer_executable_with_return_type_from_closure_await_future3_int() async {
+    var library = await checkLibrary(r'''
+import 'dart:async';
+var v = (Future<Future<Future<int>>> f) async => await f;
+''');
+    // The analyzer type system over-flattens - see dartbug.com/31887
+    checkElementText(library, r'''
+import 'dart:async';
+(Future<Future<Future<int>>>) → Future<int> v;
+''');
+  }
+
+  test_initializer_executable_with_return_type_from_closure_await_future_int() async {
+    var library = await checkLibrary(r'''
+import 'dart:async';
+var v = (Future<int> f) async => await f;
+''');
+    checkElementText(library, r'''
+import 'dart:async';
+(Future<int>) → Future<int> v;
+''');
+  }
+
+  test_initializer_executable_with_return_type_from_closure_await_future_noArg() async {
+    var library = await checkLibrary(r'''
+import 'dart:async';
+var v = (Future f) async => await f;
+''');
+    checkElementText(library, r'''
+import 'dart:async';
+(Future<dynamic>) → Future<dynamic> v;
+''');
+  }
+
+  test_initializer_executable_with_return_type_from_closure_field() async {
+    var library = await checkLibrary('''
+class C {
+  var v = () => 0;
+}
+''');
+    checkElementText(library, r'''
+class C {
+  () → int v;
+}
+''');
+  }
+
+  test_initializer_executable_with_return_type_from_closure_local() async {
+    var library = await checkLibrary('''
+void f() {
+  int u = 0;
+  var v = () => 0;
+}
+''');
+    checkElementText(library, r'''
+void f() {}
+''');
+  }
+
+  test_instantiateToBounds_boundRefersToEarlierTypeArgument() async {
+    var library = await checkLibrary('''
+class C<S extends num, T extends C<S, T>> {}
+C c;
+''');
+    checkElementText(library, r'''
+class C<S extends num, T extends C<S, T>> {
+}
+C<num, C<num, dynamic>> c;
+''');
+  }
+
+  test_instantiateToBounds_boundRefersToItself() async {
+    var library = await checkLibrary('''
+class C<T extends C<T>> {}
+C c;
+var c2 = new C();
+class B {
+  var c3 = new C();
+}
+''');
+    checkElementText(library, r'''
+class C<T extends C<T>> {
+}
+class B {
+  C<C<dynamic>> c3;
+}
+C<C<dynamic>> c;
+C<C<dynamic>> c2;
+''');
+  }
+
+  test_instantiateToBounds_boundRefersToLaterTypeArgument() async {
+    var library = await checkLibrary('''
+class C<T extends C<T, U>, U extends num> {}
+C c;
+''');
+    checkElementText(library, r'''
+class C<T extends C<T, U>, U extends num> {
+}
+C<C<dynamic, num>, num> c;
+''');
+  }
+
+  test_instantiateToBounds_functionTypeAlias_reexported() async {
+    addLibrarySource('/a.dart', r'''
+class O {}
+typedef T F<T extends O>(T p);
+''');
+    addLibrarySource('/b.dart', r'''
+export 'a.dart' show F;
+''');
+    var library = await checkLibrary('''
+import 'b.dart';
+class C {
+  F f() => null;
+}
+''');
+    checkElementText(library, r'''
+import 'b.dart';
+class C {
+  (O) → O f() {}
+}
+''');
+  }
+
+  test_instantiateToBounds_functionTypeAlias_simple() async {
+    var library = await checkLibrary('''
+typedef F<T extends num>(T p);
+F f;
+''');
+    checkElementText(library, r'''
+typedef F<T extends num> = dynamic Function(T p);
+(num) → dynamic f;
+''');
+  }
+
+  test_instantiateToBounds_simple() async {
+    var library = await checkLibrary('''
+class C<T extends num> {}
+C c;
+''');
+    checkElementText(library, r'''
+class C<T extends num> {
+}
+C<num> c;
+''');
+  }
+
+  test_invalid_annotation_prefixed_constructor() async {
+    shouldCompareLibraryElements = false;
+    addLibrarySource('/a.dart', r'''
+class C {
+  const C.named();
+}
+''');
+    var library = await checkLibrary('''
+import "a.dart" as a;
+@a.C.named
+class D {}
+''');
+    checkElementText(library, r'''
+import 'a.dart' as a;
+@#invalidConst
+class D {
+}
+''');
+  }
+
+  test_invalid_annotation_unprefixed_constructor() async {
+    shouldCompareLibraryElements = false;
+    addLibrarySource('/a.dart', r'''
+class C {
+  const C.named();
+}
+''');
+    var library = await checkLibrary('''
+import "a.dart";
+@C.named
+class D {}
+''');
+    checkElementText(library, r'''
+import 'a.dart';
+@#invalidConst
+class D {
+}
+''');
+  }
+
+  test_invalid_importPrefix_asTypeArgument() async {
+    var library = await checkLibrary('''
+import 'dart:async' as ppp;
+class C {
+  List<ppp> v;
+}
+''');
+    checkElementText(library, r'''
+import 'dart:async' as ppp;
+class C {
+  List<dynamic> v;
+}
+''');
+  }
+
+  test_invalid_nameConflict_imported() async {
+    shouldCompareLibraryElements = false;
+    namesThatCannotBeResolved.add('V');
+    addLibrarySource('/a.dart', 'V() {}');
+    addLibrarySource('/b.dart', 'V() {}');
+    var library = await checkLibrary('''
+import 'a.dart';
+import 'b.dart';
+foo([p = V]) {}
+''');
+    checkElementText(library, r'''
+import 'a.dart';
+import 'b.dart';
+dynamic foo([dynamic p = #invalidConst]) {}
+''');
+  }
+
+  test_invalid_nameConflict_imported_exported() async {
+    shouldCompareLibraryElements = false;
+    namesThatCannotBeResolved.add('V');
+    addLibrarySource('/a.dart', 'V() {}');
+    addLibrarySource('/b.dart', 'V() {}');
+    addLibrarySource('/c.dart', r'''
+export 'a.dart';
+export 'b.dart';
+''');
+    var library = await checkLibrary('''
+import 'c.dart';
+foo([p = V]) {}
+''');
+    checkElementText(library, r'''
+import 'c.dart';
+dynamic foo([dynamic p = #invalidConst]) {}
+''');
+  }
+
+  test_invalid_nameConflict_local() async {
+    shouldCompareLibraryElements = false;
+    namesThatCannotBeResolved.add('V');
+    var library = await checkLibrary('''
+foo([p = V]) {}
+V() {}
+var V;
+''');
+    checkElementText(library, r'''
+dynamic V;
+dynamic foo([dynamic p = #invalidConst]) {}
+dynamic V() {}
+''');
+  }
+
+  test_invalid_setterParameter_fieldFormalParameter() async {
+    var library = await checkLibrary('''
+class C {
+  int foo;
+  void set bar(this.foo) {}
+}
+''');
+    checkElementText(library, r'''
+class C {
+  int foo;
+  void set bar(dynamic this.foo) {}
+}
+''');
+  }
+
+  test_invalid_setterParameter_fieldFormalParameter_self() async {
+    var library = await checkLibrary('''
+class C {
+  set x(this.x) {}
+}
+''');
+    checkElementText(library, r'''
+class C {
+  void set x(dynamic this.x) {}
+}
+''');
+  }
+
+  test_invalidUri_part_emptyUri() async {
+    allowMissingFiles = true;
+    shouldCompareLibraryElements = false;
+    var library = await checkLibrary(r'''
+part '';
+class B extends A {}
+''');
+    checkElementText(library, r'''
+part '<unresolved>';
+class B {
+}
+--------------------
+unit: null
+
+''');
+  }
+
+  test_invalidUris() async {
+    allowMissingFiles = true;
+    shouldCompareLibraryElements = false;
+    var library = await checkLibrary(r'''
+import '[invalid uri]';
+import '[invalid uri]:foo.dart';
+import 'a1.dart';
+import '[invalid uri]';
+import '[invalid uri]:foo.dart';
+
+export '[invalid uri]';
+export '[invalid uri]:foo.dart';
+export 'a2.dart';
+export '[invalid uri]';
+export '[invalid uri]:foo.dart';
+
+part '[invalid uri]';
+part 'a3.dart';
+part '[invalid uri]';
+''');
+    checkElementText(library, r'''
+import '<unresolved>';
+import '<unresolved>';
+import 'a1.dart';
+import '<unresolved>';
+import '<unresolved>';
+export '<unresolved>';
+export '<unresolved>';
+export 'a2.dart';
+export '<unresolved>';
+export '<unresolved>';
+part '<unresolved>';
+part 'a3.dart';
+part '<unresolved>';
+--------------------
+unit: null
+
+--------------------
+unit: a3.dart
+
+--------------------
+unit: null
+
+''');
+  }
+
+  test_library() async {
+    var library = await checkLibrary('');
+    checkElementText(library, r'''
+''');
+  }
+
+  test_library_documented_lines() async {
+    var library = await checkLibrary('''
+/// aaa
+/// bbb
+library test;
+''');
+    checkElementText(library, r'''
+/// aaa
+/// bbb
+library test;
+''');
+  }
+
+  test_library_documented_stars() async {
+    var library = await checkLibrary('''
+/**
+ * aaa
+ * bbb
+ */
+library test;''');
+    checkElementText(library, r'''
+/**
+ * aaa
+ * bbb
+ */
+library test;
+''');
+  }
+
+  test_library_name_with_spaces() async {
+    var library = await checkLibrary('library foo . bar ;');
+    checkElementText(library, r'''
+library foo.bar;
+''');
+  }
+
+  test_library_named() async {
+    var library = await checkLibrary('library foo.bar;');
+    checkElementText(library, r'''
+library foo.bar;
+''');
+  }
+
+  test_localFunctions() async {
+    var library = await checkLibrary(r'''
+f() {
+  f1() {}
+  {
+    f2() {}
+  }
+}
+''');
+    checkElementText(library, r'''
+dynamic f() {}
+''');
+  }
+
+  test_localFunctions_inConstructor() async {
+    var library = await checkLibrary(r'''
+class C {
+  C() {
+    f() {}
+  }
+}
+''');
+    checkElementText(library, r'''
+class C {
+  C();
+}
+''');
+  }
+
+  test_localFunctions_inMethod() async {
+    var library = await checkLibrary(r'''
+class C {
+  m() {
+    f() {}
+  }
+}
+''');
+    checkElementText(library, r'''
+class C {
+  dynamic m() {}
+}
+''');
+  }
+
+  test_localFunctions_inTopLevelGetter() async {
+    var library = await checkLibrary(r'''
+get g {
+  f() {}
+}
+''');
+    checkElementText(library, r'''
+dynamic get g {}
+''');
+  }
+
+  test_localLabels_inConstructor() async {
+    var library = await checkLibrary(r'''
+class C {
+  C() {
+    aaa: while (true) {}
+    bbb: switch (42) {
+      ccc: case 0:
+        break;
+    }
+  }
+}
+''', allowErrors: true);
+    checkElementText(library, r'''
+class C {
+  C();
+}
+''');
+  }
+
+  test_localLabels_inMethod() async {
+    var library = await checkLibrary(r'''
+class C {
+  m() {
+    aaa: while (true) {}
+    bbb: switch (42) {
+      ccc: case 0:
+        break;
+    }
+  }
+}
+''', allowErrors: true);
+    checkElementText(library, r'''
+class C {
+  dynamic m() {}
+}
+''');
+  }
+
+  test_localLabels_inTopLevelFunction() async {
+    var library = await checkLibrary(r'''
+main() {
+  aaa: while (true) {}
+  bbb: switch (42) {
+    ccc: case 0:
+      break;
+  }
+}
+''', allowErrors: true);
+    checkElementText(library, r'''
+dynamic main() {}
+''');
+  }
+
+  test_main_class() async {
+    var library = await checkLibrary('class main {}');
+    checkElementText(library, r'''
+class main {
+}
+''');
+  }
+
+  test_main_class_alias() async {
+    var library =
+        await checkLibrary('class main = C with D; class C {} class D {}');
+    checkElementText(library, r'''
+class alias main extends C with D {
+  synthetic main() = C;
+}
+class C {
+}
+class D {
+}
+''');
+  }
+
+  test_main_class_alias_via_export() async {
+    addLibrarySource('/a.dart', 'class main = C with D; class C {} class D {}');
+    var library = await checkLibrary('export "a.dart";');
+    checkElementText(library, r'''
+export 'a.dart';
+''');
+  }
+
+  test_main_class_via_export() async {
+    addLibrarySource('/a.dart', 'class main {}');
+    var library = await checkLibrary('export "a.dart";');
+    checkElementText(library, r'''
+export 'a.dart';
+''');
+  }
+
+  test_main_getter() async {
+    var library = await checkLibrary('get main => null;');
+    checkElementText(library, r'''
+dynamic get main {}
+''');
+  }
+
+  test_main_getter_via_export() async {
+    addLibrarySource('/a.dart', 'get main => null;');
+    var library = await checkLibrary('export "a.dart";');
+    checkElementText(library, r'''
+export 'a.dart';
+''');
+  }
+
+  test_main_typedef() async {
+    var library = await checkLibrary('typedef main();');
+    checkElementText(library, r'''
+typedef main = dynamic Function();
+''');
+  }
+
+  test_main_typedef_via_export() async {
+    addLibrarySource('/a.dart', 'typedef main();');
+    var library = await checkLibrary('export "a.dart";');
+    checkElementText(library, r'''
+export 'a.dart';
+''');
+  }
+
+  test_main_variable() async {
+    var library = await checkLibrary('var main;');
+    checkElementText(library, r'''
+dynamic main;
+''');
+  }
+
+  test_main_variable_via_export() async {
+    addLibrarySource('/a.dart', 'var main;');
+    var library = await checkLibrary('export "a.dart";');
+    checkElementText(library, r'''
+export 'a.dart';
+''');
+  }
+
+  test_member_function_async() async {
+    var library = await checkLibrary(r'''
+import 'dart:async';
+class C {
+  Future f() async {}
+}
+''');
+    checkElementText(library, r'''
+import 'dart:async';
+class C {
+  Future<dynamic> f() async {}
+}
+''');
+  }
+
+  test_member_function_asyncStar() async {
+    var library = await checkLibrary(r'''
+import 'dart:async';
+class C {
+  Stream f() async* {}
+}
+''');
+    checkElementText(library, r'''
+import 'dart:async';
+class C {
+  Stream<dynamic> f() async* {}
+}
+''');
+  }
+
+  test_member_function_syncStar() async {
+    var library = await checkLibrary(r'''
+class C {
+  Iterable<int> f() sync* {
+    yield 42;
+  }
+}
+''');
+    checkElementText(library, r'''
+class C {
+  Iterable<int> f() sync* {}
+}
+''');
+  }
+
+  test_metadata_classDeclaration() async {
+    var library = await checkLibrary(r'''
+const a = null;
+const b = null;
+@a
+@b
+class C {}''');
+    checkElementText(library, r'''
+@
+        a/*location: test.dart;a?*/
+@
+        b/*location: test.dart;b?*/
+class C {
+}
+const dynamic a = null;
+const dynamic b = null;
+''');
+  }
+
+  test_metadata_classTypeAlias() async {
+    var library = await checkLibrary(
+        'const a = null; @a class C = D with E; class D {} class E {}');
+    checkElementText(library, r'''
+@
+        a/*location: test.dart;a?*/
+class alias C extends D with E {
+  synthetic C() = D;
+}
+class D {
+}
+class E {
+}
+const dynamic a = null;
+''');
+  }
+
+  test_metadata_constructor_call_named() async {
+    var library = await checkLibrary('''
+class A {
+  const A.named();
+}
+@A.named()
+class C {}
+''');
+    checkElementText(library, r'''
+class A {
+  const A.named();
+}
+@
+        A/*location: test.dart;A*/.
+        named/*location: test.dart;A;named*/()
+class C {
+}
+''');
+  }
+
+  test_metadata_constructor_call_named_prefixed() async {
+    addLibrarySource('/foo.dart', 'class A { const A.named(); }');
+    var library = await checkLibrary('''
+import 'foo.dart' as foo;
+@foo.A.named()
+class C {}
+''');
+    checkElementText(library, r'''
+import 'foo.dart' as foo;
+@
+        A/*location: foo.dart;A*/.
+        named/*location: foo.dart;A;named*/()
+class C {
+}
+''');
+  }
+
+  test_metadata_constructor_call_unnamed() async {
+    var library = await checkLibrary('class A { const A(); } @A() class C {}');
+    checkElementText(library, r'''
+class A {
+  const A();
+}
+@
+        A/*location: test.dart;A*/()
+class C {
+}
+''');
+  }
+
+  test_metadata_constructor_call_unnamed_prefixed() async {
+    addLibrarySource('/foo.dart', 'class A { const A(); }');
+    var library =
+        await checkLibrary('import "foo.dart" as foo; @foo.A() class C {}');
+    checkElementText(library, r'''
+import 'foo.dart' as foo;
+@
+        A/*location: foo.dart;A*/()
+class C {
+}
+''');
+  }
+
+  test_metadata_constructor_call_with_args() async {
+    var library =
+        await checkLibrary('class A { const A(x); } @A(null) class C {}');
+    checkElementText(library, r'''
+class A {
+  const A(dynamic x);
+}
+@
+        A/*location: test.dart;A*/(null)
+class C {
+}
+''');
+  }
+
+  test_metadata_constructorDeclaration_named() async {
+    var library =
+        await checkLibrary('const a = null; class C { @a C.named(); }');
+    checkElementText(library, r'''
+class C {
+  @
+        a/*location: test.dart;a?*/
+  C.named();
+}
+const dynamic a = null;
+''');
+  }
+
+  test_metadata_constructorDeclaration_unnamed() async {
+    var library = await checkLibrary('const a = null; class C { @a C(); }');
+    checkElementText(library, r'''
+class C {
+  @
+        a/*location: test.dart;a?*/
+  C();
+}
+const dynamic a = null;
+''');
+  }
+
+  test_metadata_enumConstantDeclaration() async {
+    var library = await checkLibrary('const a = null; enum E { @a v }');
+    checkElementText(library, r'''
+enum E {
+  synthetic final int index;
+  synthetic static const List<E> values;
+  @
+        a/*location: test.dart;a?*/
+  static const E v;
+  String toString() {}
+}
+const dynamic a = null;
+''');
+  }
+
+  test_metadata_enumDeclaration() async {
+    var library = await checkLibrary('const a = null; @a enum E { v }');
+    checkElementText(library, r'''
+@
+        a/*location: test.dart;a?*/
+enum E {
+  synthetic final int index;
+  synthetic static const List<E> values;
+  static const E v;
+  String toString() {}
+}
+const dynamic a = null;
+''');
+  }
+
+  test_metadata_exportDirective() async {
+    addLibrarySource('/foo.dart', '');
+    var library = await checkLibrary('@a export "foo.dart"; const a = null;');
+    checkElementText(library, r'''
+@
+        a/*location: test.dart;a?*/
+export 'foo.dart';
+const dynamic a = null;
+''');
+  }
+
+  test_metadata_fieldDeclaration() async {
+    var library = await checkLibrary('const a = null; class C { @a int x; }');
+    checkElementText(library, r'''
+class C {
+  @
+        a/*location: test.dart;a?*/
+  int x;
+}
+const dynamic a = null;
+''');
+  }
+
+  test_metadata_fieldFormalParameter() async {
+    var library = await checkLibrary('''
+const a = null;
+class C {
+  var x;
+  C(@a this.x);
+}
+''');
+    checkElementText(library, r'''
+class C {
+  dynamic x;
+  C(@
+        a/*location: test.dart;a?*/ dynamic this.x);
+}
+const dynamic a = null;
+''');
+  }
+
+  test_metadata_fieldFormalParameter_withDefault() async {
+    var library = await checkLibrary(
+        'const a = null; class C { var x; C([@a this.x = null]); }');
+    checkElementText(library, r'''
+class C {
+  dynamic x;
+  C([@
+        a/*location: test.dart;a?*/ dynamic this.x = null]);
+}
+const dynamic a = null;
+''');
+  }
+
+  test_metadata_functionDeclaration_function() async {
+    var library = await checkLibrary('''
+const a = null;
+@a
+f() {}
+''');
+    checkElementText(library, r'''
+const dynamic a = null;
+@
+        a/*location: test.dart;a?*/
+dynamic f() {}
+''');
+  }
+
+  test_metadata_functionDeclaration_getter() async {
+    var library = await checkLibrary('const a = null; @a get f => null;');
+    checkElementText(library, r'''
+const dynamic a = null;
+@
+        a/*location: test.dart;a?*/
+dynamic get f {}
+''');
+  }
+
+  test_metadata_functionDeclaration_setter() async {
+    var library = await checkLibrary('const a = null; @a set f(value) {}');
+    checkElementText(library, r'''
+const dynamic a = null;
+@
+        a/*location: test.dart;a?*/
+void set f(dynamic value) {}
+''');
+  }
+
+  test_metadata_functionTypeAlias() async {
+    var library = await checkLibrary('const a = null; @a typedef F();');
+    checkElementText(library, r'''
+@
+        a/*location: test.dart;a?*/
+typedef F = dynamic Function();
+const dynamic a = null;
+''');
+  }
+
+  test_metadata_functionTypedFormalParameter() async {
+    var library = await checkLibrary('const a = null; f(@a g()) {}');
+    checkElementText(library, r'''
+const dynamic a = null;
+dynamic f(@
+        a/*location: test.dart;a?*/ () → dynamic g) {}
+''');
+  }
+
+  test_metadata_functionTypedFormalParameter_withDefault() async {
+    var library = await checkLibrary('const a = null; f([@a g() = null]) {}');
+    checkElementText(library, r'''
+const dynamic a = null;
+dynamic f([@
+        a/*location: test.dart;a?*/ () → dynamic g = null]) {}
+''');
+  }
+
+  test_metadata_importDirective() async {
+    addLibrarySource('/foo.dart', 'const b = null;');
+    var library = await checkLibrary('@a import "foo.dart"; const a = b;');
+    checkElementText(library, r'''
+@
+        a/*location: test.dart;a?*/
+import 'foo.dart';
+const dynamic a =
+        b/*location: foo.dart;b?*/;
+''');
+  }
+
+  test_metadata_invalid_classDeclaration() async {
+    shouldCompareLibraryElements = false;
+    var library = await checkLibrary('f(_) {} @f(42) class C {}');
+    checkElementText(library, r'''
+@#invalidConst
+class C {
+}
+dynamic f(dynamic _) {}
+''');
+  }
+
+  test_metadata_libraryDirective() async {
+    var library = await checkLibrary('@a library L; const a = null;');
+    checkElementText(library, r'''
+@
+        a/*location: test.dart;a?*/
+library L;
+const dynamic a = null;
+''');
+  }
+
+  test_metadata_methodDeclaration_getter() async {
+    var library =
+        await checkLibrary('const a = null; class C { @a get m => null; }');
+    checkElementText(library, r'''
+class C {
+  @
+        a/*location: test.dart;a?*/
+  dynamic get m {}
+}
+const dynamic a = null;
+''');
+  }
+
+  test_metadata_methodDeclaration_method() async {
+    var library = await checkLibrary(r'''
+const a = null;
+const b = null;
+class C {
+  @a
+  @b
+  m() {}
+}
+''');
+    checkElementText(library, r'''
+class C {
+  @
+        a/*location: test.dart;a?*/
+  @
+        b/*location: test.dart;b?*/
+  dynamic m() {}
+}
+const dynamic a = null;
+const dynamic b = null;
+''');
+  }
+
+  test_metadata_methodDeclaration_setter() async {
+    var library = await checkLibrary('''
+const a = null;
+class C {
+  @a
+  set m(value) {}
+}
+''');
+    checkElementText(library, r'''
+class C {
+  @
+        a/*location: test.dart;a?*/
+  void set m(dynamic value) {}
+}
+const dynamic a = null;
+''');
+  }
+
+  test_metadata_partDirective() async {
+    addSource('/foo.dart', 'part of L;');
+    var library = await checkLibrary('''
+library L;
+@a
+part 'foo.dart';
+const a = null;''');
+    checkElementText(library, r'''
+library L;
+@
+        a/*location: test.dart;a?*/
+part 'foo.dart';
+const dynamic a = null;
+--------------------
+unit: foo.dart
+
+''');
+  }
+
+  test_metadata_prefixed_variable() async {
+    addLibrarySource('/a.dart', 'const b = null;');
+    var library = await checkLibrary('import "a.dart" as a; @a.b class C {}');
+    checkElementText(library, r'''
+import 'a.dart' as a;
+@
+        a/*location: test.dart;a*/.
+        b/*location: a.dart;b?*/
+class C {
+}
+''');
+  }
+
+  test_metadata_simpleFormalParameter() async {
+    var library = await checkLibrary('const a = null; f(@a x) {}');
+    checkElementText(library, r'''
+const dynamic a = null;
+dynamic f(@
+        a/*location: test.dart;a?*/ dynamic x) {}
+''');
+  }
+
+  test_metadata_simpleFormalParameter_withDefault() async {
+    var library = await checkLibrary('const a = null; f([@a x = null]) {}');
+    checkElementText(library, r'''
+const dynamic a = null;
+dynamic f([@
+        a/*location: test.dart;a?*/ dynamic x = null]) {}
+''');
+  }
+
+  test_metadata_topLevelVariableDeclaration() async {
+    var library = await checkLibrary('const a = null; @a int v;');
+    checkElementText(library, r'''
+const dynamic a = null;
+@
+        a/*location: test.dart;a?*/
+int v;
+''');
+  }
+
+  test_metadata_typeParameter_ofClass() async {
+    var library = await checkLibrary('const a = null; class C<@a T> {}');
+    checkElementText(library, r'''
+class C<T> {
+}
+const dynamic a = null;
+''');
+  }
+
+  test_metadata_typeParameter_ofClassTypeAlias() async {
+    var library = await checkLibrary('''
+const a = null;
+class C<@a T> = D with E;
+class D {}
+class E {}''');
+    checkElementText(library, r'''
+class alias C<T> extends D with E {
+  synthetic C() = D;
+}
+class D {
+}
+class E {
+}
+const dynamic a = null;
+''');
+  }
+
+  test_metadata_typeParameter_ofFunction() async {
+    var library = await checkLibrary('const a = null; f<@a T>() {}');
+    checkElementText(library, r'''
+const dynamic a = null;
+dynamic f<T>() {}
+''');
+  }
+
+  test_metadata_typeParameter_ofTypedef() async {
+    var library = await checkLibrary('const a = null; typedef F<@a T>();');
+    checkElementText(library, r'''
+typedef F<T> = dynamic Function();
+const dynamic a = null;
+''');
+  }
+
+  test_method_documented() async {
+    var library = await checkLibrary('''
+class C {
+  /**
+   * Docs
+   */
+  f() {}
+}''');
+    checkElementText(library, r'''
+class C {
+  /**
+   * Docs
+   */
+  dynamic f() {}
+}
+''');
+  }
+
+  test_method_inferred_type_nonStatic_implicit_param() async {
+    var library = await checkLibrary('class C extends D { void f(value) {} }'
+        ' abstract class D { void f(int value); }');
+    checkElementText(library, r'''
+class C extends D {
+  void f(int value) {}
+}
+abstract class D {
+  void f(int value);
+}
+''');
+  }
+
+  test_method_inferred_type_nonStatic_implicit_return() async {
+    var library = await checkLibrary('''
+class C extends D {
+  f() => null;
+}
+abstract class D {
+  int f();
+}
+''');
+    checkElementText(library, r'''
+class C extends D {
+  int f() {}
+}
+abstract class D {
+  int f();
+}
+''');
+  }
+
+  test_method_type_parameter() async {
+    var library = await checkLibrary('class C { T f<T, U>(U u) => null; }');
+    checkElementText(library, r'''
+class C {
+  T f<T, U>(U u) {}
+}
+''');
+  }
+
+  test_method_type_parameter_in_generic_class() async {
+    var library = await checkLibrary('''
+class C<T, U> {
+  V f<V, W>(T t, U u, W w) => null;
+}
+''');
+    checkElementText(library, r'''
+class C<T, U> {
+  V f<V, W>(T t, U u, W w) {}
+}
+''');
+  }
+
+  test_method_type_parameter_with_function_typed_parameter() async {
+    var library = await checkLibrary('class C { void f<T, U>(T x(U u)) {} }');
+    checkElementText(library, r'''
+class C {
+  void f<T, U>((U) → T x) {}
+}
+''');
+  }
+
+  test_methodInvocation_implicitCall() async {
+    var library = await checkLibrary(r'''
+class A {
+  double call() => 0.0;
+}
+class B {
+  A a;
+}
+var c = new B().a();
+''');
+    checkElementText(library, r'''
+class A {
+  double call() {}
+}
+class B {
+  A a;
+}
+double c;
+''');
+  }
+
+  test_mixin() async {
+    var library = await checkLibrary(r'''
+class A {}
+class B {}
+class C {}
+class D {}
+
+mixin M<T extends num, U> on A, B implements C, D {
+  T f;
+  U get g => 0;
+  set s(int v) {}
+  int m(double v) => 0;
+}
+''');
+    checkElementText(library, r'''
+class A {
+}
+class B {
+}
+class C {
+}
+class D {
+}
+mixin M<T extends num, U> on A, B implements C, D {
+  T f;
+  U get g {}
+  void set s(int v) {}
+  int m(double v) {}
+}
+''');
+  }
+
+  test_mixin_implicitObjectSuperclassConstraint() async {
+    var library = await checkLibrary(r'''
+mixin M {}
+''');
+    checkElementText(library, r'''
+mixin M on Object {
+}
+''');
+  }
+
+  test_nameConflict_exportedAndLocal() async {
+    namesThatCannotBeResolved.add('V');
+    addLibrarySource('/a.dart', 'class C {}');
+    addLibrarySource('/c.dart', '''
+export 'a.dart';
+class C {}
+''');
+    var library = await checkLibrary('''
+import 'c.dart';
+C v = null;
+''');
+    checkElementText(library, r'''
+import 'c.dart';
+C v;
+''');
+  }
+
+  test_nameConflict_exportedAndLocal_exported() async {
+    namesThatCannotBeResolved.add('V');
+    addLibrarySource('/a.dart', 'class C {}');
+    addLibrarySource('/c.dart', '''
+export 'a.dart';
+class C {}
+''');
+    addLibrarySource('/d.dart', 'export "c.dart";');
+    var library = await checkLibrary('''
+import 'd.dart';
+C v = null;
+''');
+    checkElementText(library, r'''
+import 'd.dart';
+C v;
+''');
+  }
+
+  test_nameConflict_exportedAndParted() async {
+    namesThatCannotBeResolved.add('V');
+    addLibrarySource('/a.dart', 'class C {}');
+    addLibrarySource('/b.dart', '''
+part of lib;
+class C {}
+''');
+    addLibrarySource('/c.dart', '''
+library lib;
+export 'a.dart';
+part 'b.dart';
+''');
+    var library = await checkLibrary('''
+import 'c.dart';
+C v = null;
+''');
+    checkElementText(library, r'''
+import 'c.dart';
+C v;
+''');
+  }
+
+  test_nameConflict_importWithRelativeUri_exportWithAbsolute() async {
+    if (resourceProvider.pathContext.separator != '/') {
+      return;
+    }
+
+    addLibrarySource('/a.dart', 'class A {}');
+    addLibrarySource('/b.dart', 'export "/a.dart";');
+    var library = await checkLibrary('''
+import 'a.dart';
+import 'b.dart';
+A v = null;
+''');
+    checkElementText(library, r'''
+import 'a.dart';
+import 'b.dart';
+A v;
+''');
+  }
+
+  test_nested_generic_functions_in_generic_class_with_function_typed_params() async {
+    var library = await checkLibrary('''
+class C<T, U> {
+  void g<V, W>() {
+    void h<X, Y>(void p(T t, U u, V v, W w, X x, Y y)) {
+    }
+  }
+}
+''');
+    checkElementText(library, r'''
+class C<T, U> {
+  void g<V, W>() {}
+}
+''');
+  }
+
+  test_nested_generic_functions_in_generic_class_with_local_variables() async {
+    var library = await checkLibrary('''
+class C<T, U> {
+  void g<V, W>() {
+    void h<X, Y>() {
+      T t;
+      U u;
+      V v;
+      W w;
+      X x;
+      Y y;
+    }
+  }
+}
+''');
+    checkElementText(library, r'''
+class C<T, U> {
+  void g<V, W>() {}
+}
+''');
+  }
+
+  test_nested_generic_functions_with_function_typed_param() async {
+    var library = await checkLibrary('''
+void f<T, U>() {
+  void g<V, W>() {
+    void h<X, Y>(void p(T t, U u, V v, W w, X x, Y y)) {
+    }
+  }
+}
+''');
+    checkElementText(library, r'''
+void f<T, U>() {}
+''');
+  }
+
+  test_nested_generic_functions_with_local_variables() async {
+    var library = await checkLibrary('''
+void f<T, U>() {
+  void g<V, W>() {
+    void h<X, Y>() {
+      T t;
+      U u;
+      V v;
+      W w;
+      X x;
+      Y y;
+    }
+  }
+}
+''');
+    checkElementText(library, r'''
+void f<T, U>() {}
+''');
+  }
+
+  test_operator() async {
+    var library =
+        await checkLibrary('class C { C operator+(C other) => null; }');
+    checkElementText(library, r'''
+class C {
+  C +(C other) {}
+}
+''');
+  }
+
+  test_operator_equal() async {
+    var library = await checkLibrary('''
+class C {
+  bool operator==(Object other) => false;
+}
+''');
+    checkElementText(library, r'''
+class C {
+  bool ==(Object other) {}
+}
+''');
+  }
+
+  test_operator_external() async {
+    var library =
+        await checkLibrary('class C { external C operator+(C other); }');
+    checkElementText(library, r'''
+class C {
+  external C +(C other) {}
+}
+''');
+  }
+
+  test_operator_greater_equal() async {
+    var library = await checkLibrary('''
+class C {
+  bool operator>=(C other) => false;
+}
+''');
+    checkElementText(library, r'''
+class C {
+  bool >=(C other) {}
+}
+''');
+  }
+
+  test_operator_index() async {
+    var library =
+        await checkLibrary('class C { bool operator[](int i) => null; }');
+    checkElementText(library, r'''
+class C {
+  bool [](int i) {}
+}
+''');
+  }
+
+  test_operator_index_set() async {
+    var library = await checkLibrary('''
+class C {
+  void operator[]=(int i, bool v) {}
+}
+''');
+    checkElementText(library, r'''
+class C {
+  void []=(int i, bool v) {}
+}
+''');
+  }
+
+  test_operator_less_equal() async {
+    var library = await checkLibrary('''
+class C {
+  bool operator<=(C other) => false;
+}
+''');
+    checkElementText(library, r'''
+class C {
+  bool <=(C other) {}
+}
+''');
+  }
+
+  test_parameter() async {
+    var library = await checkLibrary('void main(int p) {}');
+    checkElementText(
+        library,
+        r'''
+void main@5(int p@14) {}
+''',
+        withOffsets: true);
+  }
+
+  test_parameter_checked() async {
+    // Note: due to dartbug.com/27393, the keyword "checked" is identified by
+    // its presence in a library called "meta".  If that bug is fixed, this test
+    // my need to be changed.
+    var library = await checkLibrary(r'''
+library meta;
+const checked = null;
+class A<T> {
+  void f(@checked T t) {}
+}
+''');
+    checkElementText(library, r'''
+library meta;
+class A<T> {
+  void f(@
+        checked/*location: test.dart;checked?*/ covariant T t) {}
+}
+const dynamic checked = null;
+''');
+  }
+
+  test_parameter_checked_inherited() async {
+    // Note: due to dartbug.com/27393, the keyword "checked" is identified by
+    // its presence in a library called "meta".  If that bug is fixed, this test
+    // my need to be changed.
+    var library = await checkLibrary(r'''
+library meta;
+const checked = null;
+class A<T> {
+  void f(@checked T t) {}
+}
+class B<T> extends A<T> {
+  void f(T t) {}
+}
+''');
+    checkElementText(library, r'''
+library meta;
+class A<T> {
+  void f(@
+        checked/*location: test.dart;checked?*/ covariant T t) {}
+}
+class B<T> extends A<T> {
+  void f(covariant T t) {}
+}
+const dynamic checked = null;
+''');
+  }
+
+  test_parameter_covariant() async {
+    var library = await checkLibrary('class C { void m(covariant C c) {} }');
+    checkElementText(library, r'''
+class C {
+  void m(covariant C c) {}
+}
+''');
+  }
+
+  test_parameter_covariant_inherited() async {
+    var library = await checkLibrary(r'''
+class A<T> {
+  void f(covariant T t) {}
+}
+class B<T> extends A<T> {
+  void f(T t) {}
+}
+''');
+    checkElementText(library, r'''
+class A<T> {
+  void f(covariant T t) {}
+}
+class B<T> extends A<T> {
+  void f(covariant T t) {}
+}
+''');
+  }
+
+  test_parameter_parameters() async {
+    var library = await checkLibrary('class C { f(g(x, y)) {} }');
+    checkElementText(library, r'''
+class C {
+  dynamic f((dynamic, dynamic) → dynamic g) {}
+}
+''');
+  }
+
+  test_parameter_parameters_in_generic_class() async {
+    var library = await checkLibrary('class C<A, B> { f(A g(B x)) {} }');
+    checkElementText(library, r'''
+class C<A, B> {
+  dynamic f((B) → A g) {}
+}
+''');
+  }
+
+  test_parameter_return_type() async {
+    var library = await checkLibrary('class C { f(int g()) {} }');
+    checkElementText(library, r'''
+class C {
+  dynamic f(() → int g) {}
+}
+''');
+  }
+
+  test_parameter_return_type_void() async {
+    var library = await checkLibrary('class C { f(void g()) {} }');
+    checkElementText(library, r'''
+class C {
+  dynamic f(() → void g) {}
+}
+''');
+  }
+
+  test_parameterTypeNotInferred_constructor() async {
+    // Strong mode doesn't do type inference on constructor parameters, so it's
+    // ok that we don't store inferred type info for them in summaries.
+    var library = await checkLibrary('''
+class C {
+  C.positional([x = 1]);
+  C.named({x: 1});
+}
+''');
+    checkElementText(library, r'''
+class C {
+  C.positional([dynamic x = 1]);
+  C.named({dynamic x: 1});
+}
+''');
+  }
+
+  test_parameterTypeNotInferred_initializingFormal() async {
+    // Strong mode doesn't do type inference on initializing formals, so it's
+    // ok that we don't store inferred type info for them in summaries.
+    var library = await checkLibrary('''
+class C {
+  var x;
+  C.positional([this.x = 1]);
+  C.named({this.x: 1});
+}
+''');
+    checkElementText(library, r'''
+class C {
+  dynamic x;
+  C.positional([dynamic this.x = 1]);
+  C.named({dynamic this.x: 1});
+}
+''');
+  }
+
+  test_parameterTypeNotInferred_staticMethod() async {
+    // Strong mode doesn't do type inference on parameters of static methods,
+    // so it's ok that we don't store inferred type info for them in summaries.
+    var library = await checkLibrary('''
+class C {
+  static void positional([x = 1]) {}
+  static void named({x: 1}) {}
+}
+''');
+    checkElementText(library, r'''
+class C {
+  static void positional([dynamic x = 1]) {}
+  static void named({dynamic x: 1}) {}
+}
+''');
+  }
+
+  test_parameterTypeNotInferred_topLevelFunction() async {
+    // Strong mode doesn't do type inference on parameters of top level
+    // functions, so it's ok that we don't store inferred type info for them in
+    // summaries.
+    var library = await checkLibrary('''
+void positional([x = 1]) {}
+void named({x: 1}) {}
+''');
+    checkElementText(library, r'''
+void positional([dynamic x = 1]) {}
+void named({dynamic x: 1}) {}
+''');
+  }
+
+  test_parts() async {
+    addSource('/a.dart', 'part of my.lib;');
+    addSource('/b.dart', 'part of my.lib;');
+    var library =
+        await checkLibrary('library my.lib; part "a.dart"; part "b.dart";');
+    checkElementText(library, r'''
+library my.lib;
+part 'a.dart';
+part 'b.dart';
+--------------------
+unit: a.dart
+
+--------------------
+unit: b.dart
+
+''');
+  }
+
+  test_parts_invalidUri() async {
+    allowMissingFiles = true;
+    shouldCompareLibraryElements = false;
+    addSource('/foo/bar.dart', 'part of my.lib;');
+    var library = await checkLibrary('library my.lib; part "foo/";');
+    checkElementText(library, r'''
+library my.lib;
+part '<unresolved>';
+--------------------
+unit: null
+
+''');
+  }
+
+  test_parts_invalidUri_nullStringValue() async {
+    allowMissingFiles = true;
+    shouldCompareLibraryElements = false;
+    addSource('/foo/bar.dart', 'part of my.lib;');
+    var library = await checkLibrary(r'''
+library my.lib;
+part "${foo}/bar.dart";
+''');
+    checkElementText(library, r'''
+library my.lib;
+part '<unresolved>';
+--------------------
+unit: null
+
+''');
+  }
+
+  test_propagated_type_refers_to_closure() async {
+    var library = await checkLibrary('''
+void f() {
+  var x = () => 0;
+  var y = x;
+}
+''');
+    checkElementText(library, r'''
+void f() {}
+''');
+  }
+
+  test_setter_covariant() async {
+    var library =
+        await checkLibrary('class C { void set x(covariant int value); }');
+    checkElementText(library, r'''
+class C {
+  void set x(covariant int value);
+}
+''');
+  }
+
+  test_setter_documented() async {
+    var library = await checkLibrary('''
+// Extra comment so doc comment offset != 0
+/**
+ * Docs
+ */
+void set x(value) {}''');
+    checkElementText(library, r'''
+/**
+ * Docs
+ */
+void set x(dynamic value) {}
+''');
+  }
+
+  test_setter_external() async {
+    var library = await checkLibrary('external void set x(int value);');
+    checkElementText(library, r'''
+external void set x(int value);
+''');
+  }
+
+  test_setter_inferred_type_conflictingInheritance() async {
+    var library = await checkLibrary('''
+class A {
+  int t;
+}
+class B extends A {
+  double t;
+}
+class C extends A implements B {
+}
+class D extends C {
+  void set t(p) {}
+}
+''');
+    checkElementText(library, r'''
+class A {
+  int t;
+}
+class B extends A {
+  double t;
+}
+class C extends A implements B {
+}
+class D extends C {
+  void set t(dynamic p) {}
+}
+''');
+  }
+
+  test_setter_inferred_type_nonStatic_implicit_param() async {
+    var library =
+        await checkLibrary('class C extends D { void set f(value) {} }'
+            ' abstract class D { void set f(int value); }');
+    checkElementText(library, r'''
+class C extends D {
+  void set f(int value) {}
+}
+abstract class D {
+  void set f(int value);
+}
+''');
+  }
+
+  test_setter_inferred_type_static_implicit_return() async {
+    var library = await checkLibrary('''
+class C {
+  static set f(int value) {}
+}
+''');
+    checkElementText(library, r'''
+class C {
+  static void set f(int value) {}
+}
+''');
+  }
+
+  test_setter_inferred_type_top_level_implicit_return() async {
+    var library = await checkLibrary('set f(int value) {}');
+    checkElementText(library, r'''
+void set f(int value) {}
+''');
+  }
+
+  test_setters() async {
+    var library =
+        await checkLibrary('void set x(int value) {} set y(value) {}');
+    checkElementText(library, r'''
+void set x(int value) {}
+void set y(dynamic value) {}
+''');
+  }
+
+  test_syntheticFunctionType_genericClosure() async {
+    var library = await checkLibrary('''
+final v = f() ? <T>(T t) => 0 : <T>(T t) => 1;
+bool f() => true;
+''');
+    checkElementText(library, r'''
+final (<bottom>) → int v;
+bool f() {}
+''');
+  }
+
+  test_syntheticFunctionType_genericClosure_inGenericFunction() async {
+    var library = await checkLibrary('''
+void f<T, U>(bool b) {
+  final v = b ? <V>(T t, U u, V v) => 0 : <V>(T t, U u, V v) => 1;
+}
+''');
+    checkElementText(library, r'''
+void f<T, U>(bool b) {}
+''');
+  }
+
+  test_syntheticFunctionType_inGenericClass() async {
+    var library = await checkLibrary('''
+class C<T, U> {
+  var v = f() ? (T t, U u) => 0 : (T t, U u) => 1;
+}
+bool f() => false;
+''');
+    checkElementText(library, r'''
+class C<T, U> {
+  (T, U) → int v;
+}
+bool f() {}
+''');
+  }
+
+  test_syntheticFunctionType_inGenericFunction() async {
+    var library = await checkLibrary('''
+void f<T, U>(bool b) {
+  var v = b ? (T t, U u) => 0 : (T t, U u) => 1;
+}
+''');
+    checkElementText(library, r'''
+void f<T, U>(bool b) {}
+''');
+  }
+
+  test_syntheticFunctionType_noArguments() async {
+    var library = await checkLibrary('''
+final v = f() ? () => 0 : () => 1;
+bool f() => true;
+''');
+    checkElementText(library, r'''
+final () → int v;
+bool f() {}
+''');
+  }
+
+  test_syntheticFunctionType_withArguments() async {
+    var library = await checkLibrary('''
+final v = f() ? (int x, String y) => 0 : (int x, String y) => 1;
+bool f() => true;
+''');
+    checkElementText(library, r'''
+final (int, String) → int v;
+bool f() {}
+''');
+  }
+
+  test_type_arguments_explicit_dynamic_dynamic() async {
+    var library = await checkLibrary('Map<dynamic, dynamic> m;');
+    checkElementText(library, r'''
+Map<dynamic, dynamic> m;
+''');
+  }
+
+  test_type_arguments_explicit_dynamic_int() async {
+    var library = await checkLibrary('Map<dynamic, int> m;');
+    checkElementText(library, r'''
+Map<dynamic, int> m;
+''');
+  }
+
+  test_type_arguments_explicit_String_dynamic() async {
+    var library = await checkLibrary('Map<String, dynamic> m;');
+    checkElementText(library, r'''
+Map<String, dynamic> m;
+''');
+  }
+
+  test_type_arguments_explicit_String_int() async {
+    var library = await checkLibrary('Map<String, int> m;');
+    checkElementText(library, r'''
+Map<String, int> m;
+''');
+  }
+
+  test_type_arguments_implicit() async {
+    var library = await checkLibrary('Map m;');
+    checkElementText(library, r'''
+Map<dynamic, dynamic> m;
+''');
+  }
+
+  test_type_dynamic() async {
+    var library = await checkLibrary('dynamic d;');
+    checkElementText(library, r'''
+dynamic d;
+''');
+  }
+
+  test_type_inference_based_on_loadLibrary() async {
+    addLibrarySource('/a.dart', '');
+    var library = await checkLibrary('''
+import 'a.dart' deferred as a;
+var x = a.loadLibrary;
+''');
+    checkElementText(library, '''
+import 'a.dart' deferred as a;
+() → Future<dynamic> x;
+''');
+  }
+
+  test_type_inference_closure_with_function_typed_parameter() async {
+    var library = await checkLibrary('''
+var x = (int f(String x)) => 0;
+''');
+    checkElementText(library, '''
+((String) → int) → int x;
+''');
+  }
+
+  test_type_inference_closure_with_function_typed_parameter_new() async {
+    var library = await checkLibrary('''
+var x = (int Function(String) f) => 0;
+''');
+    checkElementText(library, '''
+((String) → int) → int x;
+''');
+  }
+
+  test_type_inference_depends_on_exported_variable() async {
+    addLibrarySource('/a.dart', 'export "b.dart";');
+    addLibrarySource('/b.dart', 'var x = 0;');
+    var library = await checkLibrary('''
+import 'a.dart';
+var y = x;
+''');
+    checkElementText(library, '''
+import 'a.dart';
+int y;
+''');
+  }
+
+  test_type_inference_nested_function() async {
+    var library = await checkLibrary('''
+var x = (t) => (u) => t + u;
+''');
+    checkElementText(library, '''
+(dynamic) → (dynamic) → dynamic x;
+''');
+  }
+
+  test_type_inference_nested_function_with_parameter_types() async {
+    var library = await checkLibrary('''
+var x = (int t) => (int u) => t + u;
+''');
+    checkElementText(library, '''
+(int) → (int) → int x;
+''');
+  }
+
+  test_type_inference_of_closure_with_default_value() async {
+    var library = await checkLibrary('''
+var x = ([y: 0]) => y;
+''');
+    checkElementText(library, '''
+([dynamic]) → dynamic x;
+''');
+  }
+
+  test_type_invalid_topLevelVariableElement_asType() async {
+    var library = await checkLibrary('''
+class C<T extends V> {}
+typedef V F(V p);
+V f(V p) {}
+V V2 = null;
+int V = 0;
+''', allowErrors: true);
+    checkElementText(library, r'''
+typedef F = dynamic Function(dynamic p);
+class C<T extends dynamic> {
+}
+dynamic V2;
+int V;
+dynamic f(dynamic p) {}
+''');
+  }
+
+  test_type_invalid_topLevelVariableElement_asTypeArgument() async {
+    var library = await checkLibrary('''
+var V;
+static List<V> V2;
+''', allowErrors: true);
+    checkElementText(library, r'''
+dynamic V;
+List<dynamic> V2;
+''');
+  }
+
+  test_type_invalid_typeParameter_asPrefix() async {
+    var library = await checkLibrary('''
+class C<T> {
+  m(T.K p) {}
+}
+''', allowErrors: true);
+    checkElementText(library, r'''
+class C<T> {
+  dynamic m(dynamic p) {}
+}
+''');
+  }
+
+  test_type_reference_lib_to_lib() async {
+    var library = await checkLibrary('''
+class C {}
+enum E { v }
+typedef F();
+C c;
+E e;
+F f;''');
+    checkElementText(library, r'''
+typedef F = dynamic Function();
+enum E {
+  synthetic final int index;
+  synthetic static const List<E> values;
+  static const E v;
+  String toString() {}
+}
+class C {
+}
+C c;
+E e;
+() → dynamic f;
+''');
+  }
+
+  test_type_reference_lib_to_part() async {
+    addSource('/a.dart', 'part of l; class C {} enum E { v } typedef F();');
+    var library =
+        await checkLibrary('library l; part "a.dart"; C c; E e; F f;');
+    checkElementText(library, r'''
+library l;
+part 'a.dart';
+C c;
+E e;
+() → dynamic f;
+--------------------
+unit: a.dart
+
+typedef F = dynamic Function();
+enum E {
+  synthetic final int index;
+  synthetic static const List<E> values;
+  static const E v;
+  String toString() {}
+}
+class C {
+}
+''');
+  }
+
+  test_type_reference_part_to_lib() async {
+    addSource('/a.dart', 'part of l; C c; E e; F f;');
+    var library = await checkLibrary(
+        'library l; part "a.dart"; class C {} enum E { v } typedef F();');
+    checkElementText(library, r'''
+library l;
+part 'a.dart';
+typedef F = dynamic Function();
+enum E {
+  synthetic final int index;
+  synthetic static const List<E> values;
+  static const E v;
+  String toString() {}
+}
+class C {
+}
+--------------------
+unit: a.dart
+
+C c;
+E e;
+() → dynamic f;
+''');
+  }
+
+  test_type_reference_part_to_other_part() async {
+    addSource('/a.dart', 'part of l; class C {} enum E { v } typedef F();');
+    addSource('/b.dart', 'part of l; C c; E e; F f;');
+    var library =
+        await checkLibrary('library l; part "a.dart"; part "b.dart";');
+    checkElementText(library, r'''
+library l;
+part 'a.dart';
+part 'b.dart';
+--------------------
+unit: a.dart
+
+typedef F = dynamic Function();
+enum E {
+  synthetic final int index;
+  synthetic static const List<E> values;
+  static const E v;
+  String toString() {}
+}
+class C {
+}
+--------------------
+unit: b.dart
+
+C c;
+E e;
+() → dynamic f;
+''');
+  }
+
+  test_type_reference_part_to_part() async {
+    addSource('/a.dart',
+        'part of l; class C {} enum E { v } typedef F(); C c; E e; F f;');
+    var library = await checkLibrary('library l; part "a.dart";');
+    checkElementText(library, r'''
+library l;
+part 'a.dart';
+--------------------
+unit: a.dart
+
+typedef F = dynamic Function();
+enum E {
+  synthetic final int index;
+  synthetic static const List<E> values;
+  static const E v;
+  String toString() {}
+}
+class C {
+}
+C c;
+E e;
+() → dynamic f;
+''');
+  }
+
+  test_type_reference_to_class() async {
+    var library = await checkLibrary('class C {} C c;');
+    checkElementText(library, r'''
+class C {
+}
+C c;
+''');
+  }
+
+  test_type_reference_to_class_with_type_arguments() async {
+    var library = await checkLibrary('class C<T, U> {} C<int, String> c;');
+    checkElementText(library, r'''
+class C<T, U> {
+}
+C<int, String> c;
+''');
+  }
+
+  test_type_reference_to_class_with_type_arguments_implicit() async {
+    var library = await checkLibrary('class C<T, U> {} C c;');
+    checkElementText(library, r'''
+class C<T, U> {
+}
+C<dynamic, dynamic> c;
+''');
+  }
+
+  test_type_reference_to_enum() async {
+    var library = await checkLibrary('enum E { v } E e;');
+    checkElementText(library, r'''
+enum E {
+  synthetic final int index;
+  synthetic static const List<E> values;
+  static const E v;
+  String toString() {}
+}
+E e;
+''');
+  }
+
+  test_type_reference_to_import() async {
+    addLibrarySource('/a.dart', 'class C {} enum E { v } typedef F();');
+    var library = await checkLibrary('import "a.dart"; C c; E e; F f;');
+    checkElementText(library, r'''
+import 'a.dart';
+C c;
+E e;
+() → dynamic f;
+''');
+  }
+
+  test_type_reference_to_import_export() async {
+    addLibrarySource('/a.dart', 'export "b.dart";');
+    addLibrarySource('/b.dart', 'class C {} enum E { v } typedef F();');
+    var library = await checkLibrary('import "a.dart"; C c; E e; F f;');
+    checkElementText(library, r'''
+import 'a.dart';
+C c;
+E e;
+() → dynamic f;
+''');
+  }
+
+  test_type_reference_to_import_export_export() async {
+    addLibrarySource('/a.dart', 'export "b.dart";');
+    addLibrarySource('/b.dart', 'export "c.dart";');
+    addLibrarySource('/c.dart', 'class C {} enum E { v } typedef F();');
+    var library = await checkLibrary('import "a.dart"; C c; E e; F f;');
+    checkElementText(library, r'''
+import 'a.dart';
+C c;
+E e;
+() → dynamic f;
+''');
+  }
+
+  test_type_reference_to_import_export_export_in_subdirs() async {
+    addLibrarySource('/a/a.dart', 'export "b/b.dart";');
+    addLibrarySource('/a/b/b.dart', 'export "../c/c.dart";');
+    addLibrarySource('/a/c/c.dart', 'class C {} enum E { v } typedef F();');
+    var library = await checkLibrary('import "a/a.dart"; C c; E e; F f;');
+    checkElementText(library, r'''
+import 'a.dart';
+C c;
+E e;
+() → dynamic f;
+''');
+  }
+
+  test_type_reference_to_import_export_in_subdirs() async {
+    addLibrarySource('/a/a.dart', 'export "b/b.dart";');
+    addLibrarySource('/a/b/b.dart', 'class C {} enum E { v } typedef F();');
+    var library = await checkLibrary('import "a/a.dart"; C c; E e; F f;');
+    checkElementText(library, r'''
+import 'a.dart';
+C c;
+E e;
+() → dynamic f;
+''');
+  }
+
+  test_type_reference_to_import_part() async {
+    addLibrarySource('/a.dart', 'library l; part "b.dart";');
+    addSource('/b.dart', 'part of l; class C {} enum E { v } typedef F();');
+    var library = await checkLibrary('import "a.dart"; C c; E e; F f;');
+    checkElementText(library, r'''
+import 'a.dart';
+C c;
+E e;
+() → dynamic f;
+''');
+  }
+
+  test_type_reference_to_import_part2() async {
+    addLibrarySource('/a.dart', 'library l; part "p1.dart"; part "p2.dart";');
+    addSource('/p1.dart', 'part of l; class C1 {}');
+    addSource('/p2.dart', 'part of l; class C2 {}');
+    var library = await checkLibrary('import "a.dart"; C1 c1; C2 c2;');
+    checkElementText(library, r'''
+import 'a.dart';
+C1 c1;
+C2 c2;
+''');
+  }
+
+  test_type_reference_to_import_part_in_subdir() async {
+    addLibrarySource('/a/b.dart', 'library l; part "c.dart";');
+    addSource('/a/c.dart', 'part of l; class C {} enum E { v } typedef F();');
+    var library = await checkLibrary('import "a/b.dart"; C c; E e; F f;');
+    checkElementText(library, r'''
+import 'b.dart';
+C c;
+E e;
+() → dynamic f;
+''');
+  }
+
+  test_type_reference_to_import_relative() async {
+    addLibrarySource('/a.dart', 'class C {} enum E { v } typedef F();');
+    var library = await checkLibrary('import "a.dart"; C c; E e; F f;');
+    checkElementText(library, r'''
+import 'a.dart';
+C c;
+E e;
+() → dynamic f;
+''');
+  }
+
+  test_type_reference_to_typedef() async {
+    var library = await checkLibrary('typedef F(); F f;');
+    checkElementText(library, r'''
+typedef F = dynamic Function();
+() → dynamic f;
+''');
+  }
+
+  test_type_reference_to_typedef_with_type_arguments() async {
+    var library =
+        await checkLibrary('typedef U F<T, U>(T t); F<int, String> f;');
+    checkElementText(library, r'''
+typedef F<T, U> = U Function(T t);
+(int) → String f;
+''');
+  }
+
+  test_type_reference_to_typedef_with_type_arguments_implicit() async {
+    var library = await checkLibrary('typedef U F<T, U>(T t); F f;');
+    checkElementText(library, r'''
+typedef F<T, U> = U Function(T t);
+(dynamic) → dynamic f;
+''');
+  }
+
+  test_type_unresolved() async {
+    var library = await checkLibrary('C c;', allowErrors: true);
+    checkElementText(library, r'''
+dynamic c;
+''');
+  }
+
+  test_type_unresolved_prefixed() async {
+    var library = await checkLibrary('import "dart:core" as core; core.C c;',
+        allowErrors: true);
+    checkElementText(library, r'''
+import 'dart:core' as core;
+dynamic c;
+''');
+  }
+
+  test_typedef_documented() async {
+    var library = await checkLibrary('''
+// Extra comment so doc comment offset != 0
+/**
+ * Docs
+ */
+typedef F();''');
+    checkElementText(library, r'''
+/**
+ * Docs
+ */
+typedef F = dynamic Function();
+''');
+  }
+
+  test_typedef_generic() async {
+    var library = await checkLibrary(
+        'typedef F<T> = int Function<S>(List<S> list, num Function<A>(A), T);');
+    checkElementText(library, r'''
+typedef F<T> = int Function<S>(List<S> list, <A>(A) → num , T );
+''');
+  }
+
+  test_typedef_generic_asFieldType() async {
+    shouldCompareLibraryElements = false;
+    var library = await checkLibrary(r'''
+typedef Foo<S> = S Function<T>(T x);
+class A {
+  Foo<int> f;
+}
+''');
+    checkElementText(library, r'''
+typedef Foo<S> = S Function<T>(T x);
+class A {
+  <T>(T) → int f;
+}
+''');
+  }
+
+  test_typedef_parameter_parameters() async {
+    var library = await checkLibrary('typedef F(g(x, y));');
+    checkElementText(library, r'''
+typedef F = dynamic Function((dynamic, dynamic) → dynamic g);
+''');
+  }
+
+  test_typedef_parameter_parameters_in_generic_class() async {
+    var library = await checkLibrary('typedef F<A, B>(A g(B x));');
+    checkElementText(library, r'''
+typedef F<A, B> = dynamic Function((B) → A g);
+''');
+  }
+
+  test_typedef_parameter_return_type() async {
+    var library = await checkLibrary('typedef F(int g());');
+    checkElementText(library, r'''
+typedef F = dynamic Function(() → int g);
+''');
+  }
+
+  test_typedef_parameter_type() async {
+    var library = await checkLibrary('typedef F(int i);');
+    checkElementText(library, r'''
+typedef F = dynamic Function(int i);
+''');
+  }
+
+  test_typedef_parameter_type_generic() async {
+    var library = await checkLibrary('typedef F<T>(T t);');
+    checkElementText(library, r'''
+typedef F<T> = dynamic Function(T t);
+''');
+  }
+
+  test_typedef_parameters() async {
+    var library = await checkLibrary('typedef F(x, y);');
+    checkElementText(library, r'''
+typedef F = dynamic Function(dynamic x, dynamic y);
+''');
+  }
+
+  test_typedef_parameters_named() async {
+    var library = await checkLibrary('typedef F({y, z, x});');
+    checkElementText(library, r'''
+typedef F = dynamic Function({dynamic y}, {dynamic z}, {dynamic x});
+''');
+  }
+
+  test_typedef_return_type() async {
+    var library = await checkLibrary('typedef int F();');
+    checkElementText(library, r'''
+typedef F = int Function();
+''');
+  }
+
+  test_typedef_return_type_generic() async {
+    var library = await checkLibrary('typedef T F<T>();');
+    checkElementText(library, r'''
+typedef F<T> = T Function();
+''');
+  }
+
+  test_typedef_return_type_implicit() async {
+    var library = await checkLibrary('typedef F();');
+    checkElementText(library, r'''
+typedef F = dynamic Function();
+''');
+  }
+
+  test_typedef_return_type_void() async {
+    var library = await checkLibrary('typedef void F();');
+    checkElementText(library, r'''
+typedef F = void Function();
+''');
+  }
+
+  test_typedef_type_parameters() async {
+    var library = await checkLibrary('typedef U F<T, U>(T t);');
+    checkElementText(library, r'''
+typedef F<T, U> = U Function(T t);
+''');
+  }
+
+  test_typedef_type_parameters_bound() async {
+    var library = await checkLibrary(
+        'typedef U F<T extends Object, U extends D>(T t); class D {}');
+    checkElementText(library, r'''
+typedef F<T, U extends D> = U Function(T t);
+class D {
+}
+''');
+  }
+
+  test_typedef_type_parameters_bound_recursive() async {
+    shouldCompareLibraryElements = false;
+    var library = await checkLibrary('typedef void F<T extends F>();');
+    // Typedefs cannot reference themselves.
+    checkElementText(library, r'''
+typedef F<T extends () → void> = void Function();
+''');
+  }
+
+  test_typedef_type_parameters_bound_recursive2() async {
+    shouldCompareLibraryElements = false;
+    var library = await checkLibrary('typedef void F<T extends List<F>>();');
+    // Typedefs cannot reference themselves.
+    checkElementText(library, r'''
+typedef F<T extends List<() → void>> = void Function();
+''');
+  }
+
+  test_typedef_type_parameters_f_bound_complex() async {
+    var library = await checkLibrary('typedef U F<T extends List<U>, U>(T t);');
+    checkElementText(library, r'''
+typedef F<T extends List<U>, U> = U Function(T t);
+''');
+  }
+
+  test_typedef_type_parameters_f_bound_simple() async {
+    var library = await checkLibrary('typedef U F<T extends U, U>(T t);');
+    checkElementText(library, r'''
+typedef F<T extends U, U> = U Function(T t);
+''');
+  }
+
+  test_typedefs() async {
+    var library = await checkLibrary('f() {} g() {}');
+    checkElementText(library, r'''
+dynamic f() {}
+dynamic g() {}
+''');
+  }
+
+  @failingTest
+  test_unresolved_annotation_instanceCreation_argument_super() async {
+    // TODO(scheglov) fix https://github.com/dart-lang/sdk/issues/28553
+    var library = await checkLibrary('''
+class A {
+  const A(_);
+}
+
+@A(super)
+class C {}
+''', allowErrors: true);
+    checkElementText(library, r'''
+class A {
+  A(_);
+}
+
+class C {
+  synthetic C();
+}
+''');
+  }
+
+  test_unresolved_annotation_instanceCreation_argument_this() async {
+    shouldCompareLibraryElements = false;
+    var library = await checkLibrary('''
+class A {
+  const A(_);
+}
+
+@A(this)
+class C {}
+''', allowErrors: true);
+    checkElementText(library, r'''
+class A {
+  const A(dynamic _);
+}
+@#invalidConst
+class C {
+}
+''');
+  }
+
+  test_unresolved_annotation_namedConstructorCall_noClass() async {
+    shouldCompareLibraryElements = false;
+    var library =
+        await checkLibrary('@foo.bar() class C {}', allowErrors: true);
+    checkElementText(library, r'''
+@#invalidConst
+class C {
+}
+''');
+  }
+
+  test_unresolved_annotation_namedConstructorCall_noConstructor() async {
+    shouldCompareLibraryElements = false;
+    var library =
+        await checkLibrary('@String.foo() class C {}', allowErrors: true);
+    checkElementText(library, r'''
+@#invalidConst
+class C {
+}
+''');
+  }
+
+  test_unresolved_annotation_prefixedIdentifier_badPrefix() async {
+    shouldCompareLibraryElements = false;
+    var library = await checkLibrary('@foo.bar class C {}', allowErrors: true);
+    checkElementText(library, r'''
+@#invalidConst
+class C {
+}
+''');
+  }
+
+  test_unresolved_annotation_prefixedIdentifier_noDeclaration() async {
+    shouldCompareLibraryElements = false;
+    var library = await checkLibrary(
+        'import "dart:async" as foo; @foo.bar class C {}',
+        allowErrors: true);
+    checkElementText(library, r'''
+import 'dart:async' as foo;
+@#invalidConst
+class C {
+}
+''');
+  }
+
+  test_unresolved_annotation_prefixedNamedConstructorCall_badPrefix() async {
+    shouldCompareLibraryElements = false;
+    var library =
+        await checkLibrary('@foo.bar.baz() class C {}', allowErrors: true);
+    checkElementText(library, r'''
+@#invalidConst
+class C {
+}
+''');
+  }
+
+  test_unresolved_annotation_prefixedNamedConstructorCall_noClass() async {
+    shouldCompareLibraryElements = false;
+    var library = await checkLibrary(
+        'import "dart:async" as foo; @foo.bar.baz() class C {}',
+        allowErrors: true);
+    checkElementText(library, r'''
+import 'dart:async' as foo;
+@#invalidConst
+class C {
+}
+''');
+  }
+
+  test_unresolved_annotation_prefixedNamedConstructorCall_noConstructor() async {
+    shouldCompareLibraryElements = false;
+    var library = await checkLibrary(
+        'import "dart:async" as foo; @foo.Future.bar() class C {}',
+        allowErrors: true);
+    checkElementText(library, r'''
+import 'dart:async' as foo;
+@#invalidConst
+class C {
+}
+''');
+  }
+
+  test_unresolved_annotation_prefixedUnnamedConstructorCall_badPrefix() async {
+    shouldCompareLibraryElements = false;
+    var library =
+        await checkLibrary('@foo.bar() class C {}', allowErrors: true);
+    checkElementText(library, r'''
+@#invalidConst
+class C {
+}
+''');
+  }
+
+  test_unresolved_annotation_prefixedUnnamedConstructorCall_noClass() async {
+    shouldCompareLibraryElements = false;
+    var library = await checkLibrary(
+        'import "dart:async" as foo; @foo.bar() class C {}',
+        allowErrors: true);
+    checkElementText(library, r'''
+import 'dart:async' as foo;
+@#invalidConst
+class C {
+}
+''');
+  }
+
+  test_unresolved_annotation_simpleIdentifier() async {
+    shouldCompareLibraryElements = false;
+    var library = await checkLibrary('@foo class C {}', allowErrors: true);
+    checkElementText(library, r'''
+@#invalidConst
+class C {
+}
+''');
+  }
+
+  test_unresolved_annotation_unnamedConstructorCall_noClass() async {
+    shouldCompareLibraryElements = false;
+    var library = await checkLibrary('@foo() class C {}', allowErrors: true);
+    checkElementText(library, r'''
+@#invalidConst
+class C {
+}
+''');
+  }
+
+  test_unresolved_export() async {
+    allowMissingFiles = true;
+    var library = await checkLibrary("export 'foo.dart';", allowErrors: true);
+    checkElementText(library, r'''
+export 'foo.dart';
+''');
+  }
+
+  test_unresolved_import() async {
+    allowMissingFiles = true;
+    var library = await checkLibrary("import 'foo.dart';", allowErrors: true);
+    LibraryElement importedLibrary = library.imports[0].importedLibrary;
+    expect(importedLibrary.loadLibraryFunction, isNotNull);
+    expect(importedLibrary.publicNamespace, isNotNull);
+    expect(importedLibrary.exportNamespace, isNotNull);
+    checkElementText(library, r'''
+import 'foo.dart';
+''');
+  }
+
+  test_unresolved_part() async {
+    allowMissingFiles = true;
+    var library = await checkLibrary("part 'foo.dart';", allowErrors: true);
+    checkElementText(library, r'''
+part 'foo.dart';
+--------------------
+unit: foo.dart
+
+''');
+  }
+
+  test_unused_type_parameter() async {
+    shouldCompareLibraryElements = false;
+    var library = await checkLibrary('''
+class C<T> {
+  void f() {}
+}
+C<int> c;
+var v = c.f;
+''');
+    checkElementText(library, r'''
+class C<T> {
+  void f() {}
+}
+C<int> c;
+() → void v;
+''');
+  }
+
+  test_variable() async {
+    var library = await checkLibrary('int x = 0;');
+    checkElementText(
+        library,
+        r'''
+int x@4;
+synthetic int get x@4 {}
+synthetic void set x@4(int _x@4) {}
+''',
+        withOffsets: true,
+        withSyntheticAccessors: true);
+  }
+
+  test_variable_const() async {
+    var library = await checkLibrary('const int i = 0;');
+    checkElementText(library, r'''
+const int i = 0;
+''');
+  }
+
+  test_variable_documented() async {
+    var library = await checkLibrary('''
+// Extra comment so doc comment offset != 0
+/**
+ * Docs
+ */
+var x;''');
+    checkElementText(library, r'''
+/**
+ * Docs
+ */
+dynamic x;
+''');
+  }
+
+  test_variable_final() async {
+    var library = await checkLibrary('final int x = 0;');
+    checkElementText(library, r'''
+final int x;
+''');
+  }
+
+  test_variable_final_top_level_untyped() async {
+    var library = await checkLibrary('final v = 0;');
+    checkElementText(library, r'''
+final int v;
+''');
+  }
+
+  test_variable_getterInLib_setterInPart() async {
+    addSource('/a.dart', '''
+part of my.lib;
+void set x(int _) {}
+''');
+    var library = await checkLibrary('''
+library my.lib;
+part 'a.dart';
+int get x => 42;''');
+    checkElementText(library, r'''
+library my.lib;
+part 'a.dart';
+int get x {}
+--------------------
+unit: a.dart
+
+void set x(int _) {}
+''');
+  }
+
+  test_variable_getterInPart_setterInLib() async {
+    addSource('/a.dart', '''
+part of my.lib;
+int get x => 42;
+''');
+    var library = await checkLibrary('''
+library my.lib;
+part 'a.dart';
+void set x(int _) {}
+''');
+    checkElementText(library, r'''
+library my.lib;
+part 'a.dart';
+void set x(int _) {}
+--------------------
+unit: a.dart
+
+int get x {}
+''');
+  }
+
+  test_variable_getterInPart_setterInPart() async {
+    addSource('/a.dart', 'part of my.lib; int get x => 42;');
+    addSource('/b.dart', 'part of my.lib; void set x(int _) {}');
+    var library =
+        await checkLibrary('library my.lib; part "a.dart"; part "b.dart";');
+    checkElementText(library, r'''
+library my.lib;
+part 'a.dart';
+part 'b.dart';
+--------------------
+unit: a.dart
+
+int get x {}
+--------------------
+unit: b.dart
+
+void set x(int _) {}
+''');
+  }
+
+  test_variable_implicit_type() async {
+    var library = await checkLibrary('var x;');
+    checkElementText(library, r'''
+dynamic x;
+''');
+  }
+
+  test_variable_inferred_type_implicit_initialized() async {
+    var library = await checkLibrary('var v = 0;');
+    checkElementText(library, r'''
+int v;
+''');
+  }
+
+  test_variable_propagatedType_const_noDep() async {
+    var library = await checkLibrary('const i = 0;');
+    checkElementText(library, r'''
+const int i = 0;
+''');
+  }
+
+  test_variable_propagatedType_final_dep_inLib() async {
+    addLibrarySource('/a.dart', 'final a = 1;');
+    var library = await checkLibrary('import "a.dart"; final b = a / 2;');
+    checkElementText(library, r'''
+import 'a.dart';
+final double b;
+''');
+  }
+
+  test_variable_propagatedType_final_dep_inPart() async {
+    addSource('/a.dart', 'part of lib; final a = 1;');
+    var library =
+        await checkLibrary('library lib; part "a.dart"; final b = a / 2;');
+    checkElementText(library, r'''
+library lib;
+part 'a.dart';
+final double b;
+--------------------
+unit: a.dart
+
+final int a;
+''');
+  }
+
+  test_variable_propagatedType_final_noDep() async {
+    var library = await checkLibrary('final i = 0;');
+    checkElementText(library, r'''
+final int i;
+''');
+  }
+
+  test_variable_propagatedType_implicit_dep() async {
+    // The propagated type is defined in a library that is not imported.
+    addLibrarySource('/a.dart', 'class C {}');
+    addLibrarySource('/b.dart', 'import "a.dart"; C f() => null;');
+    var library = await checkLibrary('import "b.dart"; final x = f();');
+    checkElementText(library, r'''
+import 'b.dart';
+final C x;
+''');
+  }
+
+  test_variable_setterInPart_getterInPart() async {
+    addSource('/a.dart', 'part of my.lib; void set x(int _) {}');
+    addSource('/b.dart', 'part of my.lib; int get x => 42;');
+    var library =
+        await checkLibrary('library my.lib; part "a.dart"; part "b.dart";');
+    checkElementText(library, r'''
+library my.lib;
+part 'a.dart';
+part 'b.dart';
+--------------------
+unit: a.dart
+
+void set x(int _) {}
+--------------------
+unit: b.dart
+
+int get x {}
+''');
+  }
+
+  test_variables() async {
+    var library = await checkLibrary('int i; int j;');
+    checkElementText(library, r'''
+int i;
+int j;
+''');
+  }
+
+  /**
+   * Encode the library containing [original] into a summary and then use
+   * [TestSummaryResynthesizer.getElement] to retrieve just the original
+   * element from the resynthesized summary.
+   */
+  Element _validateGetElement(String text, Element original) {
+    SummaryResynthesizer resynthesizer = encodeLibrary(original.library.source);
+    ElementLocationImpl location = original.location;
+    Element result = resynthesizer.getElement(location);
+    checkMinimalResynthesisWork(resynthesizer, original.library);
+    // Check that no other summaries needed to be resynthesized to resynthesize
+    // the library element.
+    expect(resynthesizer.resynthesisCount, 3);
+    expect(result.location, location);
+    return result;
+  }
+}
+
+/// Mixin containing helper methods for testing summary resynthesis.  Intended
+/// to be applied to a class implementing [ResynthesizeTestStrategy].
+abstract class ResynthesizeTestHelpers implements ResynthesizeTestStrategy {
+  /**
+   * Names of variables which have initializers that are not valid constants,
+   * so they are not resynthesized.
+   */
+  final variablesWithNotConstInitializers = Set<String>();
+
+  /**
+   * Tests may set this to `false` to indicate that resynthesized elements
+   * should not be compare with elements created using AnalysisContext.
+   */
+  bool shouldCompareLibraryElements = true;
+
+  /**
+   * Names that cannot be resolved, e.g. because of duplicate declaration.
+   */
+  final namesThatCannotBeResolved = Set<String>();
+
+  /**
    * Verify that the given prefix is safe to elide from a resynthesized AST.
    */
   void checkElidablePrefix(SimpleIdentifier prefix) {
@@ -118,6 +8737,23 @@
     }
   }
 
+  Future<LibraryElementImpl> checkLibrary(String text,
+      {bool allowErrors: false, bool dumpSummaries: false}) async {
+    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');
+      }
+    }
+    if (shouldCompareLibraryElements) {
+      checkLibraryElements(original, resynthesized);
+    }
+    return resynthesized;
+  }
+
   void checkLibraryElements(
       LibraryElementImpl original, LibraryElementImpl resynthesized) {
     compareElements(resynthesized, original, '(library)');
@@ -168,29 +8804,6 @@
     expect(resynthesized.libraryCycle.toSet(), original.libraryCycle.toSet());
   }
 
-  /**
-   * Verify that the [resynthesizer] didn't do any unnecessary work when
-   * resynthesizing [library].
-   */
-  void checkMinimalResynthesisWork(
-      TestSummaryResynthesizer resynthesizer, LibraryElement library) {
-    // Check that no other summaries needed to be resynthesized to resynthesize
-    // the library element.
-    expect(resynthesizer.resynthesisCount, 3);
-    // Check that the only linked summary consulted was that for [uri].
-    expect(resynthesizer.linkedSummariesRequested, hasLength(1));
-    expect(resynthesizer.linkedSummariesRequested.first,
-        library.source.uri.toString());
-    // Check that the only unlinked summaries consulted were those for the
-    // library in question.
-    Set<String> expectedCompilationUnitUris = library.units
-        .map((CompilationUnitElement unit) => unit.source.uri.toString())
-        .toSet();
-    for (String requestedUri in resynthesizer.unlinkedSummariesRequested) {
-      expect(expectedCompilationUnitUris, contains(requestedUri));
-    }
-  }
-
   void checkPossibleLocalElements(Element resynthesized, Element original) {
     if (original is! LocalElement && resynthesized is! LocalElement) {
       return;
@@ -1193,13 +9806,6 @@
     checkPossibleLocalElements(resynthesized, original);
   }
 
-  DartSdk createDartSdk() => AbstractContextTest.SHARED_MOCK_SDK;
-
-  /**
-   * Create the analysis options that should be used for this test.
-   */
-  AnalysisOptionsImpl createOptions() => new AnalysisOptionsImpl();
-
   ElementImpl getActualElement(Element element, String desc) {
     if (element == null) {
       return null;
@@ -1238,10 +9844,9 @@
     }
   }
 
-  @override
-  void setUp() {
-    super.setUp();
-    prepareAnalysisContext(createOptions());
+  LibraryElementImpl _encodeDecodeLibraryElement(Source source) {
+    SummaryResynthesizer resynthesizer = encodeLibrary(source);
+    return resynthesizer.getLibraryElement(source.uri.toString());
   }
 
   List<PropertyAccessorElement> _getSortedPropertyAccessors(
@@ -1350,10037 +9955,6 @@
   }
 }
 
-@reflectiveTest
-abstract class ResynthesizeTest extends AbstractResynthesizeTest {
-  Future<LibraryElementImpl> checkLibrary(String text,
-      {bool allowErrors: false, bool dumpSummaries: false});
-
-  test_class_abstract() async {
-    var library = await checkLibrary('abstract class C {}');
-    checkElementText(library, r'''
-abstract class C {
-}
-''');
-  }
-
-  test_class_alias() async {
-    var library = await checkLibrary('''
-class C = D with E, F, G;
-class D {}
-class E {}
-class F {}
-class G {}
-''');
-    checkElementText(library, r'''
-class alias C extends D with E, F, G {
-  synthetic C() = D;
-}
-class D {
-}
-class E {
-}
-class F {
-}
-class G {
-}
-''');
-  }
-
-  test_class_alias_abstract() async {
-    var library = await checkLibrary('''
-abstract class C = D with E;
-class D {}
-class E {}
-''');
-    checkElementText(library, r'''
-abstract class alias C extends D with E {
-  synthetic C() = D;
-}
-class D {
-}
-class E {
-}
-''');
-  }
-
-  test_class_alias_documented() async {
-    var library = await checkLibrary('''
-/**
- * Docs
- */
-class C = D with E;
-
-class D {}
-class E {}
-''');
-    checkElementText(library, r'''
-/**
- * Docs
- */
-class alias C extends D with E {
-  synthetic C() = D;
-}
-class D {
-}
-class E {
-}
-''');
-  }
-
-  test_class_alias_documented_tripleSlash() async {
-    var library = await checkLibrary('''
-/// aaa
-/// b
-/// cc
-class C = D with E;
-
-class D {}
-class E {}
-''');
-    checkElementText(library, r'''
-/// aaa
-/// b
-/// cc
-class alias C extends D with E {
-  synthetic C() = D;
-}
-class D {
-}
-class E {
-}
-''');
-  }
-
-  test_class_alias_documented_withLeadingNonDocumentation() async {
-    var library = await checkLibrary('''
-// Extra comment so doc comment offset != 0
-/**
- * Docs
- */
-class C = D with E;
-
-class D {}
-class E {}''');
-    checkElementText(library, r'''
-/**
- * Docs
- */
-class alias C extends D with E {
-  synthetic C() = D;
-}
-class D {
-}
-class E {
-}
-''');
-  }
-
-  test_class_alias_generic() async {
-    var library = await checkLibrary('''
-class Z = A with B<int>, C<double>;
-class A {}
-class B<B1> {}
-class C<C1> {}
-''');
-    checkElementText(library, r'''
-class alias Z extends A with B<int>, C<double> {
-  synthetic Z() = A;
-}
-class A {
-}
-class B<B1> {
-}
-class C<C1> {
-}
-''');
-  }
-
-  test_class_alias_with_forwarding_constructors() async {
-    addLibrarySource('/a.dart', '''
-class Base {
-  Base._priv();
-  Base();
-  Base.noArgs();
-  Base.requiredArg(x);
-  Base.positionalArg([x]);
-  Base.namedArg({x});
-  factory Base.fact() => null;
-  factory Base.fact2() = Base.noArgs;
-}
-''');
-    var library = await checkLibrary('''
-import "a.dart";
-class M {}
-class MixinApp = Base with M;
-''');
-    checkElementText(library, r'''
-import 'a.dart';
-class M {
-}
-class alias MixinApp extends Base with M {
-  synthetic MixinApp() = Base;
-  synthetic MixinApp.noArgs() = Base.noArgs;
-  synthetic MixinApp.requiredArg(dynamic x) = Base.requiredArg;
-  synthetic MixinApp.fact() = Base.fact;
-  synthetic MixinApp.fact2() = Base.fact2;
-}
-''');
-  }
-
-  test_class_alias_with_forwarding_constructors_type_substitution() async {
-    var library = await checkLibrary('''
-class Base<T> {
-  Base.ctor(T t, List<T> l);
-}
-class M {}
-class MixinApp = Base with M;
-''');
-    checkElementText(library, r'''
-class Base<T> {
-  Base.ctor(T t, List<T> l);
-}
-class M {
-}
-class alias MixinApp extends Base<dynamic> with M {
-  synthetic MixinApp.ctor(dynamic t, List<dynamic> l) = Base<T>.ctor;
-}
-''');
-  }
-
-  test_class_alias_with_forwarding_constructors_type_substitution_complex() async {
-    var library = await checkLibrary('''
-class Base<T> {
-  Base.ctor(T t, List<T> l);
-}
-class M {}
-class MixinApp<U> = Base<List<U>> with M;
-''');
-    checkElementText(library, r'''
-class Base<T> {
-  Base.ctor(T t, List<T> l);
-}
-class M {
-}
-class alias MixinApp<U> extends Base<List<U>> with M {
-  synthetic MixinApp.ctor(List<U> t, List<List<U>> l) = Base<T>.ctor;
-}
-''');
-  }
-
-  test_class_alias_with_mixin_members() async {
-    var library = await checkLibrary('''
-class C = D with E;
-class D {}
-class E {
-  int get a => null;
-  void set b(int i) {}
-  void f() {}
-  int x;
-}''');
-    checkElementText(library, r'''
-class alias C extends D with E {
-  synthetic C() = D;
-}
-class D {
-}
-class E {
-  int x;
-  int get a {}
-  void set b(int i) {}
-  void f() {}
-}
-''');
-  }
-
-  test_class_constructor_const() async {
-    var library = await checkLibrary('class C { const C(); }');
-    checkElementText(library, r'''
-class C {
-  const C();
-}
-''');
-  }
-
-  test_class_constructor_const_external() async {
-    var library = await checkLibrary('class C { external const C(); }');
-    checkElementText(library, r'''
-class C {
-  external const C();
-}
-''');
-  }
-
-  test_class_constructor_explicit_named() async {
-    var library = await checkLibrary('class C { C.foo(); }');
-    checkElementText(library, r'''
-class C {
-  C.foo();
-}
-''');
-  }
-
-  test_class_constructor_explicit_type_params() async {
-    var library = await checkLibrary('class C<T, U> { C(); }');
-    checkElementText(library, r'''
-class C<T, U> {
-  C();
-}
-''');
-  }
-
-  test_class_constructor_explicit_unnamed() async {
-    var library = await checkLibrary('class C { C(); }');
-    checkElementText(library, r'''
-class C {
-  C();
-}
-''');
-  }
-
-  test_class_constructor_external() async {
-    var library = await checkLibrary('class C { external C(); }');
-    checkElementText(library, r'''
-class C {
-  external C();
-}
-''');
-  }
-
-  test_class_constructor_factory() async {
-    var library = await checkLibrary('class C { factory C() => null; }');
-    checkElementText(library, r'''
-class C {
-  factory C();
-}
-''');
-  }
-
-  test_class_constructor_field_formal_dynamic_dynamic() async {
-    var library =
-        await checkLibrary('class C { dynamic x; C(dynamic this.x); }');
-    checkElementText(library, r'''
-class C {
-  dynamic x;
-  C(dynamic this.x);
-}
-''');
-  }
-
-  test_class_constructor_field_formal_dynamic_typed() async {
-    var library = await checkLibrary('class C { dynamic x; C(int this.x); }');
-    checkElementText(library, r'''
-class C {
-  dynamic x;
-  C(int this.x);
-}
-''');
-  }
-
-  test_class_constructor_field_formal_dynamic_untyped() async {
-    var library = await checkLibrary('class C { dynamic x; C(this.x); }');
-    checkElementText(library, r'''
-class C {
-  dynamic x;
-  C(dynamic this.x);
-}
-''');
-  }
-
-  test_class_constructor_field_formal_multiple_matching_fields() async {
-    // This is a compile-time error but it should still analyze consistently.
-    var library = await checkLibrary('class C { C(this.x); int x; String x; }',
-        allowErrors: true);
-    checkElementText(library, r'''
-class C {
-  int x;
-  String x;
-  C(int this.x);
-}
-''');
-  }
-
-  test_class_constructor_field_formal_no_matching_field() async {
-    // This is a compile-time error but it should still analyze consistently.
-    var library =
-        await checkLibrary('class C { C(this.x); }', allowErrors: true);
-    checkElementText(library, r'''
-class C {
-  C(dynamic this.x);
-}
-''');
-  }
-
-  test_class_constructor_field_formal_typed_dynamic() async {
-    var library = await checkLibrary('class C { num x; C(dynamic this.x); }',
-        allowErrors: true);
-    checkElementText(library, r'''
-class C {
-  num x;
-  C(dynamic this.x);
-}
-''');
-  }
-
-  test_class_constructor_field_formal_typed_typed() async {
-    var library = await checkLibrary('class C { num x; C(int this.x); }');
-    checkElementText(library, r'''
-class C {
-  num x;
-  C(int this.x);
-}
-''');
-  }
-
-  test_class_constructor_field_formal_typed_untyped() async {
-    var library = await checkLibrary('class C { num x; C(this.x); }');
-    checkElementText(library, r'''
-class C {
-  num x;
-  C(num this.x);
-}
-''');
-  }
-
-  test_class_constructor_field_formal_untyped_dynamic() async {
-    var library = await checkLibrary('class C { var x; C(dynamic this.x); }');
-    checkElementText(library, r'''
-class C {
-  dynamic x;
-  C(dynamic this.x);
-}
-''');
-  }
-
-  test_class_constructor_field_formal_untyped_typed() async {
-    var library = await checkLibrary('class C { var x; C(int this.x); }');
-    checkElementText(library, r'''
-class C {
-  dynamic x;
-  C(int this.x);
-}
-''');
-  }
-
-  test_class_constructor_field_formal_untyped_untyped() async {
-    var library = await checkLibrary('class C { var x; C(this.x); }');
-    checkElementText(library, r'''
-class C {
-  dynamic x;
-  C(dynamic this.x);
-}
-''');
-  }
-
-  test_class_constructor_fieldFormal_named_noDefault() async {
-    var library = await checkLibrary('class C { int x; C({this.x}); }');
-    checkElementText(library, r'''
-class C {
-  int x;
-  C({int this.x});
-}
-''');
-  }
-
-  test_class_constructor_fieldFormal_named_withDefault() async {
-    var library = await checkLibrary('class C { int x; C({this.x: 42}); }');
-    checkElementText(library, r'''
-class C {
-  int x;
-  C({int this.x: 42});
-}
-''');
-  }
-
-  test_class_constructor_fieldFormal_optional_noDefault() async {
-    var library = await checkLibrary('class C { int x; C([this.x]); }');
-    checkElementText(library, r'''
-class C {
-  int x;
-  C([int this.x]);
-}
-''');
-  }
-
-  test_class_constructor_fieldFormal_optional_withDefault() async {
-    var library = await checkLibrary('class C { int x; C([this.x = 42]); }');
-    checkElementText(library, r'''
-class C {
-  int x;
-  C([int this.x = 42]);
-}
-''');
-  }
-
-  test_class_constructor_implicit() async {
-    var library = await checkLibrary('class C {}');
-    checkElementText(library, r'''
-class C {
-}
-''');
-  }
-
-  test_class_constructor_implicit_type_params() async {
-    var library = await checkLibrary('class C<T, U> {}');
-    checkElementText(library, r'''
-class C<T, U> {
-}
-''');
-  }
-
-  test_class_constructor_params() async {
-    var library = await checkLibrary('class C { C(x, int y); }');
-    checkElementText(library, r'''
-class C {
-  C(dynamic x, int y);
-}
-''');
-  }
-
-  test_class_constructors() async {
-    var library = await checkLibrary('class C { C.foo(); C.bar(); }');
-    checkElementText(library, r'''
-class C {
-  C.foo();
-  C.bar();
-}
-''');
-  }
-
-  test_class_documented() async {
-    var library = await checkLibrary('''
-/**
- * Docs
- */
-class C {}''');
-    checkElementText(library, r'''
-/**
- * Docs
- */
-class C {
-}
-''');
-  }
-
-  test_class_documented_mix() async {
-    var library = await checkLibrary('''
-/**
- * aaa
- */
-/**
- * bbb
- */
-class A {}
-
-/**
- * aaa
- */
-/// bbb
-/// ccc
-class B {}
-
-/// aaa
-/// bbb
-/**
- * ccc
- */
-class C {}
-
-/// aaa
-/// bbb
-/**
- * ccc
- */
-/// ddd
-class D {}
-
-/**
- * aaa
- */
-// bbb
-class E {}
-''');
-    checkElementText(library, r'''
-/**
- * bbb
- */
-class A {
-}
-/// bbb
-/// ccc
-class B {
-}
-/**
- * ccc
- */
-class C {
-}
-/// ddd
-class D {
-}
-/**
- * aaa
- */
-class E {
-}
-''');
-  }
-
-  test_class_documented_tripleSlash() async {
-    var library = await checkLibrary('''
-/// aaa
-/// bbbb
-/// cc
-class C {}''');
-    checkElementText(library, r'''
-/// aaa
-/// bbbb
-/// cc
-class C {
-}
-''');
-  }
-
-  test_class_documented_with_references() async {
-    var library = await checkLibrary('''
-/**
- * Docs referring to [D] and [E]
- */
-class C {}
-
-class D {}
-class E {}''');
-    checkElementText(library, r'''
-/**
- * Docs referring to [D] and [E]
- */
-class C {
-}
-class D {
-}
-class E {
-}
-''');
-  }
-
-  test_class_documented_with_windows_line_endings() async {
-    var library = await checkLibrary('/**\r\n * Docs\r\n */\r\nclass C {}');
-    checkElementText(library, r'''
-/**
- * Docs
- */
-class C {
-}
-''');
-  }
-
-  test_class_documented_withLeadingNotDocumentation() async {
-    var library = await checkLibrary('''
-// Extra comment so doc comment offset != 0
-/**
- * Docs
- */
-class C {}''');
-    checkElementText(library, r'''
-/**
- * Docs
- */
-class C {
-}
-''');
-  }
-
-  test_class_documented_withMetadata() async {
-    var library = await checkLibrary('''
-/// Comment 1
-/// Comment 2
-@Annotation()
-class BeforeMeta {}
-
-/// Comment 1
-/// Comment 2
-@Annotation.named()
-class BeforeMetaNamed {}
-
-@Annotation()
-/// Comment 1
-/// Comment 2
-class AfterMeta {}
-
-/// Comment 1
-@Annotation()
-/// Comment 2
-class AroundMeta {}
-
-/// Doc comment.
-@Annotation()
-// Not doc comment.
-class DocBeforeMetaNotDocAfter {}
-
-class Annotation {
-  const Annotation();
-  const Annotation.named();
-}
-''');
-    checkElementText(
-        library,
-        r'''
-/// Comment 1
-/// Comment 2
-@Annotation()
-class BeforeMeta {
-}
-/// Comment 1
-/// Comment 2
-@Annotation.named()
-class BeforeMetaNamed {
-}
-/// Comment 1
-/// Comment 2
-@Annotation()
-class AfterMeta {
-}
-/// Comment 2
-@Annotation()
-class AroundMeta {
-}
-/// Doc comment.
-@Annotation()
-class DocBeforeMetaNotDocAfter {
-}
-class Annotation {
-  const Annotation();
-  const Annotation.named();
-}
-''',
-        withConstElements: false);
-  }
-
-  test_class_field_const() async {
-    var library = await checkLibrary('class C { static const int i = 0; }');
-    checkElementText(library, r'''
-class C {
-  static const int i = 0;
-}
-''');
-  }
-
-  test_class_field_implicit_type() async {
-    var library = await checkLibrary('class C { var x; }');
-    checkElementText(library, r'''
-class C {
-  dynamic x;
-}
-''');
-  }
-
-  test_class_field_static() async {
-    var library = await checkLibrary('class C { static int i; }');
-    checkElementText(library, r'''
-class C {
-  static int i;
-}
-''');
-  }
-
-  test_class_fields() async {
-    var library = await checkLibrary('class C { int i; int j; }');
-    checkElementText(library, r'''
-class C {
-  int i;
-  int j;
-}
-''');
-  }
-
-  test_class_getter_abstract() async {
-    var library = await checkLibrary('abstract class C { int get x; }');
-    checkElementText(library, r'''
-abstract class C {
-  int get x;
-}
-''');
-  }
-
-  test_class_getter_external() async {
-    var library = await checkLibrary('class C { external int get x; }');
-    checkElementText(library, r'''
-class C {
-  external int get x;
-}
-''');
-  }
-
-  test_class_getter_implicit_return_type() async {
-    var library = await checkLibrary('class C { get x => null; }');
-    checkElementText(library, r'''
-class C {
-  dynamic get x {}
-}
-''');
-  }
-
-  test_class_getter_static() async {
-    var library = await checkLibrary('class C { static int get x => null; }');
-    checkElementText(library, r'''
-class C {
-  static int get x {}
-}
-''');
-  }
-
-  test_class_getters() async {
-    var library =
-        await checkLibrary('class C { int get x => null; get y => null; }');
-    checkElementText(library, r'''
-class C {
-  int get x {}
-  dynamic get y {}
-}
-''');
-  }
-
-  test_class_implicitField_getterFirst() async {
-    var library = await checkLibrary('''
-class C {
-  int get x => 0;
-  void set x(int value) {} 
-}
-''');
-    checkElementText(library, r'''
-class C {
-  int get x {}
-  void set x(int value) {}
-}
-''');
-  }
-
-  test_class_implicitField_setterFirst() async {
-    var library = await checkLibrary('''
-class C {
-  void set x(int value) {}
-  int get x => 0;
-}
-''');
-    checkElementText(library, r'''
-class C {
-  void set x(int value) {}
-  int get x {}
-}
-''');
-  }
-
-  test_class_interfaces() async {
-    var library = await checkLibrary('''
-class C implements D, E {}
-class D {}
-class E {}
-''');
-    checkElementText(library, r'''
-class C implements D, E {
-}
-class D {
-}
-class E {
-}
-''');
-  }
-
-  test_class_interfaces_unresolved() async {
-    var library = await checkLibrary(
-        'class C implements X, Y, Z {} class X {} class Z {}',
-        allowErrors: true);
-    checkElementText(library, r'''
-class C implements X, Z {
-}
-class X {
-}
-class Z {
-}
-''');
-  }
-
-  test_class_method_abstract() async {
-    var library = await checkLibrary('abstract class C { f(); }');
-    checkElementText(library, r'''
-abstract class C {
-  dynamic f();
-}
-''');
-  }
-
-  test_class_method_external() async {
-    var library = await checkLibrary('class C { external f(); }');
-    checkElementText(library, r'''
-class C {
-  external dynamic f() {}
-}
-''');
-  }
-
-  test_class_method_params() async {
-    var library = await checkLibrary('class C { f(x, y) {} }');
-    checkElementText(library, r'''
-class C {
-  dynamic f(dynamic x, dynamic y) {}
-}
-''');
-  }
-
-  test_class_method_static() async {
-    var library = await checkLibrary('class C { static f() {} }');
-    checkElementText(library, r'''
-class C {
-  static dynamic f() {}
-}
-''');
-  }
-
-  test_class_methods() async {
-    var library = await checkLibrary('class C { f() {} g() {} }');
-    checkElementText(library, r'''
-class C {
-  dynamic f() {}
-  dynamic g() {}
-}
-''');
-  }
-
-  test_class_mixins() async {
-    var library = await checkLibrary('''
-class C extends D with E, F, G {}
-class D {}
-class E {}
-class F {}
-class G {}
-''');
-    checkElementText(library, r'''
-class C extends D with E, F, G {
-  synthetic C();
-}
-class D {
-}
-class E {
-}
-class F {
-}
-class G {
-}
-''');
-  }
-
-  test_class_mixins_generic() async {
-    var library = await checkLibrary('''
-class Z extends A with B<int>, C<double> {}
-class A {}
-class B<B1> {}
-class C<C1> {}
-''');
-    checkElementText(library, r'''
-class Z extends A with B<int>, C<double> {
-  synthetic Z();
-}
-class A {
-}
-class B<B1> {
-}
-class C<C1> {
-}
-''');
-  }
-
-  test_class_mixins_unresolved() async {
-    var library = await checkLibrary(
-        'class C extends Object with X, Y, Z {} class X {} class Z {}',
-        allowErrors: true);
-    checkElementText(library, r'''
-class C extends Object with X, Z {
-  synthetic C();
-}
-class X {
-}
-class Z {
-}
-''');
-  }
-
-  test_class_setter_abstract() async {
-    var library =
-        await checkLibrary('abstract class C { void set x(int value); }');
-    checkElementText(library, r'''
-abstract class C {
-  void set x(int value);
-}
-''');
-  }
-
-  test_class_setter_external() async {
-    var library =
-        await checkLibrary('class C { external void set x(int value); }');
-    checkElementText(library, r'''
-class C {
-  external void set x(int value);
-}
-''');
-  }
-
-  test_class_setter_implicit_param_type() async {
-    var library = await checkLibrary('class C { void set x(value) {} }');
-    checkElementText(library, r'''
-class C {
-  void set x(dynamic value) {}
-}
-''');
-  }
-
-  test_class_setter_implicit_return_type() async {
-    var library = await checkLibrary('class C { set x(int value) {} }');
-    if (isStrongMode) {
-      checkElementText(library, r'''
-class C {
-  void set x(int value) {}
-}
-''');
-    } else {
-      checkElementText(library, r'''
-class C {
-  dynamic set x(int value) {}
-}
-''');
-    }
-  }
-
-  test_class_setter_invalid_named_parameter() async {
-    var library = await checkLibrary('class C { void set x({a}) {} }');
-    checkElementText(library, r'''
-class C {
-  void set x({dynamic a}) {}
-}
-''');
-  }
-
-  test_class_setter_invalid_no_parameter() async {
-    var library = await checkLibrary('class C { void set x() {} }');
-    checkElementText(library, r'''
-class C {
-  void set x() {}
-}
-''');
-  }
-
-  test_class_setter_invalid_optional_parameter() async {
-    var library = await checkLibrary('class C { void set x([a]) {} }');
-    checkElementText(library, r'''
-class C {
-  void set x([dynamic a]) {}
-}
-''');
-  }
-
-  test_class_setter_invalid_too_many_parameters() async {
-    var library = await checkLibrary('class C { void set x(a, b) {} }');
-    checkElementText(library, r'''
-class C {
-  void set x(dynamic a, dynamic b) {}
-}
-''');
-  }
-
-  test_class_setter_static() async {
-    var library =
-        await checkLibrary('class C { static void set x(int value) {} }');
-    checkElementText(library, r'''
-class C {
-  static void set x(int value) {}
-}
-''');
-  }
-
-  test_class_setters() async {
-    var library = await checkLibrary('''
-class C {
-  void set x(int value) {}
-  set y(value) {}
-}
-''');
-    if (isStrongMode) {
-      checkElementText(library, r'''
-class C {
-  void set x(int value) {}
-  void set y(dynamic value) {}
-}
-''');
-    } else {
-      checkElementText(library, r'''
-class C {
-  void set x(int value) {}
-  dynamic set y(dynamic value) {}
-}
-''');
-    }
-  }
-
-  test_class_supertype() async {
-    var library = await checkLibrary('''
-class C extends D {}
-class D {}
-''');
-    checkElementText(library, r'''
-class C extends D {
-}
-class D {
-}
-''');
-  }
-
-  test_class_supertype_typeArguments() async {
-    var library = await checkLibrary('''
-class C extends D<int, double> {}
-class D<T1, T2> {}
-''');
-    checkElementText(library, r'''
-class C extends D<int, double> {
-}
-class D<T1, T2> {
-}
-''');
-  }
-
-  test_class_supertype_unresolved() async {
-    var library = await checkLibrary('class C extends D {}', allowErrors: true);
-    checkElementText(library, r'''
-class C {
-}
-''');
-  }
-
-  test_class_type_parameters() async {
-    var library = await checkLibrary('class C<T, U> {}');
-    checkElementText(library, r'''
-class C<T, U> {
-}
-''');
-  }
-
-  test_class_type_parameters_bound() async {
-    var library = await checkLibrary('''
-class C<T extends Object, U extends D> {}
-class D {}
-''');
-    checkElementText(library, r'''
-class C<T, U extends D> {
-}
-class D {
-}
-''');
-  }
-
-  test_class_type_parameters_f_bound_complex() async {
-    var library = await checkLibrary('class C<T extends List<U>, U> {}');
-    checkElementText(library, r'''
-class C<T extends List<U>, U> {
-}
-''');
-  }
-
-  test_class_type_parameters_f_bound_simple() async {
-    var library = await checkLibrary('class C<T extends U, U> {}');
-    checkElementText(library, r'''
-class C<T extends U, U> {
-}
-''');
-  }
-
-  test_classes() async {
-    var library = await checkLibrary('class C {} class D {}');
-    checkElementText(library, r'''
-class C {
-}
-class D {
-}
-''');
-  }
-
-  test_closure_executable_with_return_type_from_closure() async {
-    var library = await checkLibrary('''
-f() {
-  print(() {});
-  print(() => () => 0);
-}
-''');
-    checkElementText(library, r'''
-dynamic f() {}
-''');
-  }
-
-  test_closure_generic() async {
-    var library = await checkLibrary(r'''
-final f = <U, V>(U x, V y) => y;
-''');
-    if (isStrongMode) {
-      checkElementText(library, r'''
-final <U,V>(U, V) → V f;
-''');
-    } else {
-      checkElementText(library, r'''
-final dynamic f;
-''');
-    }
-  }
-
-  test_closure_in_variable_declaration_in_part() async {
-    addSource('/a.dart', 'part of lib; final f = (int i) => i.toDouble();');
-    var library = await checkLibrary('''
-library lib;
-part "a.dart";
-''');
-    if (isStrongMode) {
-      checkElementText(library, r'''
-library lib;
-part 'a.dart';
---------------------
-unit: a.dart
-
-final (int) → double f;
-''');
-    } else {
-      checkElementText(library, r'''
-library lib;
-part 'a.dart';
---------------------
-unit: a.dart
-
-final dynamic f;
-''');
-    }
-  }
-
-  test_codeRange_class() async {
-    var library = await checkLibrary('''
-class Raw {}
-
-/// Comment 1.
-/// Comment 2.
-class HasDocComment {}
-
-@Object()
-class HasAnnotation {}
-
-@Object()
-/// Comment 1.
-/// Comment 2.
-class AnnotationThenComment {}
-
-/// Comment 1.
-/// Comment 2.
-@Object()
-class CommentThenAnnotation {}
-
-/// Comment 1.
-@Object()
-/// Comment 2.
-class CommentAroundAnnotation {}
-''');
-    checkElementText(
-        library,
-        r'''
-class Raw/*codeOffset=0, codeLength=12*/ {
-}
-/// Comment 1.
-/// Comment 2.
-class HasDocComment/*codeOffset=14, codeLength=52*/ {
-}
-@Object()
-class HasAnnotation/*codeOffset=68, codeLength=32*/ {
-}
-/// Comment 1.
-/// Comment 2.
-@Object()
-class AnnotationThenComment/*codeOffset=102, codeLength=70*/ {
-}
-/// Comment 1.
-/// Comment 2.
-@Object()
-class CommentThenAnnotation/*codeOffset=174, codeLength=70*/ {
-}
-/// Comment 2.
-@Object()
-class CommentAroundAnnotation/*codeOffset=261, codeLength=57*/ {
-}
-''',
-        withCodeRanges: true,
-        withConstElements: false);
-  }
-
-  test_codeRange_class_namedMixin() async {
-    var library = await checkLibrary('''
-class A {}
-
-class B {}
-    
-class Raw = Object with A, B;
-
-/// Comment 1.
-/// Comment 2.
-class HasDocComment = Object with A, B;
-
-@Object()
-class HasAnnotation = Object with A, B;
-
-@Object()
-/// Comment 1.
-/// Comment 2.
-class AnnotationThenComment = Object with A, B;
-
-/// Comment 1.
-/// Comment 2.
-@Object()
-class CommentThenAnnotation = Object with A, B;
-
-/// Comment 1.
-@Object()
-/// Comment 2.
-class CommentAroundAnnotation = Object with A, B;
-''');
-    checkElementText(
-        library,
-        r'''
-class A/*codeOffset=0, codeLength=10*/ {
-}
-class B/*codeOffset=12, codeLength=10*/ {
-}
-class alias Raw/*codeOffset=28, codeLength=29*/ extends Object with A, B {
-  synthetic Raw() = Object;
-}
-/// Comment 1.
-/// Comment 2.
-class alias HasDocComment/*codeOffset=59, codeLength=69*/ extends Object with A, B {
-  synthetic HasDocComment() = Object;
-}
-@Object()
-class alias HasAnnotation/*codeOffset=130, codeLength=49*/ extends Object with A, B {
-  synthetic HasAnnotation() = Object;
-}
-/// Comment 1.
-/// Comment 2.
-@Object()
-class alias AnnotationThenComment/*codeOffset=181, codeLength=87*/ extends Object with A, B {
-  synthetic AnnotationThenComment() = Object;
-}
-/// Comment 1.
-/// Comment 2.
-@Object()
-class alias CommentThenAnnotation/*codeOffset=270, codeLength=87*/ extends Object with A, B {
-  synthetic CommentThenAnnotation() = Object;
-}
-/// Comment 2.
-@Object()
-class alias CommentAroundAnnotation/*codeOffset=374, codeLength=74*/ extends Object with A, B {
-  synthetic CommentAroundAnnotation() = Object;
-}
-''',
-        withCodeRanges: true,
-        withConstElements: false);
-  }
-
-  test_codeRange_constructor() async {
-    var library = await checkLibrary('''
-class C {
-  C();
-
-  C.raw() {}
-
-  /// Comment 1.
-  /// Comment 2.
-  C.hasDocComment() {}
-
-  @Object()
-  C.hasAnnotation() {}
-
-  @Object()
-  /// Comment 1.
-  /// Comment 2.
-  C.annotationThenComment() {}
-
-  /// Comment 1.
-  /// Comment 2.
-  @Object()
-  C.commentThenAnnotation() {}
-
-  /// Comment 1.
-  @Object()
-  /// Comment 2.
-  C.commentAroundAnnotation() {}
-}
-''');
-    checkElementText(
-        library,
-        r'''
-class C/*codeOffset=0, codeLength=362*/ {
-  C/*codeOffset=12, codeLength=4*/();
-  C.raw/*codeOffset=20, codeLength=10*/();
-  /// Comment 1.
-  /// Comment 2.
-  C.hasDocComment/*codeOffset=34, codeLength=54*/();
-  @Object()
-  C.hasAnnotation/*codeOffset=92, codeLength=32*/();
-  /// Comment 1.
-  /// Comment 2.
-  @Object()
-  C.annotationThenComment/*codeOffset=128, codeLength=74*/();
-  /// Comment 1.
-  /// Comment 2.
-  @Object()
-  C.commentThenAnnotation/*codeOffset=206, codeLength=74*/();
-  /// Comment 2.
-  @Object()
-  C.commentAroundAnnotation/*codeOffset=301, codeLength=59*/();
-}
-''',
-        withCodeRanges: true,
-        withConstElements: false);
-  }
-
-  test_codeRange_constructor_factory() async {
-    var library = await checkLibrary('''
-class C {
-  factory C() => null;
-
-  factory C.raw() => null;
-
-  /// Comment 1.
-  /// Comment 2.
-  factory C.hasDocComment() => null;
-
-  @Object()
-  factory C.hasAnnotation() => null;
-
-  @Object()
-  /// Comment 1.
-  /// Comment 2.
-  factory C.annotationThenComment() => null;
-
-  /// Comment 1.
-  /// Comment 2.
-  @Object()
-  factory C.commentThenAnnotation() => null;
-
-  /// Comment 1.
-  @Object()
-  /// Comment 2.
-  factory C.commentAroundAnnotation() => null;
-}
-''');
-    checkElementText(
-        library,
-        r'''
-class C/*codeOffset=0, codeLength=462*/ {
-  factory C/*codeOffset=12, codeLength=20*/();
-  factory C.raw/*codeOffset=36, codeLength=24*/();
-  /// Comment 1.
-  /// Comment 2.
-  factory C.hasDocComment/*codeOffset=64, codeLength=68*/();
-  @Object()
-  factory C.hasAnnotation/*codeOffset=136, codeLength=46*/();
-  /// Comment 1.
-  /// Comment 2.
-  @Object()
-  factory C.annotationThenComment/*codeOffset=186, codeLength=88*/();
-  /// Comment 1.
-  /// Comment 2.
-  @Object()
-  factory C.commentThenAnnotation/*codeOffset=278, codeLength=88*/();
-  /// Comment 2.
-  @Object()
-  factory C.commentAroundAnnotation/*codeOffset=387, codeLength=73*/();
-}
-''',
-        withCodeRanges: true,
-        withConstElements: false);
-  }
-
-  test_codeRange_field() async {
-    var library = await checkLibrary('''
-class C {
-  int withInit = 1;
-
-  int withoutInit;
-
-  int multiWithInit = 2, multiWithoutInit, multiWithInit2 = 3; 
-}
-''');
-    checkElementText(
-        library,
-        r'''
-class C/*codeOffset=0, codeLength=116*/ {
-  int withInit/*codeOffset=12, codeLength=16*/;
-  int withoutInit/*codeOffset=33, codeLength=15*/;
-  int multiWithInit/*codeOffset=53, codeLength=21*/;
-  int multiWithoutInit/*codeOffset=76, codeLength=16*/;
-  int multiWithInit2/*codeOffset=94, codeLength=18*/;
-}
-''',
-        withCodeRanges: true,
-        withConstElements: false);
-  }
-
-  test_codeRange_field_annotations() async {
-    var library = await checkLibrary('''
-class C {
-  /// Comment 1.
-  /// Comment 2.
-  int hasDocComment, hasDocComment2;
-
-  @Object()
-  int hasAnnotation, hasAnnotation2;
-
-  @Object()
-  /// Comment 1.
-  /// Comment 2.
-  int annotationThenComment, annotationThenComment2;
-
-  /// Comment 1.
-  /// Comment 2.
-  @Object()
-  int commentThenAnnotation, commentThenAnnotation2;
-
-  /// Comment 1.
-  @Object()
-  /// Comment 2.
-  int commentAroundAnnotation, commentAroundAnnotation2;
-}
-''');
-    checkElementText(
-        library,
-        r'''
-class C/*codeOffset=0, codeLength=436*/ {
-  /// Comment 1.
-  /// Comment 2.
-  int hasDocComment/*codeOffset=12, codeLength=51*/;
-  /// Comment 1.
-  /// Comment 2.
-  int hasDocComment2/*codeOffset=65, codeLength=14*/;
-  @Object()
-  int hasAnnotation/*codeOffset=84, codeLength=29*/;
-  @Object()
-  int hasAnnotation2/*codeOffset=115, codeLength=14*/;
-  /// Comment 1.
-  /// Comment 2.
-  @Object()
-  int annotationThenComment/*codeOffset=134, codeLength=71*/;
-  /// Comment 1.
-  /// Comment 2.
-  @Object()
-  int annotationThenComment2/*codeOffset=207, codeLength=22*/;
-  /// Comment 1.
-  /// Comment 2.
-  @Object()
-  int commentThenAnnotation/*codeOffset=234, codeLength=71*/;
-  /// Comment 1.
-  /// Comment 2.
-  @Object()
-  int commentThenAnnotation2/*codeOffset=307, codeLength=22*/;
-  /// Comment 2.
-  @Object()
-  int commentAroundAnnotation/*codeOffset=351, codeLength=56*/;
-  /// Comment 2.
-  @Object()
-  int commentAroundAnnotation2/*codeOffset=409, codeLength=24*/;
-}
-''',
-        withCodeRanges: true,
-        withConstElements: false);
-  }
-
-  test_codeRange_function() async {
-    var library = await checkLibrary('''
-void raw() {}
-
-/// Comment 1.
-/// Comment 2.
-void hasDocComment() {}
-
-@Object()
-void hasAnnotation() {}
-
-@Object()
-/// Comment 1.
-/// Comment 2.
-void annotationThenComment() {}
-
-/// Comment 1.
-/// Comment 2.
-@Object()
-void commentThenAnnotation() {}
-
-/// Comment 1.
-@Object()
-/// Comment 2.
-void commentAroundAnnotation() {}
-''');
-    checkElementText(
-        library,
-        r'''
-void raw/*codeOffset=0, codeLength=13*/() {}
-/// Comment 1.
-/// Comment 2.
-void hasDocComment/*codeOffset=15, codeLength=53*/() {}
-@Object()
-void hasAnnotation/*codeOffset=70, codeLength=33*/() {}
-/// Comment 1.
-/// Comment 2.
-@Object()
-void annotationThenComment/*codeOffset=105, codeLength=71*/() {}
-/// Comment 1.
-/// Comment 2.
-@Object()
-void commentThenAnnotation/*codeOffset=178, codeLength=71*/() {}
-/// Comment 2.
-@Object()
-void commentAroundAnnotation/*codeOffset=266, codeLength=58*/() {}
-''',
-        withCodeRanges: true,
-        withConstElements: false);
-  }
-
-  test_codeRange_method() async {
-    var library = await checkLibrary('''
-class C {
-  void raw() {}
-
-  /// Comment 1.
-  /// Comment 2.
-  void hasDocComment() {}
-
-  @Object()
-  void hasAnnotation() {}
-
-  @Object()
-  /// Comment 1.
-  /// Comment 2.
-  void annotationThenComment() {}
-
-  /// Comment 1.
-  /// Comment 2.
-  @Object()
-  void commentThenAnnotation() {}
-
-  /// Comment 1.
-  @Object()
-  /// Comment 2.
-  void commentAroundAnnotation() {}
-}
-''');
-    checkElementText(
-        library,
-        r'''
-class C/*codeOffset=0, codeLength=372*/ {
-  void raw/*codeOffset=12, codeLength=13*/() {}
-  /// Comment 1.
-  /// Comment 2.
-  void hasDocComment/*codeOffset=29, codeLength=57*/() {}
-  @Object()
-  void hasAnnotation/*codeOffset=90, codeLength=35*/() {}
-  /// Comment 1.
-  /// Comment 2.
-  @Object()
-  void annotationThenComment/*codeOffset=129, codeLength=77*/() {}
-  /// Comment 1.
-  /// Comment 2.
-  @Object()
-  void commentThenAnnotation/*codeOffset=210, codeLength=77*/() {}
-  /// Comment 2.
-  @Object()
-  void commentAroundAnnotation/*codeOffset=308, codeLength=62*/() {}
-}
-''',
-        withCodeRanges: true,
-        withConstElements: false);
-  }
-
-  test_codeRange_parameter() async {
-    var library = await checkLibrary('''
-main({int a = 1, int b, int c = 2}) {}
-''');
-    checkElementText(
-        library,
-        'dynamic main/*codeOffset=0, codeLength=38*/('
-        '{int a/*codeOffset=6, codeLength=9*/: 1}, '
-        '{int b/*codeOffset=17, codeLength=5*/}, '
-        '{int c/*codeOffset=24, codeLength=9*/: 2}) {}\n',
-        withCodeRanges: true,
-        withConstElements: false);
-  }
-
-  test_codeRange_parameter_annotations() async {
-    var library = await checkLibrary('''
-main(@Object() int a, int b, @Object() int c) {}
-''');
-    checkElementText(
-        library,
-        'dynamic main/*codeOffset=0, codeLength=48*/('
-        '@Object() int a/*codeOffset=5, codeLength=15*/, '
-        'int b/*codeOffset=22, codeLength=5*/, '
-        '@Object() int c/*codeOffset=29, codeLength=15*/) {}\n',
-        withCodeRanges: true,
-        withConstElements: false);
-  }
-
-  test_codeRange_topLevelVariable() async {
-    var library = await checkLibrary('''
-int withInit = 1 + 2 * 3;
-
-int withoutInit;
-
-int multiWithInit = 2, multiWithoutInit, multiWithInit2 = 3; 
-''');
-    checkElementText(
-        library,
-        r'''
-int withInit/*codeOffset=0, codeLength=24*/;
-int withoutInit/*codeOffset=27, codeLength=15*/;
-int multiWithInit/*codeOffset=45, codeLength=21*/;
-int multiWithoutInit/*codeOffset=68, codeLength=16*/;
-int multiWithInit2/*codeOffset=86, codeLength=18*/;
-''',
-        withCodeRanges: true,
-        withConstElements: false);
-  }
-
-  test_codeRange_topLevelVariable_annotations() async {
-    var library = await checkLibrary('''
-/// Comment 1.
-/// Comment 2.
-int hasDocComment, hasDocComment2;
-
-@Object()
-int hasAnnotation, hasAnnotation2;
-
-@Object()
-/// Comment 1.
-/// Comment 2.
-int annotationThenComment, annotationThenComment2;
-
-/// Comment 1.
-/// Comment 2.
-@Object()
-int commentThenAnnotation, commentThenAnnotation2;
-
-/// Comment 1.
-@Object()
-/// Comment 2.
-int commentAroundAnnotation, commentAroundAnnotation2;
-''');
-    checkElementText(
-        library,
-        r'''
-/// Comment 1.
-/// Comment 2.
-int hasDocComment/*codeOffset=0, codeLength=47*/;
-/// Comment 1.
-/// Comment 2.
-int hasDocComment2/*codeOffset=49, codeLength=14*/;
-@Object()
-int hasAnnotation/*codeOffset=66, codeLength=27*/;
-@Object()
-int hasAnnotation2/*codeOffset=95, codeLength=14*/;
-/// Comment 1.
-/// Comment 2.
-@Object()
-int annotationThenComment/*codeOffset=112, codeLength=65*/;
-/// Comment 1.
-/// Comment 2.
-@Object()
-int annotationThenComment2/*codeOffset=179, codeLength=22*/;
-/// Comment 1.
-/// Comment 2.
-@Object()
-int commentThenAnnotation/*codeOffset=204, codeLength=65*/;
-/// Comment 1.
-/// Comment 2.
-@Object()
-int commentThenAnnotation2/*codeOffset=271, codeLength=22*/;
-/// Comment 2.
-@Object()
-int commentAroundAnnotation/*codeOffset=311, codeLength=52*/;
-/// Comment 2.
-@Object()
-int commentAroundAnnotation2/*codeOffset=365, codeLength=24*/;
-''',
-        withCodeRanges: true,
-        withConstElements: false);
-  }
-
-  test_const_constructor_inferred_args() async {
-    if (!isStrongMode) return;
-    var library = await checkLibrary('''
-class C<T> {
-  final T t;
-  const C(this.t);
-  const C.named(this.t);
-}
-const Object x = const C(0);
-const Object y = const C.named(0);
-''');
-    checkElementText(library, '''
-class C<T> {
-  final T t;
-  const C(T this.t);
-  const C.named(T this.t);
-}
-const Object x = const
-        C/*location: test.dart;C*/(0);
-const Object y = const
-        C/*location: test.dart;C*/.
-        named/*location: test.dart;C;named*/(0);
-''');
-    TopLevelVariableElementImpl x =
-        library.definingCompilationUnit.topLevelVariables[0];
-    InstanceCreationExpression xExpr = x.constantInitializer;
-    var xType = xExpr.constructorName.staticElement.returnType;
-    expect(xType.toString(), 'C<int>');
-    TopLevelVariableElementImpl y =
-        library.definingCompilationUnit.topLevelVariables[0];
-    InstanceCreationExpression yExpr = y.constantInitializer;
-    var yType = yExpr.constructorName.staticElement.returnType;
-    expect(yType.toString(), 'C<int>');
-  }
-
-  test_const_finalField_hasConstConstructor() async {
-    var library = await checkLibrary(r'''
-class C {
-  final int f = 42;
-  const C();
-}
-''');
-    checkElementText(library, r'''
-class C {
-  final int f = 42;
-  const C();
-}
-''');
-  }
-
-  test_const_invalid_field_const() async {
-    shouldCompareLibraryElements = false;
-    var library = await checkLibrary(r'''
-class C {
-  static const f = 1 + foo();
-}
-int foo() => 42;
-''', allowErrors: true);
-    if (isSharedFrontEnd) {
-      checkElementText(library, r'''
-class C {
-  static const int f = #invalidConst;
-}
-int foo() {}
-''');
-    } else if (isStrongMode) {
-      checkElementText(library, r'''
-class C {
-  static const int f = 1 +
-        foo/*location: test.dart;foo*/();
-}
-int foo() {}
-''');
-    } else {
-      checkElementText(library, r'''
-class C {
-  static const dynamic f = 1 +
-        foo/*location: test.dart;foo*/();
-}
-int foo() {}
-''');
-    }
-  }
-
-  test_const_invalid_field_final() async {
-    variablesWithNotConstInitializers.add('f');
-    var library = await checkLibrary(r'''
-class C {
-  final f = 1 + foo();
-}
-int foo() => 42;
-''', allowErrors: true);
-    if (isStrongMode) {
-      checkElementText(library, r'''
-class C {
-  final int f;
-}
-int foo() {}
-''');
-    } else {
-      checkElementText(library, r'''
-class C {
-  final dynamic f;
-}
-int foo() {}
-''');
-    }
-  }
-
-  test_const_invalid_intLiteral() async {
-    var library = await checkLibrary(r'''
-const int x = 0x;
-''', allowErrors: true);
-    checkElementText(library, r'''
-const int x = 0;
-''');
-  }
-
-  test_const_invalid_topLevel() async {
-    shouldCompareLibraryElements = false;
-    var library = await checkLibrary(r'''
-const v = 1 + foo();
-int foo() => 42;
-''', allowErrors: true);
-    if (isSharedFrontEnd) {
-      checkElementText(library, r'''
-const int v = #invalidConst;
-int foo() {}
-''');
-    } else if (isStrongMode) {
-      checkElementText(library, r'''
-const int v = 1 +
-        foo/*location: test.dart;foo*/();
-int foo() {}
-''');
-    } else {
-      checkElementText(library, r'''
-const dynamic v = 1 +
-        foo/*location: test.dart;foo*/();
-int foo() {}
-''');
-    }
-  }
-
-  test_const_invalid_typeMismatch() async {
-    var library = await checkLibrary(r'''
-const int a = 0;
-const bool b = a + 5;
-''', allowErrors: true);
-    if (isSharedFrontEnd) {
-      checkElementText(library, r'''
-const int a = 0;
-const bool b = #invalidConst;
-''');
-    } else {
-      checkElementText(library, r'''
-const int a = 0;
-const bool b =
-        a/*location: test.dart;a?*/ + 5;
-''');
-    }
-  }
-
-  test_const_invokeConstructor_generic_named() async {
-    var library = await checkLibrary(r'''
-class C<K, V> {
-  const C.named(K k, V v);
-}
-const V = const C<int, String>.named(1, '222');
-''');
-    if (isStrongMode) {
-      checkElementText(library, r'''
-class C<K, V> {
-  const C.named(K k, V v);
-}
-const C<int, String> V = const
-        C/*location: test.dart;C*/<
-        int/*location: dart:core;int*/,
-        String/*location: dart:core;String*/>.
-        named/*location: test.dart;C;named*/(1, '222');
-''');
-    } else {
-      checkElementText(library, r'''
-class C<K, V> {
-  const C.named(K k, V v);
-}
-const dynamic V = const
-        C/*location: test.dart;C*/<
-        int/*location: dart:core;int*/,
-        String/*location: dart:core;String*/>.
-        named/*location: test.dart;C;named*/(1, '222');
-''');
-    }
-  }
-
-  test_const_invokeConstructor_generic_named_imported() async {
-    addLibrarySource('/a.dart', r'''
-class C<K, V> {
-  const C.named(K k, V v);
-}
-''');
-    var library = await checkLibrary(r'''
-import 'a.dart';
-const V = const C<int, String>.named(1, '222');
-''');
-    if (isStrongMode) {
-      checkElementText(library, r'''
-import 'a.dart';
-const C<int, String> V = const
-        C/*location: a.dart;C*/<
-        int/*location: dart:core;int*/,
-        String/*location: dart:core;String*/>.
-        named/*location: a.dart;C;named*/(1, '222');
-''');
-    } else {
-      checkElementText(library, r'''
-import 'a.dart';
-const dynamic V = const
-        C/*location: a.dart;C*/<
-        int/*location: dart:core;int*/,
-        String/*location: dart:core;String*/>.
-        named/*location: a.dart;C;named*/(1, '222');
-''');
-    }
-  }
-
-  test_const_invokeConstructor_generic_named_imported_withPrefix() async {
-    addLibrarySource('/a.dart', r'''
-class C<K, V> {
-  const C.named(K k, V v);
-}
-''');
-    var library = await checkLibrary(r'''
-import 'a.dart' as p;
-const V = const p.C<int, String>.named(1, '222');
-''');
-    if (isStrongMode) {
-      checkElementText(library, r'''
-import 'a.dart' as p;
-const C<int, String> V = const
-        C/*location: a.dart;C*/<
-        int/*location: dart:core;int*/,
-        String/*location: dart:core;String*/>.
-        named/*location: a.dart;C;named*/(1, '222');
-''');
-    } else {
-      checkElementText(library, r'''
-import 'a.dart' as p;
-const dynamic V = const
-        C/*location: a.dart;C*/<
-        int/*location: dart:core;int*/,
-        String/*location: dart:core;String*/>.
-        named/*location: a.dart;C;named*/(1, '222');
-''');
-    }
-  }
-
-  test_const_invokeConstructor_generic_noTypeArguments() async {
-    var library = await checkLibrary(r'''
-class C<K, V> {
-  const C();
-}
-const V = const C();
-''');
-    if (isStrongMode) {
-      checkElementText(library, r'''
-class C<K, V> {
-  const C();
-}
-const C<dynamic, dynamic> V = const
-        C/*location: test.dart;C*/();
-''');
-    } else {
-      checkElementText(library, r'''
-class C<K, V> {
-  const C();
-}
-const dynamic V = const
-        C/*location: test.dart;C*/();
-''');
-    }
-  }
-
-  test_const_invokeConstructor_generic_unnamed() async {
-    var library = await checkLibrary(r'''
-class C<K, V> {
-  const C();
-}
-const V = const C<int, String>();
-''');
-    if (isStrongMode) {
-      checkElementText(library, r'''
-class C<K, V> {
-  const C();
-}
-const C<int, String> V = const
-        C/*location: test.dart;C*/<
-        int/*location: dart:core;int*/,
-        String/*location: dart:core;String*/>();
-''');
-    } else {
-      checkElementText(library, r'''
-class C<K, V> {
-  const C();
-}
-const dynamic V = const
-        C/*location: test.dart;C*/<
-        int/*location: dart:core;int*/,
-        String/*location: dart:core;String*/>();
-''');
-    }
-  }
-
-  test_const_invokeConstructor_generic_unnamed_imported() async {
-    addLibrarySource('/a.dart', r'''
-class C<K, V> {
-  const C();
-}
-''');
-    var library = await checkLibrary(r'''
-import 'a.dart';
-const V = const C<int, String>();
-''');
-    if (isStrongMode) {
-      checkElementText(library, r'''
-import 'a.dart';
-const C<int, String> V = const
-        C/*location: a.dart;C*/<
-        int/*location: dart:core;int*/,
-        String/*location: dart:core;String*/>();
-''');
-    } else {
-      checkElementText(library, r'''
-import 'a.dart';
-const dynamic V = const
-        C/*location: a.dart;C*/<
-        int/*location: dart:core;int*/,
-        String/*location: dart:core;String*/>();
-''');
-    }
-  }
-
-  test_const_invokeConstructor_generic_unnamed_imported_withPrefix() async {
-    addLibrarySource('/a.dart', r'''
-class C<K, V> {
-  const C();
-}
-''');
-    var library = await checkLibrary(r'''
-import 'a.dart' as p;
-const V = const p.C<int, String>();
-''');
-    if (isStrongMode) {
-      checkElementText(library, r'''
-import 'a.dart' as p;
-const C<int, String> V = const
-        C/*location: a.dart;C*/<
-        int/*location: dart:core;int*/,
-        String/*location: dart:core;String*/>();
-''');
-    } else {
-      checkElementText(library, r'''
-import 'a.dart' as p;
-const dynamic V = const
-        C/*location: a.dart;C*/<
-        int/*location: dart:core;int*/,
-        String/*location: dart:core;String*/>();
-''');
-    }
-  }
-
-  test_const_invokeConstructor_named() async {
-    var library = await checkLibrary(r'''
-class C {
-  const C.named(bool a, int b, int c, {String d, double e});
-}
-const V = const C.named(true, 1, 2, d: 'ccc', e: 3.4);
-''');
-    if (isStrongMode) {
-      checkElementText(library, r'''
-class C {
-  const C.named(bool a, int b, int c, {String d}, {double e});
-}
-const C V = const
-        C/*location: test.dart;C*/.
-        named/*location: test.dart;C;named*/(true, 1, 2,
-        d/*location: null*/: 'ccc',
-        e/*location: null*/: 3.4);
-''');
-    } else {
-      checkElementText(library, r'''
-class C {
-  const C.named(bool a, int b, int c, {String d}, {double e});
-}
-const dynamic V = const
-        C/*location: test.dart;C*/.
-        named/*location: test.dart;C;named*/(true, 1, 2,
-        d/*location: null*/: 'ccc',
-        e/*location: null*/: 3.4);
-''');
-    }
-  }
-
-  test_const_invokeConstructor_named_imported() async {
-    addLibrarySource('/a.dart', r'''
-class C {
-  const C.named();
-}
-''');
-    var library = await checkLibrary(r'''
-import 'a.dart';
-const V = const C.named();
-''');
-    if (isStrongMode) {
-      checkElementText(library, r'''
-import 'a.dart';
-const C V = const
-        C/*location: a.dart;C*/.
-        named/*location: a.dart;C;named*/();
-''');
-    } else {
-      checkElementText(library, r'''
-import 'a.dart';
-const dynamic V = const
-        C/*location: a.dart;C*/.
-        named/*location: a.dart;C;named*/();
-''');
-    }
-  }
-
-  test_const_invokeConstructor_named_imported_withPrefix() async {
-    addLibrarySource('/a.dart', r'''
-class C {
-  const C.named();
-}
-''');
-    var library = await checkLibrary(r'''
-import 'a.dart' as p;
-const V = const p.C.named();
-''');
-    if (isStrongMode) {
-      checkElementText(library, r'''
-import 'a.dart' as p;
-const C V = const
-        C/*location: a.dart;C*/.
-        named/*location: a.dart;C;named*/();
-''');
-    } else {
-      checkElementText(library, r'''
-import 'a.dart' as p;
-const dynamic V = const
-        C/*location: a.dart;C*/.
-        named/*location: a.dart;C;named*/();
-''');
-    }
-  }
-
-  test_const_invokeConstructor_named_unresolved() async {
-    shouldCompareLibraryElements = false;
-    var library = await checkLibrary(r'''
-class C {}
-const V = const C.named();
-''', allowErrors: true);
-    checkElementText(library, r'''
-class C {
-}
-const dynamic V = #invalidConst;
-''');
-  }
-
-  test_const_invokeConstructor_named_unresolved2() async {
-    shouldCompareLibraryElements = false;
-    var library = await checkLibrary(r'''
-const V = const C.named();
-''', allowErrors: true);
-    checkElementText(library, r'''
-const dynamic V = #invalidConst;
-''');
-  }
-
-  test_const_invokeConstructor_named_unresolved3() async {
-    shouldCompareLibraryElements = false;
-    addLibrarySource('/a.dart', r'''
-class C {
-}
-''');
-    var library = await checkLibrary(r'''
-import 'a.dart' as p;
-const V = const p.C.named();
-''', allowErrors: true);
-    checkElementText(library, r'''
-import 'a.dart' as p;
-const dynamic V = #invalidConst;
-''');
-  }
-
-  test_const_invokeConstructor_named_unresolved4() async {
-    shouldCompareLibraryElements = false;
-    addLibrarySource('/a.dart', '');
-    var library = await checkLibrary(r'''
-import 'a.dart' as p;
-const V = const p.C.named();
-''', allowErrors: true);
-    checkElementText(library, r'''
-import 'a.dart' as p;
-const dynamic V = #invalidConst;
-''');
-  }
-
-  test_const_invokeConstructor_named_unresolved5() async {
-    shouldCompareLibraryElements = false;
-    var library = await checkLibrary(r'''
-const V = const p.C.named();
-''', allowErrors: true);
-    checkElementText(library, r'''
-const dynamic V = #invalidConst;
-''');
-  }
-
-  test_const_invokeConstructor_named_unresolved6() async {
-    shouldCompareLibraryElements = false;
-    var library = await checkLibrary(r'''
-class C<T> {}
-const V = const C.named();
-''', allowErrors: true);
-    checkElementText(library, r'''
-class C<T> {
-}
-const dynamic V = #invalidConst;
-''');
-  }
-
-  test_const_invokeConstructor_unnamed() async {
-    var library = await checkLibrary(r'''
-class C {
-  const C();
-}
-const V = const C();
-''');
-    if (isStrongMode) {
-      checkElementText(library, r'''
-class C {
-  const C();
-}
-const C V = const
-        C/*location: test.dart;C*/();
-''');
-    } else {
-      checkElementText(library, r'''
-class C {
-  const C();
-}
-const dynamic V = const
-        C/*location: test.dart;C*/();
-''');
-    }
-  }
-
-  test_const_invokeConstructor_unnamed_imported() async {
-    addLibrarySource('/a.dart', r'''
-class C {
-  const C();
-}
-''');
-    var library = await checkLibrary(r'''
-import 'a.dart';
-const V = const C();
-''');
-    if (isStrongMode) {
-      checkElementText(library, r'''
-import 'a.dart';
-const C V = const
-        C/*location: a.dart;C*/();
-''');
-    } else {
-      checkElementText(library, r'''
-import 'a.dart';
-const dynamic V = const
-        C/*location: a.dart;C*/();
-''');
-    }
-  }
-
-  test_const_invokeConstructor_unnamed_imported_withPrefix() async {
-    addLibrarySource('/a.dart', r'''
-class C {
-  const C();
-}
-''');
-    var library = await checkLibrary(r'''
-import 'a.dart' as p;
-const V = const p.C();
-''');
-    if (isStrongMode) {
-      checkElementText(library, r'''
-import 'a.dart' as p;
-const C V = const
-        C/*location: a.dart;C*/();
-''');
-    } else {
-      checkElementText(library, r'''
-import 'a.dart' as p;
-const dynamic V = const
-        C/*location: a.dart;C*/();
-''');
-    }
-  }
-
-  test_const_invokeConstructor_unnamed_unresolved() async {
-    shouldCompareLibraryElements = false;
-    var library = await checkLibrary(r'''
-const V = const C();
-''', allowErrors: true);
-    checkElementText(library, r'''
-const dynamic V = #invalidConst;
-''');
-  }
-
-  test_const_invokeConstructor_unnamed_unresolved2() async {
-    shouldCompareLibraryElements = false;
-    addLibrarySource('/a.dart', '');
-    var library = await checkLibrary(r'''
-import 'a.dart' as p;
-const V = const p.C();
-''', allowErrors: true);
-    checkElementText(library, r'''
-import 'a.dart' as p;
-const dynamic V = #invalidConst;
-''');
-  }
-
-  test_const_invokeConstructor_unnamed_unresolved3() async {
-    shouldCompareLibraryElements = false;
-    var library = await checkLibrary(r'''
-const V = const p.C();
-''', allowErrors: true);
-    checkElementText(library, r'''
-const dynamic V = #invalidConst;
-''');
-  }
-
-  test_const_length_ofClassConstField() async {
-    var library = await checkLibrary(r'''
-class C {
-  static const String F = '';
-}
-const int v = C.F.length;
-''');
-    checkElementText(library, r'''
-class C {
-  static const String F = '';
-}
-const int v =
-        C/*location: test.dart;C*/.
-        F/*location: test.dart;C;F?*/.
-        length/*location: dart:core;String;length?*/;
-''');
-  }
-
-  test_const_length_ofClassConstField_imported() async {
-    addLibrarySource('/a.dart', r'''
-class C {
-  static const String F = '';
-}
-''');
-    var library = await checkLibrary(r'''
-import 'a.dart';
-const int v = C.F.length;
-''');
-    checkElementText(library, r'''
-import 'a.dart';
-const int v =
-        C/*location: a.dart;C*/.
-        F/*location: a.dart;C;F?*/.
-        length/*location: dart:core;String;length?*/;
-''');
-  }
-
-  test_const_length_ofClassConstField_imported_withPrefix() async {
-    addLibrarySource('/a.dart', r'''
-class C {
-  static const String F = '';
-}
-''');
-    var library = await checkLibrary(r'''
-import 'a.dart' as p;
-const int v = p.C.F.length;
-''');
-    if (isSharedFrontEnd) {
-      checkElementText(library, r'''
-import 'a.dart' as p;
-const int v =
-        C/*location: a.dart;C*/.
-        F/*location: a.dart;C;F?*/.
-        length/*location: dart:core;String;length?*/;
-''');
-    } else {
-      checkElementText(library, r'''
-import 'a.dart' as p;
-const int v =
-        p/*location: test.dart;p*/.
-        C/*location: a.dart;C*/.
-        F/*location: a.dart;C;F?*/.
-        length/*location: dart:core;String;length?*/;
-''');
-    }
-  }
-
-  test_const_length_ofStringLiteral() async {
-    var library = await checkLibrary(r'''
-const v = 'abc'.length;
-''');
-    if (isStrongMode) {
-      checkElementText(library, r'''
-const int v = 'abc'.
-        length/*location: dart:core;String;length?*/;
-''');
-    } else {
-      checkElementText(library, r'''
-const dynamic v = 'abc'.
-        length/*location: dart:core;String;length?*/;
-''');
-    }
-  }
-
-  test_const_length_ofTopLevelVariable() async {
-    var library = await checkLibrary(r'''
-const String S = 'abc';
-const v = S.length;
-''');
-    if (isStrongMode) {
-      checkElementText(library, r'''
-const String S = 'abc';
-const int v =
-        S/*location: test.dart;S?*/.
-        length/*location: dart:core;String;length?*/;
-''');
-    } else {
-      checkElementText(library, r'''
-const String S = 'abc';
-const dynamic v =
-        S/*location: test.dart;S?*/.
-        length/*location: dart:core;String;length?*/;
-''');
-    }
-  }
-
-  test_const_length_ofTopLevelVariable_imported() async {
-    addLibrarySource('/a.dart', r'''
-const String S = 'abc';
-''');
-    var library = await checkLibrary(r'''
-import 'a.dart';
-const v = S.length;
-''');
-    if (isStrongMode) {
-      checkElementText(library, r'''
-import 'a.dart';
-const int v =
-        S/*location: a.dart;S?*/.
-        length/*location: dart:core;String;length?*/;
-''');
-    } else {
-      checkElementText(library, r'''
-import 'a.dart';
-const dynamic v =
-        S/*location: a.dart;S?*/.
-        length/*location: dart:core;String;length?*/;
-''');
-    }
-  }
-
-  test_const_length_ofTopLevelVariable_imported_withPrefix() async {
-    addLibrarySource('/a.dart', r'''
-const String S = 'abc';
-''');
-    var library = await checkLibrary(r'''
-import 'a.dart' as p;
-const v = p.S.length;
-''');
-    if (isStrongMode) {
-      if (isSharedFrontEnd) {
-        checkElementText(library, r'''
-import 'a.dart' as p;
-const int v =
-        S/*location: a.dart;S?*/.
-        length/*location: dart:core;String;length?*/;
-''');
-      } else {
-        checkElementText(library, r'''
-import 'a.dart' as p;
-const int v =
-        p/*location: test.dart;p*/.
-        S/*location: a.dart;S?*/.
-        length/*location: dart:core;String;length?*/;
-''');
-      }
-    } else {
-      checkElementText(library, r'''
-import 'a.dart' as p;
-const dynamic v =
-        p/*location: test.dart;p*/.
-        S/*location: a.dart;S?*/.
-        length/*location: dart:core;String;length?*/;
-''');
-    }
-  }
-
-  test_const_length_staticMethod() async {
-    var library = await checkLibrary(r'''
-class C {
-  static int length() => 42;
-}
-const v = C.length;
-''');
-    if (isStrongMode) {
-      checkElementText(library, r'''
-class C {
-  static int length() {}
-}
-const () → int v =
-        C/*location: test.dart;C*/.
-        length/*location: test.dart;C;length*/;
-''');
-    } else {
-      checkElementText(library, r'''
-class C {
-  static int length() {}
-}
-const dynamic v =
-        C/*location: test.dart;C*/.
-        length/*location: test.dart;C;length*/;
-''');
-    }
-  }
-
-  test_const_list_inferredType() async {
-    if (!isStrongMode) return;
-    // The summary needs to contain enough information so that when the constant
-    // is resynthesized, the constant value can get the type that was computed
-    // by type inference.
-    var library = await checkLibrary('''
-const Object x = const [1];
-''');
-    checkElementText(library, '''
-const Object x = const <
-        int/*location: dart:core;int*/>[1];
-''');
-  }
-
-  test_const_map_inferredType() async {
-    if (!isStrongMode) return;
-    // The summary needs to contain enough information so that when the constant
-    // is resynthesized, the constant value can get the type that was computed
-    // by type inference.
-    var library = await checkLibrary('''
-const Object x = const {1: 1.0};
-''');
-    checkElementText(library, '''
-const Object x = const <
-        int/*location: dart:core;int*/,
-        double/*location: dart:core;double*/>{1: 1.0};
-''');
-  }
-
-  test_const_parameterDefaultValue_initializingFormal_functionTyped() async {
-    var library = await checkLibrary(r'''
-class C {
-  final x;
-  const C({this.x: foo});
-}
-int foo() => 42;
-''');
-    checkElementText(library, r'''
-class C {
-  final dynamic x;
-  const C({dynamic this.x:
-        foo/*location: test.dart;foo*/});
-}
-int foo() {}
-''');
-  }
-
-  test_const_parameterDefaultValue_initializingFormal_named() async {
-    var library = await checkLibrary(r'''
-class C {
-  final x;
-  const C({this.x: 1 + 2});
-}
-''');
-    checkElementText(library, r'''
-class C {
-  final dynamic x;
-  const C({dynamic this.x: 1 + 2});
-}
-''');
-  }
-
-  test_const_parameterDefaultValue_initializingFormal_positional() async {
-    var library = await checkLibrary(r'''
-class C {
-  final x;
-  const C([this.x = 1 + 2]);
-}
-''');
-    checkElementText(library, r'''
-class C {
-  final dynamic x;
-  const C([dynamic this.x = 1 + 2]);
-}
-''');
-  }
-
-  test_const_parameterDefaultValue_normal() async {
-    var library = await checkLibrary(r'''
-class C {
-  const C.positional([p = 1 + 2]);
-  const C.named({p: 1 + 2});
-  void methodPositional([p = 1 + 2]) {}
-  void methodPositionalWithoutDefault([p]) {}
-  void methodNamed({p: 1 + 2}) {}
-  void methodNamedWithoutDefault({p}) {}
-}
-''');
-    checkElementText(library, r'''
-class C {
-  const C.positional([dynamic p = 1 + 2]);
-  const C.named({dynamic p: 1 + 2});
-  void methodPositional([dynamic p = 1 + 2]) {}
-  void methodPositionalWithoutDefault([dynamic p]) {}
-  void methodNamed({dynamic p: 1 + 2}) {}
-  void methodNamedWithoutDefault({dynamic p}) {}
-}
-''');
-  }
-
-  test_const_reference_staticField() async {
-    var library = await checkLibrary(r'''
-class C {
-  static const int F = 42;
-}
-const V = C.F;
-''');
-    if (isStrongMode) {
-      checkElementText(library, r'''
-class C {
-  static const int F = 42;
-}
-const int V =
-        C/*location: test.dart;C*/.
-        F/*location: test.dart;C;F?*/;
-''');
-    } else {
-      checkElementText(library, r'''
-class C {
-  static const int F = 42;
-}
-const dynamic V =
-        C/*location: test.dart;C*/.
-        F/*location: test.dart;C;F?*/;
-''');
-    }
-  }
-
-  test_const_reference_staticField_imported() async {
-    addLibrarySource('/a.dart', r'''
-class C {
-  static const int F = 42;
-}
-''');
-    var library = await checkLibrary(r'''
-import 'a.dart';
-const V = C.F;
-''');
-    if (isStrongMode) {
-      checkElementText(library, r'''
-import 'a.dart';
-const int V =
-        C/*location: a.dart;C*/.
-        F/*location: a.dart;C;F?*/;
-''');
-    } else {
-      checkElementText(library, r'''
-import 'a.dart';
-const dynamic V =
-        C/*location: a.dart;C*/.
-        F/*location: a.dart;C;F?*/;
-''');
-    }
-  }
-
-  test_const_reference_staticField_imported_withPrefix() async {
-    addLibrarySource('/a.dart', r'''
-class C {
-  static const int F = 42;
-}
-''');
-    var library = await checkLibrary(r'''
-import 'a.dart' as p;
-const V = p.C.F;
-''');
-    if (isStrongMode) {
-      if (isSharedFrontEnd) {
-        checkElementText(library, r'''
-import 'a.dart' as p;
-const int V =
-        C/*location: a.dart;C*/.
-        F/*location: a.dart;C;F?*/;
-''');
-      } else {
-        checkElementText(library, r'''
-import 'a.dart' as p;
-const int V =
-        p/*location: test.dart;p*/.
-        C/*location: a.dart;C*/.
-        F/*location: a.dart;C;F?*/;
-''');
-      }
-    } else {
-      checkElementText(library, r'''
-import 'a.dart' as p;
-const dynamic V =
-        p/*location: test.dart;p*/.
-        C/*location: a.dart;C*/.
-        F/*location: a.dart;C;F?*/;
-''');
-    }
-  }
-
-  test_const_reference_staticMethod() async {
-    var library = await checkLibrary(r'''
-class C {
-  static int m(int a, String b) => 42;
-}
-const V = C.m;
-''');
-    if (isStrongMode) {
-      checkElementText(library, r'''
-class C {
-  static int m(int a, String b) {}
-}
-const (int, String) → int V =
-        C/*location: test.dart;C*/.
-        m/*location: test.dart;C;m*/;
-''');
-    } else {
-      checkElementText(library, r'''
-class C {
-  static int m(int a, String b) {}
-}
-const dynamic V =
-        C/*location: test.dart;C*/.
-        m/*location: test.dart;C;m*/;
-''');
-    }
-  }
-
-  test_const_reference_staticMethod_imported() async {
-    addLibrarySource('/a.dart', r'''
-class C {
-  static int m(int a, String b) => 42;
-}
-''');
-    var library = await checkLibrary(r'''
-import 'a.dart';
-const V = C.m;
-''');
-    if (isStrongMode) {
-      checkElementText(library, r'''
-import 'a.dart';
-const (int, String) → int V =
-        C/*location: a.dart;C*/.
-        m/*location: a.dart;C;m*/;
-''');
-    } else {
-      checkElementText(library, r'''
-import 'a.dart';
-const dynamic V =
-        C/*location: a.dart;C*/.
-        m/*location: a.dart;C;m*/;
-''');
-    }
-  }
-
-  test_const_reference_staticMethod_imported_withPrefix() async {
-    addLibrarySource('/a.dart', r'''
-class C {
-  static int m(int a, String b) => 42;
-}
-''');
-    var library = await checkLibrary(r'''
-import 'a.dart' as p;
-const V = p.C.m;
-''');
-    if (isStrongMode) {
-      if (isSharedFrontEnd) {
-        checkElementText(library, r'''
-import 'a.dart' as p;
-const (int, String) → int V =
-        C/*location: a.dart;C*/.
-        m/*location: a.dart;C;m*/;
-''');
-      } else {
-        checkElementText(library, r'''
-import 'a.dart' as p;
-const (int, String) → int V =
-        p/*location: test.dart;p*/.
-        C/*location: a.dart;C*/.
-        m/*location: a.dart;C;m*/;
-''');
-      }
-    } else {
-      checkElementText(library, r'''
-import 'a.dart' as p;
-const dynamic V =
-        p/*location: test.dart;p*/.
-        C/*location: a.dart;C*/.
-        m/*location: a.dart;C;m*/;
-''');
-    }
-  }
-
-  test_const_reference_topLevelFunction() async {
-    var library = await checkLibrary(r'''
-foo() {}
-const V = foo;
-''');
-    if (isStrongMode) {
-      checkElementText(library, r'''
-const () → dynamic V =
-        foo/*location: test.dart;foo*/;
-dynamic foo() {}
-''');
-    } else {
-      checkElementText(library, r'''
-const dynamic V =
-        foo/*location: test.dart;foo*/;
-dynamic foo() {}
-''');
-    }
-  }
-
-  test_const_reference_topLevelFunction_generic() async {
-    var library = await checkLibrary(r'''
-R foo<P, R>(P p) {}
-const V = foo;
-''');
-    if (isStrongMode) {
-      checkElementText(library, r'''
-const <P,R>(P) → R V =
-        foo/*location: test.dart;foo*/;
-R foo<P, R>(P p) {}
-''');
-    } else {
-      checkElementText(library, r'''
-const dynamic V =
-        foo/*location: test.dart;foo*/;
-R foo<P, R>(P p) {}
-''');
-    }
-  }
-
-  test_const_reference_topLevelFunction_imported() async {
-    addLibrarySource('/a.dart', r'''
-foo() {}
-''');
-    var library = await checkLibrary(r'''
-import 'a.dart';
-const V = foo;
-''');
-    if (isStrongMode) {
-      checkElementText(library, r'''
-import 'a.dart';
-const () → dynamic V =
-        foo/*location: a.dart;foo*/;
-''');
-    } else {
-      checkElementText(library, r'''
-import 'a.dart';
-const dynamic V =
-        foo/*location: a.dart;foo*/;
-''');
-    }
-  }
-
-  test_const_reference_topLevelFunction_imported_withPrefix() async {
-    addLibrarySource('/a.dart', r'''
-foo() {}
-''');
-    var library = await checkLibrary(r'''
-import 'a.dart' as p;
-const V = p.foo;
-''');
-    if (isStrongMode) {
-      if (isSharedFrontEnd) {
-        checkElementText(library, r'''
-import 'a.dart' as p;
-const () → dynamic V =
-        foo/*location: a.dart;foo*/;
-''');
-      } else {
-        checkElementText(library, r'''
-import 'a.dart' as p;
-const () → dynamic V =
-        p/*location: test.dart;p*/.
-        foo/*location: a.dart;foo*/;
-''');
-      }
-    } else {
-      checkElementText(library, r'''
-import 'a.dart' as p;
-const dynamic V =
-        p/*location: test.dart;p*/.
-        foo/*location: a.dart;foo*/;
-''');
-    }
-  }
-
-  test_const_reference_topLevelVariable() async {
-    var library = await checkLibrary(r'''
-const A = 1;
-const B = A + 2;
-''');
-    if (isStrongMode) {
-      checkElementText(library, r'''
-const int A = 1;
-const int B =
-        A/*location: test.dart;A?*/ + 2;
-''');
-    } else {
-      checkElementText(library, r'''
-const dynamic A = 1;
-const dynamic B =
-        A/*location: test.dart;A?*/ + 2;
-''');
-    }
-  }
-
-  test_const_reference_topLevelVariable_imported() async {
-    addLibrarySource('/a.dart', r'''
-const A = 1;
-''');
-    var library = await checkLibrary(r'''
-import 'a.dart';
-const B = A + 2;
-''');
-    if (isStrongMode) {
-      checkElementText(library, r'''
-import 'a.dart';
-const int B =
-        A/*location: a.dart;A?*/ + 2;
-''');
-    } else {
-      checkElementText(library, r'''
-import 'a.dart';
-const dynamic B =
-        A/*location: a.dart;A?*/ + 2;
-''');
-    }
-  }
-
-  test_const_reference_topLevelVariable_imported_withPrefix() async {
-    addLibrarySource('/a.dart', r'''
-const A = 1;
-''');
-    var library = await checkLibrary(r'''
-import 'a.dart' as p;
-const B = p.A + 2;
-''');
-    if (isStrongMode) {
-      if (isSharedFrontEnd) {
-        checkElementText(library, r'''
-import 'a.dart' as p;
-const int B =
-        A/*location: a.dart;A?*/ + 2;
-''');
-      } else {
-        checkElementText(library, r'''
-import 'a.dart' as p;
-const int B =
-        p/*location: test.dart;p*/.
-        A/*location: a.dart;A?*/ + 2;
-''');
-      }
-    } else {
-      checkElementText(library, r'''
-import 'a.dart' as p;
-const dynamic B =
-        p/*location: test.dart;p*/.
-        A/*location: a.dart;A?*/ + 2;
-''');
-    }
-  }
-
-  test_const_reference_type() async {
-    var library = await checkLibrary(r'''
-class C {}
-class D<T> {}
-enum E {a, b, c}
-typedef F(int a, String b);
-const vDynamic = dynamic;
-const vNull = Null;
-const vObject = Object;
-const vClass = C;
-const vGenericClass = D;
-const vEnum = E;
-const vFunctionTypeAlias = F;
-''');
-    if (isStrongMode) {
-      checkElementText(library, r'''
-typedef F = dynamic Function(int a, String b);
-enum E {
-  synthetic final int index;
-  synthetic static const List<E> values;
-  static const E a;
-  static const E b;
-  static const E c;
-  String toString() {}
-}
-class C {
-}
-class D<T> {
-}
-const Type vDynamic =
-        dynamic/*location: dynamic*/;
-const Type vNull =
-        Null/*location: dart:core;Null*/;
-const Type vObject =
-        Object/*location: dart:core;Object*/;
-const Type vClass =
-        C/*location: test.dart;C*/;
-const Type vGenericClass =
-        D/*location: test.dart;D*/;
-const Type vEnum =
-        E/*location: test.dart;E*/;
-const Type vFunctionTypeAlias =
-        F/*location: test.dart;F*/;
-''');
-    } else {
-      checkElementText(library, r'''
-typedef F = dynamic Function(int a, String b);
-enum E {
-  synthetic final int index;
-  synthetic static const List<E> values;
-  static const E a;
-  static const E b;
-  static const E c;
-  String toString() {}
-}
-class C {
-}
-class D<T> {
-}
-const dynamic vDynamic =
-        dynamic/*location: dynamic*/;
-const dynamic vNull =
-        Null/*location: dart:core;Null*/;
-const dynamic vObject =
-        Object/*location: dart:core;Object*/;
-const dynamic vClass =
-        C/*location: test.dart;C*/;
-const dynamic vGenericClass =
-        D/*location: test.dart;D*/;
-const dynamic vEnum =
-        E/*location: test.dart;E*/;
-const dynamic vFunctionTypeAlias =
-        F/*location: test.dart;F*/;
-''');
-    }
-  }
-
-  test_const_reference_type_functionType() async {
-    var library = await checkLibrary(r'''
-typedef F();
-class C {
-  final f = <F>[];
-}
-''');
-    if (isStrongMode) {
-      checkElementText(library, r'''
-typedef F = dynamic Function();
-class C {
-  final List<() → dynamic> f;
-}
-''');
-    } else {
-      checkElementText(library, r'''
-typedef F = dynamic Function();
-class C {
-  final dynamic f;
-}
-''');
-    }
-  }
-
-  test_const_reference_type_imported() async {
-    addLibrarySource('/a.dart', r'''
-class C {}
-enum E {a, b, c}
-typedef F(int a, String b);
-''');
-    var library = await checkLibrary(r'''
-import 'a.dart';
-const vClass = C;
-const vEnum = E;
-const vFunctionTypeAlias = F;
-''');
-    if (isStrongMode) {
-      checkElementText(library, r'''
-import 'a.dart';
-const Type vClass =
-        C/*location: a.dart;C*/;
-const Type vEnum =
-        E/*location: a.dart;E*/;
-const Type vFunctionTypeAlias =
-        F/*location: a.dart;F*/;
-''');
-    } else {
-      checkElementText(library, r'''
-import 'a.dart';
-const dynamic vClass =
-        C/*location: a.dart;C*/;
-const dynamic vEnum =
-        E/*location: a.dart;E*/;
-const dynamic vFunctionTypeAlias =
-        F/*location: a.dart;F*/;
-''');
-    }
-  }
-
-  test_const_reference_type_imported_withPrefix() async {
-    addLibrarySource('/a.dart', r'''
-class C {}
-enum E {a, b, c}
-typedef F(int a, String b);
-''');
-    var library = await checkLibrary(r'''
-import 'a.dart' as p;
-const vClass = p.C;
-const vEnum = p.E;
-const vFunctionTypeAlias = p.F;
-''');
-    if (isStrongMode) {
-      if (isSharedFrontEnd) {
-        checkElementText(library, r'''
-import 'a.dart' as p;
-const Type vClass =
-        C/*location: a.dart;C*/;
-const Type vEnum =
-        E/*location: a.dart;E*/;
-const Type vFunctionTypeAlias =
-        F/*location: a.dart;F*/;
-''');
-      } else {
-        checkElementText(library, r'''
-import 'a.dart' as p;
-const Type vClass =
-        p/*location: test.dart;p*/.
-        C/*location: a.dart;C*/;
-const Type vEnum =
-        p/*location: test.dart;p*/.
-        E/*location: a.dart;E*/;
-const Type vFunctionTypeAlias =
-        p/*location: test.dart;p*/.
-        F/*location: a.dart;F*/;
-''');
-      }
-    } else {
-      checkElementText(library, r'''
-import 'a.dart' as p;
-const dynamic vClass =
-        p/*location: test.dart;p*/.
-        C/*location: a.dart;C*/;
-const dynamic vEnum =
-        p/*location: test.dart;p*/.
-        E/*location: a.dart;E*/;
-const dynamic vFunctionTypeAlias =
-        p/*location: test.dart;p*/.
-        F/*location: a.dart;F*/;
-''');
-    }
-  }
-
-  test_const_reference_type_typeParameter() async {
-    var library = await checkLibrary(r'''
-class C<T> {
-  final f = <T>[];
-}
-''');
-    if (isStrongMode) {
-      checkElementText(library, r'''
-class C<T> {
-  final List<T> f;
-}
-''');
-    } else {
-      checkElementText(library, r'''
-class C<T> {
-  final dynamic f;
-}
-''');
-    }
-  }
-
-  test_const_reference_unresolved_prefix0() async {
-    shouldCompareLibraryElements = false;
-    var library = await checkLibrary(r'''
-const V = foo;
-''', allowErrors: true);
-    checkElementText(library, r'''
-const dynamic V = #invalidConst;
-''');
-  }
-
-  test_const_reference_unresolved_prefix1() async {
-    shouldCompareLibraryElements = false;
-    var library = await checkLibrary(r'''
-class C {}
-const V = C.foo;
-''', allowErrors: true);
-    checkElementText(library, r'''
-class C {
-}
-const dynamic V = #invalidConst;
-''');
-  }
-
-  test_const_reference_unresolved_prefix2() async {
-    shouldCompareLibraryElements = false;
-    addLibrarySource('/foo.dart', '''
-class C {}
-''');
-    var library = await checkLibrary(r'''
-import 'foo.dart' as p;
-const V = p.C.foo;
-''', allowErrors: true);
-    checkElementText(library, r'''
-import 'foo.dart' as p;
-const dynamic V = #invalidConst;
-''');
-  }
-
-  test_const_topLevel_binary() async {
-    var library = await checkLibrary(r'''
-const vEqual = 1 == 2;
-const vAnd = true && false;
-const vOr = false || true;
-const vBitXor = 1 ^ 2;
-const vBitAnd = 1 & 2;
-const vBitOr = 1 | 2;
-const vBitShiftLeft = 1 << 2;
-const vBitShiftRight = 1 >> 2;
-const vAdd = 1 + 2;
-const vSubtract = 1 - 2;
-const vMiltiply = 1 * 2;
-const vDivide = 1 / 2;
-const vFloorDivide = 1 ~/ 2;
-const vModulo = 1 % 2;
-const vGreater = 1 > 2;
-const vGreaterEqual = 1 >= 2;
-const vLess = 1 < 2;
-const vLessEqual = 1 <= 2;
-''');
-    if (isStrongMode) {
-      checkElementText(library, r'''
-const bool vEqual = 1 == 2;
-const bool vAnd = true && false;
-const bool vOr = false || true;
-const int vBitXor = 1 ^ 2;
-const int vBitAnd = 1 & 2;
-const int vBitOr = 1 | 2;
-const int vBitShiftLeft = 1 << 2;
-const int vBitShiftRight = 1 >> 2;
-const int vAdd = 1 + 2;
-const int vSubtract = 1 - 2;
-const int vMiltiply = 1 * 2;
-const double vDivide = 1 / 2;
-const int vFloorDivide = 1 ~/ 2;
-const int vModulo = 1 % 2;
-const bool vGreater = 1 > 2;
-const bool vGreaterEqual = 1 >= 2;
-const bool vLess = 1 < 2;
-const bool vLessEqual = 1 <= 2;
-''');
-    } else {
-      checkElementText(library, r'''
-const dynamic vEqual = 1 == 2;
-const dynamic vAnd = true && false;
-const dynamic vOr = false || true;
-const dynamic vBitXor = 1 ^ 2;
-const dynamic vBitAnd = 1 & 2;
-const dynamic vBitOr = 1 | 2;
-const dynamic vBitShiftLeft = 1 << 2;
-const dynamic vBitShiftRight = 1 >> 2;
-const dynamic vAdd = 1 + 2;
-const dynamic vSubtract = 1 - 2;
-const dynamic vMiltiply = 1 * 2;
-const dynamic vDivide = 1 / 2;
-const dynamic vFloorDivide = 1 ~/ 2;
-const dynamic vModulo = 1 % 2;
-const dynamic vGreater = 1 > 2;
-const dynamic vGreaterEqual = 1 >= 2;
-const dynamic vLess = 1 < 2;
-const dynamic vLessEqual = 1 <= 2;
-''');
-    }
-  }
-
-  test_const_topLevel_conditional() async {
-    var library = await checkLibrary(r'''
-const vConditional = (1 == 2) ? 11 : 22;
-''');
-    if (isStrongMode) {
-      checkElementText(library, r'''
-const int vConditional = 1 == 2 ? 11 : 22;
-''');
-    } else {
-      checkElementText(library, r'''
-const dynamic vConditional = 1 == 2 ? 11 : 22;
-''');
-    }
-  }
-
-  test_const_topLevel_identical() async {
-    var library = await checkLibrary(r'''
-const vIdentical = (1 == 2) ? 11 : 22;
-''');
-    if (isStrongMode) {
-      checkElementText(library, r'''
-const int vIdentical = 1 == 2 ? 11 : 22;
-''');
-    } else {
-      checkElementText(library, r'''
-const dynamic vIdentical = 1 == 2 ? 11 : 22;
-''');
-    }
-  }
-
-  test_const_topLevel_ifNull() async {
-    var library = await checkLibrary(r'''
-const vIfNull = 1 ?? 2.0;
-''');
-    if (isStrongMode) {
-      checkElementText(library, r'''
-const num vIfNull = 1 ?? 2.0;
-''');
-    } else {
-      checkElementText(library, r'''
-const dynamic vIfNull = 1 ?? 2.0;
-''');
-    }
-  }
-
-  test_const_topLevel_literal() async {
-    var library = await checkLibrary(r'''
-const vNull = null;
-const vBoolFalse = false;
-const vBoolTrue = true;
-const vInt = 1;
-const vIntLong1 = 0x7FFFFFFFFFFFFFFF;
-const vIntLong2 = 0xFFFFFFFFFFFFFFFF;
-const vDouble = 2.3;
-const vString = 'abc';
-const vStringConcat = 'aaa' 'bbb';
-const vStringInterpolation = 'aaa ${true} ${42} bbb';
-const vSymbol = #aaa.bbb.ccc;
-''');
-    if (isStrongMode) {
-      checkElementText(library, r'''
-const dynamic vNull = null;
-const bool vBoolFalse = false;
-const bool vBoolTrue = true;
-const int vInt = 1;
-const int vIntLong1 = 9223372036854775807;
-const int vIntLong2 = -1;
-const double vDouble = 2.3;
-const String vString = 'abc';
-const String vStringConcat = 'aaabbb';
-const String vStringInterpolation = 'aaa ${true} ${42} bbb';
-const Symbol vSymbol = #aaa.bbb.ccc;
-''');
-    } else {
-      checkElementText(library, r'''
-const dynamic vNull = null;
-const dynamic vBoolFalse = false;
-const dynamic vBoolTrue = true;
-const dynamic vInt = 1;
-const dynamic vIntLong1 = 9223372036854775807;
-const dynamic vIntLong2 = -1;
-const dynamic vDouble = 2.3;
-const dynamic vString = 'abc';
-const dynamic vStringConcat = 'aaabbb';
-const dynamic vStringInterpolation = 'aaa ${true} ${42} bbb';
-const dynamic vSymbol = #aaa.bbb.ccc;
-''');
-    }
-  }
-
-  test_const_topLevel_parenthesis() async {
-    var library = await checkLibrary(r'''
-const int v1 = (1 + 2) * 3;
-const int v2 = -(1 + 2);
-const int v3 = ('aaa' + 'bbb').length;
-''');
-    checkElementText(library, r'''
-const int v1 = (1 + 2) * 3;
-const int v2 = -(1 + 2);
-const int v3 = ('aaa' + 'bbb').
-        length/*location: dart:core;String;length?*/;
-''');
-  }
-
-  test_const_topLevel_prefix() async {
-    var library = await checkLibrary(r'''
-const vNotEqual = 1 != 2;
-const vNot = !true;
-const vNegate = -1;
-const vComplement = ~1;
-''');
-    if (isStrongMode) {
-      if (isSharedFrontEnd) {
-        checkElementText(library, r'''
-const bool vNotEqual = !(1 == 2);
-const bool vNot = !true;
-const int vNegate = -1;
-const int vComplement = ~1;
-''');
-      } else {
-        checkElementText(library, r'''
-const bool vNotEqual = 1 != 2;
-const bool vNot = !true;
-const int vNegate = -1;
-const int vComplement = ~1;
-''');
-      }
-    } else {
-      checkElementText(library, r'''
-const dynamic vNotEqual = 1 != 2;
-const dynamic vNot = !true;
-const dynamic vNegate = -1;
-const dynamic vComplement = ~1;
-''');
-    }
-  }
-
-  test_const_topLevel_super() async {
-    shouldCompareLibraryElements = false;
-    var library = await checkLibrary(r'''
-const vSuper = super;
-''');
-    checkElementText(library, r'''
-const dynamic vSuper = #invalidConst;
-''');
-  }
-
-  test_const_topLevel_this() async {
-    shouldCompareLibraryElements = false;
-    var library = await checkLibrary(r'''
-const vThis = this;
-''');
-    checkElementText(library, r'''
-const dynamic vThis = #invalidConst;
-''');
-  }
-
-  test_const_topLevel_throw() async {
-    shouldCompareLibraryElements = false;
-    var library = await checkLibrary(r'''
-const c = throw 42;
-''');
-    if (isSharedFrontEnd) {
-      checkElementText(library, r'''
-const dynamic c = #invalidConst;
-''');
-    } else {
-      // This is a bug.
-      checkElementText(library, r'''
-const dynamic c;
-''');
-    }
-  }
-
-  test_const_topLevel_typedList() async {
-    var library = await checkLibrary(r'''
-const vNull = const <Null>[];
-const vDynamic = const <dynamic>[1, 2, 3];
-const vInterfaceNoTypeParameters = const <int>[1, 2, 3];
-const vInterfaceNoTypeArguments = const <List>[];
-const vInterfaceWithTypeArguments = const <List<String>>[];
-const vInterfaceWithTypeArguments2 = const <Map<int, List<String>>>[];
-''');
-    if (isStrongMode) {
-      checkElementText(library, r'''
-const List<Null> vNull = const <
-        Null/*location: dart:core;Null*/>[];
-const List<dynamic> vDynamic = const <
-        dynamic/*location: dynamic*/>[1, 2, 3];
-const List<int> vInterfaceNoTypeParameters = const <
-        int/*location: dart:core;int*/>[1, 2, 3];
-const List<List<dynamic>> vInterfaceNoTypeArguments = const <
-        List/*location: dart:core;List*/>[];
-const List<List<String>> vInterfaceWithTypeArguments = const <
-        List/*location: dart:core;List*/<
-        String/*location: dart:core;String*/>>[];
-const List<Map<int, List<String>>> vInterfaceWithTypeArguments2 = const <
-        Map/*location: dart:core;Map*/<
-        int/*location: dart:core;int*/,
-        List/*location: dart:core;List*/<
-        String/*location: dart:core;String*/>>>[];
-''');
-    } else {
-      checkElementText(library, r'''
-const dynamic vNull = const <
-        Null/*location: dart:core;Null*/>[];
-const dynamic vDynamic = const <
-        dynamic/*location: dynamic*/>[1, 2, 3];
-const dynamic vInterfaceNoTypeParameters = const <
-        int/*location: dart:core;int*/>[1, 2, 3];
-const dynamic vInterfaceNoTypeArguments = const <
-        List/*location: dart:core;List*/>[];
-const dynamic vInterfaceWithTypeArguments = const <
-        List/*location: dart:core;List*/<
-        String/*location: dart:core;String*/>>[];
-const dynamic vInterfaceWithTypeArguments2 = const <
-        Map/*location: dart:core;Map*/<
-        int/*location: dart:core;int*/,
-        List/*location: dart:core;List*/<
-        String/*location: dart:core;String*/>>>[];
-''');
-    }
-  }
-
-  test_const_topLevel_typedList_imported() async {
-    addLibrarySource('/a.dart', 'class C {}');
-    var library = await checkLibrary(r'''
-import 'a.dart';
-const v = const <C>[];
-''');
-    if (isStrongMode) {
-      checkElementText(library, r'''
-import 'a.dart';
-const List<C> v = const <
-        C/*location: a.dart;C*/>[];
-''');
-    } else {
-      checkElementText(library, r'''
-import 'a.dart';
-const dynamic v = const <
-        C/*location: a.dart;C*/>[];
-''');
-    }
-  }
-
-  test_const_topLevel_typedList_importedWithPrefix() async {
-    addLibrarySource('/a.dart', 'class C {}');
-    var library = await checkLibrary(r'''
-import 'a.dart' as p;
-const v = const <p.C>[];
-''');
-    if (isStrongMode) {
-      checkElementText(library, r'''
-import 'a.dart' as p;
-const List<C> v = const <
-        C/*location: a.dart;C*/>[];
-''');
-    } else {
-      checkElementText(library, r'''
-import 'a.dart' as p;
-const dynamic v = const <
-        C/*location: a.dart;C*/>[];
-''');
-    }
-  }
-
-  test_const_topLevel_typedList_typedefArgument() async {
-    shouldCompareLibraryElements = false;
-    var library = await checkLibrary(r'''
-typedef int F(String id);
-const v = const <F>[];
-''');
-    if (isStrongMode) {
-      checkElementText(library, r'''
-typedef F = int Function(String id);
-const List<(String) → int> v = const <
-        null/*location: test.dart;F;-*/>[];
-''');
-    } else {
-      checkElementText(library, r'''
-typedef F = int Function(String id);
-const dynamic v = const <
-        null/*location: test.dart;F;-*/>[];
-''');
-    }
-  }
-
-  test_const_topLevel_typedMap() async {
-    var library = await checkLibrary(r'''
-const vDynamic1 = const <dynamic, int>{};
-const vDynamic2 = const <int, dynamic>{};
-const vInterface = const <int, String>{};
-const vInterfaceWithTypeArguments = const <int, List<String>>{};
-''');
-    if (isStrongMode) {
-      checkElementText(library, r'''
-const Map<dynamic, int> vDynamic1 = const <
-        dynamic/*location: dynamic*/,
-        int/*location: dart:core;int*/>{};
-const Map<int, dynamic> vDynamic2 = const <
-        int/*location: dart:core;int*/,
-        dynamic/*location: dynamic*/>{};
-const Map<int, String> vInterface = const <
-        int/*location: dart:core;int*/,
-        String/*location: dart:core;String*/>{};
-const Map<int, List<String>> vInterfaceWithTypeArguments = const <
-        int/*location: dart:core;int*/,
-        List/*location: dart:core;List*/<
-        String/*location: dart:core;String*/>>{};
-''');
-    } else {
-      checkElementText(library, r'''
-const dynamic vDynamic1 = const <
-        dynamic/*location: dynamic*/,
-        int/*location: dart:core;int*/>{};
-const dynamic vDynamic2 = const <
-        int/*location: dart:core;int*/,
-        dynamic/*location: dynamic*/>{};
-const dynamic vInterface = const <
-        int/*location: dart:core;int*/,
-        String/*location: dart:core;String*/>{};
-const dynamic vInterfaceWithTypeArguments = const <
-        int/*location: dart:core;int*/,
-        List/*location: dart:core;List*/<
-        String/*location: dart:core;String*/>>{};
-''');
-    }
-  }
-
-  test_const_topLevel_untypedList() async {
-    var library = await checkLibrary(r'''
-const v = const [1, 2, 3];
-''');
-    if (isStrongMode) {
-      if (isSharedFrontEnd) {
-        checkElementText(library, r'''
-const List<int> v = const <
-        int/*location: dart:core;int*/>[1, 2, 3];
-''');
-      } else {
-        checkElementText(library, r'''
-const List<int> v = const [1, 2, 3];
-''');
-      }
-    } else {
-      checkElementText(library, r'''
-const dynamic v = const [1, 2, 3];
-''');
-    }
-  }
-
-  test_const_topLevel_untypedMap() async {
-    var library = await checkLibrary(r'''
-const v = const {0: 'aaa', 1: 'bbb', 2: 'ccc'};
-''');
-    if (isStrongMode) {
-      if (isSharedFrontEnd) {
-        checkElementText(library, r'''
-const Map<int, String> v = const <
-        int/*location: dart:core;int*/,
-        String/*location: dart:core;String*/>{0: 'aaa', 1: 'bbb', 2: 'ccc'};
-''');
-      } else {
-        checkElementText(library, r'''
-const Map<int, String> v = const {0: 'aaa', 1: 'bbb', 2: 'ccc'};
-''');
-      }
-    } else {
-      checkElementText(library, r'''
-const dynamic v = const {0: 'aaa', 1: 'bbb', 2: 'ccc'};
-''');
-    }
-  }
-
-  test_constExpr_pushReference_enum_field() async {
-    var library = await checkLibrary('''
-enum E {a, b, c}
-final vValue = E.a;
-final vValues = E.values;
-final vIndex = E.a.index;
-''');
-    if (isStrongMode) {
-      checkElementText(library, r'''
-enum E {
-  synthetic final int index;
-  synthetic static const List<E> values;
-  static const E a;
-  static const E b;
-  static const E c;
-  String toString() {}
-}
-final E vValue;
-final List<E> vValues;
-final int vIndex;
-''');
-    } else {
-      checkElementText(library, r'''
-enum E {
-  synthetic final int index;
-  synthetic static const List<E> values;
-  static const E a;
-  static const E b;
-  static const E c;
-  String toString() {}
-}
-final dynamic vValue;
-final dynamic vValues;
-final dynamic vIndex;
-''');
-    }
-  }
-
-  test_constExpr_pushReference_enum_method() async {
-    var library = await checkLibrary('''
-enum E {a}
-final vToString = E.a.toString();
-''');
-    if (isStrongMode) {
-      checkElementText(library, r'''
-enum E {
-  synthetic final int index;
-  synthetic static const List<E> values;
-  static const E a;
-  String toString() {}
-}
-final String vToString;
-''');
-    } else {
-      checkElementText(library, r'''
-enum E {
-  synthetic final int index;
-  synthetic static const List<E> values;
-  static const E a;
-  String toString() {}
-}
-final dynamic vToString;
-''');
-    }
-  }
-
-  test_constExpr_pushReference_field_simpleIdentifier() async {
-    var library = await checkLibrary('''
-class C {
-  static const a = b;
-  static const b = null;
-}
-''');
-    checkElementText(library, r'''
-class C {
-  static const dynamic a =
-        C/*location: test.dart;C*/.
-        b/*location: test.dart;C;b?*/;
-  static const dynamic b = null;
-}
-''');
-  }
-
-  test_constExpr_pushReference_staticMethod_simpleIdentifier() async {
-    var library = await checkLibrary('''
-class C {
-  static const a = m;
-  static m() {}
-}
-''');
-    if (isStrongMode) {
-      checkElementText(library, r'''
-class C {
-  static const () → dynamic a =
-        C/*location: test.dart;C*/.
-        m/*location: test.dart;C;m*/;
-  static dynamic m() {}
-}
-''');
-    } else {
-      checkElementText(library, r'''
-class C {
-  static const dynamic a =
-        C/*location: test.dart;C*/.
-        m/*location: test.dart;C;m*/;
-  static dynamic m() {}
-}
-''');
-    }
-  }
-
-  test_constructor_documented() async {
-    var library = await checkLibrary('''
-class C {
-  /**
-   * Docs
-   */
-  C();
-}''');
-    checkElementText(library, r'''
-class C {
-  /**
-   * Docs
-   */
-  C();
-}
-''');
-  }
-
-  test_constructor_initializers_assertInvocation() async {
-    var library = await checkLibrary('''
-class C {
-  const C(int x) : assert(x >= 42);
-}
-''');
-    checkElementText(library, r'''
-class C {
-  const C(int x) : assert(
-        x/*location: test.dart;C;;x*/ >= 42);
-}
-''');
-  }
-
-  test_constructor_initializers_assertInvocation_message() async {
-    var library = await checkLibrary('''
-class C {
-  const C(int x) : assert(x >= 42, 'foo');
-}
-''');
-    checkElementText(library, r'''
-class C {
-  const C(int x) : assert(
-        x/*location: test.dart;C;;x*/ >= 42, 'foo');
-}
-''');
-  }
-
-  test_constructor_initializers_field() async {
-    var library = await checkLibrary('''
-class C {
-  final x;
-  const C() : x = 42;
-}
-''');
-    checkElementText(library, r'''
-class C {
-  final dynamic x;
-  const C() :
-        x/*location: test.dart;C;x*/ = 42;
-}
-''');
-  }
-
-  test_constructor_initializers_field_notConst() async {
-    shouldCompareLibraryElements = false;
-    var library = await checkLibrary('''
-class C {
-  final x;
-  const C() : x = foo();
-}
-int foo() => 42;
-''', allowErrors: true);
-    if (isSharedFrontEnd) {
-      checkElementText(library, r'''
-class C {
-  final dynamic x;
-  const C() :
-        x/*location: test.dart;C;x*/ = #invalidConst;
-}
-int foo() {}
-''');
-    } else {
-      // It is OK to keep non-constant initializers.
-      checkElementText(library, r'''
-class C {
-  final dynamic x;
-  const C() :
-        x/*location: test.dart;C;x*/ =
-        foo/*location: test.dart;foo*/();
-}
-int foo() {}
-''');
-    }
-  }
-
-  test_constructor_initializers_field_withParameter() async {
-    var library = await checkLibrary('''
-class C {
-  final x;
-  const C(int p) : x = 1 + p;
-}
-''');
-    checkElementText(library, r'''
-class C {
-  final dynamic x;
-  const C(int p) :
-        x/*location: test.dart;C;x*/ = 1 +
-        p/*location: test.dart;C;;p*/;
-}
-''');
-  }
-
-  test_constructor_initializers_superInvocation_named() async {
-    var library = await checkLibrary('''
-class A {
-  const A.aaa(int p);
-}
-class C extends A {
-  const C() : super.aaa(42);
-}
-''');
-    checkElementText(library, r'''
-class A {
-  const A.aaa(int p);
-}
-class C extends A {
-  const C() : super.
-        aaa/*location: test.dart;A;aaa*/(42);
-}
-''');
-  }
-
-  test_constructor_initializers_superInvocation_named_underscore() async {
-    var library = await checkLibrary('''
-class A {
-  const A._();
-}
-class B extends A {
-  const B() : super._();
-}
-''');
-    checkElementText(library, r'''
-class A {
-  const A._();
-}
-class B extends A {
-  const B() : super.
-        _/*location: test.dart;A;_*/();
-}
-''');
-  }
-
-  test_constructor_initializers_superInvocation_namedExpression() async {
-    var library = await checkLibrary('''
-class A {
-  const A.aaa(a, {int b});
-}
-class C extends A {
-  const C() : super.aaa(1, b: 2);
-}
-''');
-    checkElementText(library, r'''
-class A {
-  const A.aaa(dynamic a, {int b});
-}
-class C extends A {
-  const C() : super.
-        aaa/*location: test.dart;A;aaa*/(1,
-        b/*location: null*/: 2);
-}
-''');
-  }
-
-  test_constructor_initializers_superInvocation_unnamed() async {
-    var library = await checkLibrary('''
-class A {
-  const A(int p);
-}
-class C extends A {
-  const C.ccc() : super(42);
-}
-''');
-    checkElementText(library, r'''
-class A {
-  const A(int p);
-}
-class C extends A {
-  const C.ccc() : super(42);
-}
-''');
-  }
-
-  test_constructor_initializers_thisInvocation_named() async {
-    var library = await checkLibrary('''
-class C {
-  const C() : this.named(1, 'bbb');
-  const C.named(int a, String b);
-}
-''');
-    checkElementText(library, r'''
-class C {
-  const C() = C.named : this.
-        named/*location: test.dart;C;named*/(1, 'bbb');
-  const C.named(int a, String b);
-}
-''');
-  }
-
-  test_constructor_initializers_thisInvocation_namedExpression() async {
-    var library = await checkLibrary('''
-class C {
-  const C() : this.named(1, b: 2);
-  const C.named(a, {int b});
-}
-''');
-    checkElementText(library, r'''
-class C {
-  const C() = C.named : this.
-        named/*location: test.dart;C;named*/(1,
-        b/*location: null*/: 2);
-  const C.named(dynamic a, {int b});
-}
-''');
-  }
-
-  test_constructor_initializers_thisInvocation_unnamed() async {
-    var library = await checkLibrary('''
-class C {
-  const C.named() : this(1, 'bbb');
-  const C(int a, String b);
-}
-''');
-    checkElementText(library, r'''
-class C {
-  const C.named() = C : this(1, 'bbb');
-  const C(int a, String b);
-}
-''');
-  }
-
-  test_constructor_redirected_factory_named() async {
-    var library = await checkLibrary('''
-class C {
-  factory C() = D.named;
-  C._();
-}
-class D extends C {
-  D.named() : super._();
-}
-''');
-    checkElementText(library, r'''
-class C {
-  factory C() = D.named;
-  C._();
-}
-class D extends C {
-  D.named();
-}
-''');
-  }
-
-  test_constructor_redirected_factory_named_generic() async {
-    var library = await checkLibrary('''
-class C<T, U> {
-  factory C() = D<U, T>.named;
-  C._();
-}
-class D<T, U> extends C<U, T> {
-  D.named() : super._();
-}
-''');
-    checkElementText(library, r'''
-class C<T, U> {
-  factory C() = D<U, T>.named;
-  C._();
-}
-class D<T, U> extends C<U, T> {
-  D.named();
-}
-''');
-  }
-
-  test_constructor_redirected_factory_named_imported() async {
-    addLibrarySource('/foo.dart', '''
-import 'test.dart';
-class D extends C {
-  D.named() : super._();
-}
-''');
-    var library = await checkLibrary('''
-import 'foo.dart';
-class C {
-  factory C() = D.named;
-  C._();
-}
-''');
-    checkElementText(library, r'''
-import 'foo.dart';
-class C {
-  factory C() = D.named;
-  C._();
-}
-''');
-  }
-
-  test_constructor_redirected_factory_named_imported_generic() async {
-    addLibrarySource('/foo.dart', '''
-import 'test.dart';
-class D<T, U> extends C<U, T> {
-  D.named() : super._();
-}
-''');
-    var library = await checkLibrary('''
-import 'foo.dart';
-class C<T, U> {
-  factory C() = D<U, T>.named;
-  C._();
-}
-''');
-    checkElementText(library, r'''
-import 'foo.dart';
-class C<T, U> {
-  factory C() = D<U, T>.named;
-  C._();
-}
-''');
-  }
-
-  test_constructor_redirected_factory_named_prefixed() async {
-    addLibrarySource('/foo.dart', '''
-import 'test.dart';
-class D extends C {
-  D.named() : super._();
-}
-''');
-    var library = await checkLibrary('''
-import 'foo.dart' as foo;
-class C {
-  factory C() = foo.D.named;
-  C._();
-}
-''');
-    checkElementText(library, r'''
-import 'foo.dart' as foo;
-class C {
-  factory C() = D.named;
-  C._();
-}
-''');
-  }
-
-  test_constructor_redirected_factory_named_prefixed_generic() async {
-    addLibrarySource('/foo.dart', '''
-import 'test.dart';
-class D<T, U> extends C<U, T> {
-  D.named() : super._();
-}
-''');
-    var library = await checkLibrary('''
-import 'foo.dart' as foo;
-class C<T, U> {
-  factory C() = foo.D<U, T>.named;
-  C._();
-}
-''');
-    checkElementText(library, r'''
-import 'foo.dart' as foo;
-class C<T, U> {
-  factory C() = D<U, T>.named;
-  C._();
-}
-''');
-  }
-
-  test_constructor_redirected_factory_named_unresolved_class() async {
-    var library = await checkLibrary('''
-class C<E> {
-  factory C() = D.named<E>;
-}
-''', allowErrors: true);
-    checkElementText(library, r'''
-class C<E> {
-  factory C();
-}
-''');
-  }
-
-  test_constructor_redirected_factory_named_unresolved_constructor() async {
-    var library = await checkLibrary('''
-class D {}
-class C<E> {
-  factory C() = D.named<E>;
-}
-''', allowErrors: true);
-    checkElementText(library, r'''
-class D {
-}
-class C<E> {
-  factory C();
-}
-''');
-  }
-
-  test_constructor_redirected_factory_unnamed() async {
-    var library = await checkLibrary('''
-class C {
-  factory C() = D;
-  C._();
-}
-class D extends C {
-  D() : super._();
-}
-''');
-    checkElementText(library, r'''
-class C {
-  factory C() = D;
-  C._();
-}
-class D extends C {
-  D();
-}
-''');
-  }
-
-  test_constructor_redirected_factory_unnamed_generic() async {
-    var library = await checkLibrary('''
-class C<T, U> {
-  factory C() = D<U, T>;
-  C._();
-}
-class D<T, U> extends C<U, T> {
-  D() : super._();
-}
-''');
-    checkElementText(library, r'''
-class C<T, U> {
-  factory C() = D<U, T>;
-  C._();
-}
-class D<T, U> extends C<U, T> {
-  D();
-}
-''');
-  }
-
-  test_constructor_redirected_factory_unnamed_imported() async {
-    addLibrarySource('/foo.dart', '''
-import 'test.dart';
-class D extends C {
-  D() : super._();
-}
-''');
-    var library = await checkLibrary('''
-import 'foo.dart';
-class C {
-  factory C() = D;
-  C._();
-}
-''');
-    checkElementText(library, r'''
-import 'foo.dart';
-class C {
-  factory C() = D;
-  C._();
-}
-''');
-  }
-
-  test_constructor_redirected_factory_unnamed_imported_generic() async {
-    addLibrarySource('/foo.dart', '''
-import 'test.dart';
-class D<T, U> extends C<U, T> {
-  D() : super._();
-}
-''');
-    var library = await checkLibrary('''
-import 'foo.dart';
-class C<T, U> {
-  factory C() = D<U, T>;
-  C._();
-}
-''');
-    checkElementText(library, r'''
-import 'foo.dart';
-class C<T, U> {
-  factory C() = D<U, T>;
-  C._();
-}
-''');
-  }
-
-  test_constructor_redirected_factory_unnamed_prefixed() async {
-    addLibrarySource('/foo.dart', '''
-import 'test.dart';
-class D extends C {
-  D() : super._();
-}
-''');
-    var library = await checkLibrary('''
-import 'foo.dart' as foo;
-class C {
-  factory C() = foo.D;
-  C._();
-}
-''');
-    checkElementText(library, r'''
-import 'foo.dart' as foo;
-class C {
-  factory C() = D;
-  C._();
-}
-''');
-  }
-
-  test_constructor_redirected_factory_unnamed_prefixed_generic() async {
-    addLibrarySource('/foo.dart', '''
-import 'test.dart';
-class D<T, U> extends C<U, T> {
-  D() : super._();
-}
-''');
-    var library = await checkLibrary('''
-import 'foo.dart' as foo;
-class C<T, U> {
-  factory C() = foo.D<U, T>;
-  C._();
-}
-''');
-    checkElementText(library, r'''
-import 'foo.dart' as foo;
-class C<T, U> {
-  factory C() = D<U, T>;
-  C._();
-}
-''');
-  }
-
-  test_constructor_redirected_factory_unnamed_unresolved() async {
-    var library = await checkLibrary('''
-class C<E> {
-  factory C() = D<E>;
-}
-''', allowErrors: true);
-    checkElementText(library, r'''
-class C<E> {
-  factory C();
-}
-''');
-  }
-
-  test_constructor_redirected_thisInvocation_named() async {
-    var library = await checkLibrary('''
-class C {
-  C.named();
-  C() : this.named();
-}
-''');
-    checkElementText(library, r'''
-class C {
-  C.named();
-  C() = C.named;
-}
-''');
-  }
-
-  test_constructor_redirected_thisInvocation_named_generic() async {
-    var library = await checkLibrary('''
-class C<T> {
-  C.named();
-  C() : this.named();
-}
-''');
-    checkElementText(library, r'''
-class C<T> {
-  C.named();
-  C() = C<T>.named;
-}
-''');
-  }
-
-  test_constructor_redirected_thisInvocation_unnamed() async {
-    var library = await checkLibrary('''
-class C {
-  C();
-  C.named() : this();
-}
-''');
-    checkElementText(library, r'''
-class C {
-  C();
-  C.named() = C;
-}
-''');
-  }
-
-  test_constructor_redirected_thisInvocation_unnamed_generic() async {
-    var library = await checkLibrary('''
-class C<T> {
-  C();
-  C.named() : this();
-}
-''');
-    checkElementText(library, r'''
-class C<T> {
-  C();
-  C.named() = C<T>;
-}
-''');
-  }
-
-  test_constructor_withCycles_const() async {
-    var library = await checkLibrary('''
-class C {
-  final x;
-  const C() : x = const D();
-}
-class D {
-  final x;
-  const D() : x = const C();
-}
-''');
-    checkElementText(library, r'''
-class C {
-  final dynamic x;
-  const C() :
-        x/*location: test.dart;C;x*/ = const
-        D/*location: test.dart;D*/();
-}
-class D {
-  final dynamic x;
-  const D() :
-        x/*location: test.dart;D;x*/ = const
-        C/*location: test.dart;C*/();
-}
-''');
-  }
-
-  test_constructor_withCycles_nonConst() async {
-    var library = await checkLibrary('''
-class C {
-  final x;
-  C() : x = new D();
-}
-class D {
-  final x;
-  D() : x = new C();
-}
-''');
-    checkElementText(library, r'''
-class C {
-  final dynamic x;
-  C();
-}
-class D {
-  final dynamic x;
-  D();
-}
-''');
-  }
-
-  test_defaultValue_genericFunction() async {
-    var library = await checkLibrary('''
-typedef void F<T>(T v);
-
-void defaultF<T>(T v) {}
-
-class X {
-  final F f;
-  const X({this.f: defaultF});
-}
-''');
-    checkElementText(library, r'''
-typedef F<T> = void Function(T v);
-class X {
-  final (dynamic) → void f;
-  const X({(dynamic) → void this.f:
-        defaultF/*location: test.dart;defaultF*/});
-}
-void defaultF<T>(T v) {}
-''');
-  }
-
-  test_defaultValue_refersToGenericClass_constructor() async {
-    var library = await checkLibrary('''
-class B<T> {
-  const B();
-}
-class C<T> {
-  const C([B<T> b = const B()]);
-}
-''');
-    if (isSharedFrontEnd) {
-      // The constant can not depend on a (non-constant) type parameter.
-      checkElementText(library, r'''
-class B<T> {
-  const B();
-}
-class C<T> {
-  const C([B<T> b = const
-        B/*location: test.dart;B*/<
-        Null/*location: dart:core;Null*/>()]);
-}
-''');
-    } else {
-      checkElementText(library, r'''
-class B<T> {
-  const B();
-}
-class C<T> {
-  const C([B<T> b = const
-        B/*location: test.dart;B*/()]);
-}
-''');
-    }
-  }
-
-  test_defaultValue_refersToGenericClass_constructor2() async {
-    var library = await checkLibrary('''
-abstract class A<T> {}
-class B<T> implements A<T> {
-  const B();
-}
-class C<T> implements A<Iterable<T>> {
-  const C([A<T> a = const B()]);
-}
-''');
-    if (isSharedFrontEnd) {
-      // The constant can not depend on a (non-constant) type parameter.
-      checkElementText(library, r'''
-abstract class A<T> {
-}
-class B<T> implements A<T> {
-  const B();
-}
-class C<T> implements A<Iterable<T>> {
-  const C([A<T> a = const
-        B/*location: test.dart;B*/<
-        Null/*location: dart:core;Null*/>()]);
-}
-''');
-    } else {
-      checkElementText(library, r'''
-abstract class A<T> {
-}
-class B<T> implements A<T> {
-  const B();
-}
-class C<T> implements A<Iterable<T>> {
-  const C([A<T> a = const
-        B/*location: test.dart;B*/()]);
-}
-''');
-    }
-  }
-
-  test_defaultValue_refersToGenericClass_functionG() async {
-    var library = await checkLibrary('''
-class B<T> {
-  const B();
-}
-void foo<T>([B<T> b = const B()]) {}
-''');
-    if (isSharedFrontEnd) {
-      // The constant can not depend on a (non-constant) type parameter.
-      checkElementText(library, r'''
-class B<T> {
-  const B();
-}
-void foo<T>([B<T> b = const
-        B/*location: test.dart;B*/<
-        Null/*location: dart:core;Null*/>()]) {}
-''');
-    } else {
-      checkElementText(library, r'''
-class B<T> {
-  const B();
-}
-void foo<T>([B<T> b = const
-        B/*location: test.dart;B*/()]) {}
-''');
-    }
-  }
-
-  test_defaultValue_refersToGenericClass_methodG() async {
-    var library = await checkLibrary('''
-class B<T> {
-  const B();
-}
-class C {
-  void foo<T>([B<T> b = const B()]) {}
-}
-''');
-    if (isSharedFrontEnd) {
-      // The constant can not depend on a (non-constant) type parameter.
-      checkElementText(library, r'''
-class B<T> {
-  const B();
-}
-class C {
-  void foo<T>([B<T> b = const
-        B/*location: test.dart;B*/<
-        Null/*location: dart:core;Null*/>()]) {}
-}
-''');
-    } else {
-      checkElementText(library, r'''
-class B<T> {
-  const B();
-}
-class C {
-  void foo<T>([B<T> b = const
-        B/*location: test.dart;B*/()]) {}
-}
-''');
-    }
-  }
-
-  test_defaultValue_refersToGenericClass_methodG_classG() async {
-    var library = await checkLibrary('''
-class B<T1, T2> {
-  const B();
-}
-class C<E1> {
-  void foo<E2>([B<E1, E2> b = const B()]) {}
-}
-''');
-    if (isSharedFrontEnd) {
-      // The constant can not depend on a (non-constant) type parameter.
-      checkElementText(library, r'''
-class B<T1, T2> {
-  const B();
-}
-class C<E1> {
-  void foo<E2>([B<E1, E2> b = const
-        B/*location: test.dart;B*/<
-        Null/*location: dart:core;Null*/,
-        Null/*location: dart:core;Null*/>()]) {}
-}
-''');
-    } else {
-      checkElementText(library, r'''
-class B<T1, T2> {
-  const B();
-}
-class C<E1> {
-  void foo<E2>([B<E1, E2> b = const
-        B/*location: test.dart;B*/()]) {}
-}
-''');
-    }
-  }
-
-  test_defaultValue_refersToGenericClass_methodNG() async {
-    var library = await checkLibrary('''
-class B<T> {
-  const B();
-}
-class C<T> {
-  void foo([B<T> b = const B()]) {}
-}
-''');
-    if (isSharedFrontEnd) {
-      // The constant can not depend on a (non-constant) type parameter.
-      checkElementText(library, r'''
-class B<T> {
-  const B();
-}
-class C<T> {
-  void foo([B<T> b = const
-        B/*location: test.dart;B*/<
-        Null/*location: dart:core;Null*/>()]) {}
-}
-''');
-    } else {
-      checkElementText(library, r'''
-class B<T> {
-  const B();
-}
-class C<T> {
-  void foo([B<T> b = const
-        B/*location: test.dart;B*/()]) {}
-}
-''');
-    }
-  }
-
-  test_enum_documented() async {
-    var library = await checkLibrary('''
-// Extra comment so doc comment offset != 0
-/**
- * Docs
- */
-enum E { v }''');
-    checkElementText(library, r'''
-/**
- * Docs
- */
-enum E {
-  synthetic final int index;
-  synthetic static const List<E> values;
-  static const E v;
-  String toString() {}
-}
-''');
-  }
-
-  test_enum_value_documented() async {
-    var library = await checkLibrary('''
-enum E {
-  /**
-   * aaa
-   */
-  a,
-  /// bbb
-  b
-}''');
-    checkElementText(library, r'''
-enum E {
-  synthetic final int index;
-  synthetic static const List<E> values;
-  /**
-   * aaa
-   */
-  static const E a;
-  /// bbb
-  static const E b;
-  String toString() {}
-}
-''');
-  }
-
-  test_enum_values() async {
-    var library = await checkLibrary('enum E { v1, v2 }');
-    checkElementText(library, r'''
-enum E {
-  synthetic final int index;
-  synthetic static const List<E> values;
-  static const E v1;
-  static const E v2;
-  String toString() {}
-}
-''');
-  }
-
-  test_enums() async {
-    var library = await checkLibrary('enum E1 { v1 } enum E2 { v2 }');
-    checkElementText(library, r'''
-enum E1 {
-  synthetic final int index;
-  synthetic static const List<E1> values;
-  static const E1 v1;
-  String toString() {}
-}
-enum E2 {
-  synthetic final int index;
-  synthetic static const List<E2> values;
-  static const E2 v2;
-  String toString() {}
-}
-''');
-  }
-
-  test_error_extendsEnum() async {
-    var library = await checkLibrary('''
-enum E {a, b, c}
-
-class M {}
-
-class A extends E {
-  foo() {}
-}
-
-class B implements E, M {
-  foo() {}
-}
-
-class C extends Object with E, M {
-  foo() {}
-}
-
-class D = Object with M, E;
-''');
-    checkElementText(library, r'''
-enum E {
-  synthetic final int index;
-  synthetic static const List<E> values;
-  static const E a;
-  static const E b;
-  static const E c;
-  String toString() {}
-}
-class M {
-}
-class A {
-  dynamic foo() {}
-}
-class B implements M {
-  dynamic foo() {}
-}
-class C extends Object with M {
-  synthetic C();
-  dynamic foo() {}
-}
-class alias D extends Object with M {
-  synthetic D() = Object;
-}
-''');
-  }
-
-  test_executable_parameter_type_typedef() async {
-    var library = await checkLibrary(r'''
-typedef F(int p);
-main(F f) {}
-''');
-    checkElementText(library, r'''
-typedef F = dynamic Function(int p);
-dynamic main((int) → dynamic f) {}
-''');
-  }
-
-  test_export_class() async {
-    addLibrarySource('/a.dart', 'class C {}');
-    var library = await checkLibrary('export "a.dart";');
-    checkElementText(library, r'''
-export 'a.dart';
-''');
-  }
-
-  test_export_class_type_alias() async {
-    addLibrarySource('/a.dart', r'''
-class C = _D with _E;
-class _D {}
-class _E {}
-''');
-    var library = await checkLibrary('export "a.dart";');
-    checkElementText(library, r'''
-export 'a.dart';
-''');
-  }
-
-  test_export_configurations_useDefault() async {
-    context.declaredVariables =
-        new DeclaredVariables.fromMap({'dart.library.io': 'false'});
-    addLibrarySource('/foo.dart', 'class A {}');
-    addLibrarySource('/foo_io.dart', 'class A {}');
-    addLibrarySource('/foo_html.dart', 'class A {}');
-    var library = await checkLibrary(r'''
-export 'foo.dart'
-  if (dart.library.io) 'foo_io.dart'
-  if (dart.library.html) 'foo_html.dart';
-''');
-    checkElementText(library, r'''
-export 'foo.dart';
-''');
-    expect(library.exports[0].exportedLibrary.source.shortName, 'foo.dart');
-  }
-
-  test_export_configurations_useFirst() async {
-    context.declaredVariables = new DeclaredVariables.fromMap(
-        {'dart.library.io': 'true', 'dart.library.html': 'true'});
-    addLibrarySource('/foo.dart', 'class A {}');
-    addLibrarySource('/foo_io.dart', 'class A {}');
-    addLibrarySource('/foo_html.dart', 'class A {}');
-    var library = await checkLibrary(r'''
-export 'foo.dart'
-  if (dart.library.io) 'foo_io.dart'
-  if (dart.library.html) 'foo_html.dart';
-''');
-    checkElementText(library, r'''
-export 'foo_io.dart';
-''');
-    expect(library.exports[0].exportedLibrary.source.shortName, 'foo_io.dart');
-  }
-
-  test_export_configurations_useSecond() async {
-    context.declaredVariables = new DeclaredVariables.fromMap(
-        {'dart.library.io': 'false', 'dart.library.html': 'true'});
-    addLibrarySource('/foo.dart', 'class A {}');
-    addLibrarySource('/foo_io.dart', 'class A {}');
-    addLibrarySource('/foo_html.dart', 'class A {}');
-    var library = await checkLibrary(r'''
-export 'foo.dart'
-  if (dart.library.io) 'foo_io.dart'
-  if (dart.library.html) 'foo_html.dart';
-''');
-    checkElementText(library, r'''
-export 'foo_html.dart';
-''');
-    ExportElement export = library.exports[0];
-    expect(export.exportedLibrary.source.shortName, 'foo_html.dart');
-  }
-
-  test_export_function() async {
-    addLibrarySource('/a.dart', 'f() {}');
-    var library = await checkLibrary('export "a.dart";');
-    checkElementText(library, r'''
-export 'a.dart';
-''');
-  }
-
-  test_export_getter() async {
-    addLibrarySource('/a.dart', 'get f() => null;');
-    var library = await checkLibrary('export "a.dart";');
-    checkElementText(library, r'''
-export 'a.dart';
-''');
-  }
-
-  test_export_hide() async {
-    addLibrary('dart:async');
-    var library =
-        await checkLibrary('export "dart:async" hide Stream, Future;');
-    checkElementText(library, r'''
-export 'dart:async' hide Stream, Future;
-''');
-  }
-
-  test_export_multiple_combinators() async {
-    addLibrary('dart:async');
-    var library =
-        await checkLibrary('export "dart:async" hide Stream show Future;');
-    checkElementText(library, r'''
-export 'dart:async' hide Stream show Future;
-''');
-  }
-
-  test_export_setter() async {
-    addLibrarySource('/a.dart', 'void set f(value) {}');
-    var library = await checkLibrary('export "a.dart";');
-    checkElementText(library, r'''
-export 'a.dart';
-''');
-  }
-
-  test_export_show() async {
-    addLibrary('dart:async');
-    var library =
-        await checkLibrary('export "dart:async" show Future, Stream;');
-    checkElementText(library, r'''
-export 'dart:async' show Future, Stream;
-''');
-  }
-
-  test_export_typedef() async {
-    addLibrarySource('/a.dart', 'typedef F();');
-    var library = await checkLibrary('export "a.dart";');
-    checkElementText(library, r'''
-export 'a.dart';
-''');
-  }
-
-  test_export_variable() async {
-    addLibrarySource('/a.dart', 'var x;');
-    var library = await checkLibrary('export "a.dart";');
-    checkElementText(library, r'''
-export 'a.dart';
-''');
-  }
-
-  test_export_variable_const() async {
-    addLibrarySource('/a.dart', 'const x = 0;');
-    var library = await checkLibrary('export "a.dart";');
-    checkElementText(library, r'''
-export 'a.dart';
-''');
-  }
-
-  test_export_variable_final() async {
-    addLibrarySource('/a.dart', 'final x = 0;');
-    var library = await checkLibrary('export "a.dart";');
-    checkElementText(library, r'''
-export 'a.dart';
-''');
-  }
-
-  test_exportImport_configurations_useDefault() async {
-    context.declaredVariables =
-        new DeclaredVariables.fromMap({'dart.library.io': 'false'});
-    addLibrarySource('/foo.dart', 'class A {}');
-    addLibrarySource('/foo_io.dart', 'class A {}');
-    addLibrarySource('/foo_html.dart', 'class A {}');
-    addLibrarySource('/bar.dart', r'''
-export 'foo.dart'
-  if (dart.library.io) 'foo_io.dart'
-  if (dart.library.html) 'foo_html.dart';
-''');
-    var library = await checkLibrary(r'''
-import 'bar.dart';
-class B extends A {}
-''');
-    checkElementText(library, r'''
-import 'bar.dart';
-class B extends A {
-}
-''');
-    var typeA = library.definingCompilationUnit.getType('B').supertype;
-    expect(typeA.element.source.shortName, 'foo.dart');
-  }
-
-  test_exportImport_configurations_useFirst() async {
-    context.declaredVariables = new DeclaredVariables.fromMap(
-        {'dart.library.io': 'true', 'dart.library.html': 'true'});
-    addLibrarySource('/foo.dart', 'class A {}');
-    addLibrarySource('/foo_io.dart', 'class A {}');
-    addLibrarySource('/foo_html.dart', 'class A {}');
-    addLibrarySource('/bar.dart', r'''
-export 'foo.dart'
-  if (dart.library.io) 'foo_io.dart'
-  if (dart.library.html) 'foo_html.dart';
-''');
-    var library = await checkLibrary(r'''
-import 'bar.dart';
-class B extends A {}
-''');
-    checkElementText(library, r'''
-import 'bar.dart';
-class B extends A {
-}
-''');
-    var typeA = library.definingCompilationUnit.getType('B').supertype;
-    expect(typeA.element.source.shortName, 'foo_io.dart');
-  }
-
-  test_exports() async {
-    addLibrarySource('/a.dart', 'library a;');
-    addLibrarySource('/b.dart', 'library b;');
-    var library = await checkLibrary('export "a.dart"; export "b.dart";');
-    checkElementText(library, r'''
-export 'a.dart';
-export 'b.dart';
-''');
-  }
-
-  test_expr_invalid_typeParameter_asPrefix() async {
-    variablesWithNotConstInitializers.add('f');
-    var library = await checkLibrary('''
-class C<T> {
-  final f = T.k;
-}
-''');
-    checkElementText(library, r'''
-class C<T> {
-  final dynamic f;
-}
-''');
-  }
-
-  test_field_covariant() async {
-    var library = await checkLibrary('''
-class C {
-  covariant int x;
-}''');
-    checkElementText(library, r'''
-class C {
-  covariant int x;
-}
-''');
-  }
-
-  test_field_documented() async {
-    var library = await checkLibrary('''
-class C {
-  /**
-   * Docs
-   */
-  var x;
-}''');
-    checkElementText(library, r'''
-class C {
-  /**
-   * Docs
-   */
-  dynamic x;
-}
-''');
-  }
-
-  test_field_formal_param_inferred_type_implicit() async {
-    var library = await checkLibrary('class C extends D { var v; C(this.v); }'
-        ' abstract class D { int get v; }');
-    if (isStrongMode) {
-      checkElementText(library, r'''
-class C extends D {
-  int v;
-  C(int this.v);
-}
-abstract class D {
-  int get v;
-}
-''');
-    } else {
-      checkElementText(library, r'''
-class C extends D {
-  dynamic v;
-  C(dynamic this.v);
-}
-abstract class D {
-  int get v;
-}
-''');
-    }
-  }
-
-  test_field_inferred_type_nonStatic_explicit_initialized() async {
-    var library = await checkLibrary('class C { num v = 0; }');
-    checkElementText(library, r'''
-class C {
-  num v;
-}
-''');
-  }
-
-  test_field_inferred_type_nonStatic_implicit_initialized() async {
-    var library = await checkLibrary('class C { var v = 0; }');
-    if (isStrongMode) {
-      checkElementText(library, r'''
-class C {
-  int v;
-}
-''');
-    } else {
-      checkElementText(library, r'''
-class C {
-  dynamic v;
-}
-''');
-    }
-  }
-
-  test_field_inferred_type_nonStatic_implicit_uninitialized() async {
-    var library = await checkLibrary(
-        'class C extends D { var v; } abstract class D { int get v; }');
-    if (isStrongMode) {
-      checkElementText(library, r'''
-class C extends D {
-  int v;
-}
-abstract class D {
-  int get v;
-}
-''');
-    } else {
-      checkElementText(library, r'''
-class C extends D {
-  dynamic v;
-}
-abstract class D {
-  int get v;
-}
-''');
-    }
-  }
-
-  test_field_inferred_type_static_implicit_initialized() async {
-    var library = await checkLibrary('class C { static var v = 0; }');
-    if (isStrongMode) {
-      checkElementText(library, r'''
-class C {
-  static int v;
-}
-''');
-    } else {
-      checkElementText(library, r'''
-class C {
-  static dynamic v;
-}
-''');
-    }
-  }
-
-  test_field_propagatedType_const_noDep() async {
-    var library = await checkLibrary('''
-class C {
-  static const x = 0;
-}''');
-    if (isStrongMode) {
-      checkElementText(library, r'''
-class C {
-  static const int x = 0;
-}
-''');
-    } else {
-      checkElementText(library, r'''
-class C {
-  static const dynamic x = 0;
-}
-''');
-    }
-  }
-
-  test_field_propagatedType_final_dep_inLib() async {
-    addLibrarySource('/a.dart', 'final a = 1;');
-    var library = await checkLibrary('''
-import "a.dart";
-class C {
-  final b = a / 2;
-}''');
-    if (isStrongMode) {
-      checkElementText(library, r'''
-import 'a.dart';
-class C {
-  final double b;
-}
-''');
-    } else {
-      checkElementText(library, r'''
-import 'a.dart';
-class C {
-  final dynamic b;
-}
-''');
-    }
-  }
-
-  test_field_propagatedType_final_dep_inPart() async {
-    addSource('/a.dart', 'part of lib; final a = 1;');
-    var library = await checkLibrary('''
-library lib;
-part "a.dart";
-class C {
-  final b = a / 2;
-}''');
-    if (isStrongMode) {
-      checkElementText(library, r'''
-library lib;
-part 'a.dart';
-class C {
-  final double b;
-}
---------------------
-unit: a.dart
-
-final int a;
-''');
-    } else {
-      checkElementText(library, r'''
-library lib;
-part 'a.dart';
-class C {
-  final dynamic b;
-}
---------------------
-unit: a.dart
-
-final dynamic a;
-''');
-    }
-  }
-
-  test_field_propagatedType_final_noDep_instance() async {
-    var library = await checkLibrary('''
-class C {
-  final x = 0;
-}''');
-    if (isStrongMode) {
-      checkElementText(library, r'''
-class C {
-  final int x;
-}
-''');
-    } else {
-      checkElementText(library, r'''
-class C {
-  final dynamic x;
-}
-''');
-    }
-  }
-
-  test_field_propagatedType_final_noDep_static() async {
-    var library = await checkLibrary('''
-class C {
-  static final x = 0;
-}''');
-    if (isStrongMode) {
-      checkElementText(library, r'''
-class C {
-  static final int x;
-}
-''');
-    } else {
-      checkElementText(library, r'''
-class C {
-  static final dynamic x;
-}
-''');
-    }
-  }
-
-  test_field_static_final_untyped() async {
-    var library = await checkLibrary('class C { static final x = 0; }');
-    if (isStrongMode) {
-      checkElementText(library, r'''
-class C {
-  static final int x;
-}
-''');
-    } else {
-      checkElementText(library, r'''
-class C {
-  static final dynamic x;
-}
-''');
-    }
-  }
-
-  test_field_untyped() async {
-    var library = await checkLibrary('class C { var x = 0; }');
-    if (isStrongMode) {
-      checkElementText(library, r'''
-class C {
-  int x;
-}
-''');
-    } else {
-      checkElementText(library, r'''
-class C {
-  dynamic x;
-}
-''');
-    }
-  }
-
-  test_function_async() async {
-    var library = await checkLibrary(r'''
-import 'dart:async';
-Future f() async {}
-''');
-    checkElementText(library, r'''
-import 'dart:async';
-Future<dynamic> f() async {}
-''');
-  }
-
-  test_function_asyncStar() async {
-    var library = await checkLibrary(r'''
-import 'dart:async';
-Stream f() async* {}
-''');
-    checkElementText(library, r'''
-import 'dart:async';
-Stream<dynamic> f() async* {}
-''');
-  }
-
-  test_function_documented() async {
-    var library = await checkLibrary('''
-// Extra comment so doc comment offset != 0
-/**
- * Docs
- */
-f() {}''');
-    checkElementText(library, r'''
-/**
- * Docs
- */
-dynamic f() {}
-''');
-  }
-
-  test_function_entry_point() async {
-    var library = await checkLibrary('main() {}');
-    checkElementText(library, r'''
-dynamic main() {}
-''');
-  }
-
-  test_function_entry_point_in_export() async {
-    addLibrarySource('/a.dart', 'library a; main() {}');
-    var library = await checkLibrary('export "a.dart";');
-    checkElementText(library, r'''
-export 'a.dart';
-''');
-  }
-
-  test_function_entry_point_in_export_hidden() async {
-    addLibrarySource('/a.dart', 'library a; main() {}');
-    var library = await checkLibrary('export "a.dart" hide main;');
-    checkElementText(library, r'''
-export 'a.dart' hide main;
-''');
-  }
-
-  test_function_entry_point_in_part() async {
-    addSource('/a.dart', 'part of my.lib; main() {}');
-    var library = await checkLibrary('library my.lib; part "a.dart";');
-    checkElementText(library, r'''
-library my.lib;
-part 'a.dart';
---------------------
-unit: a.dart
-
-dynamic main() {}
-''');
-  }
-
-  test_function_external() async {
-    var library = await checkLibrary('external f();');
-    checkElementText(library, r'''
-external dynamic f() {}
-''');
-  }
-
-  test_function_parameter_final() async {
-    var library = await checkLibrary('f(final x) {}');
-    checkElementText(library, r'''
-dynamic f(final dynamic x) {}
-''');
-  }
-
-  test_function_parameter_kind_named() async {
-    var library = await checkLibrary('f({x}) {}');
-    checkElementText(library, r'''
-dynamic f({dynamic x}) {}
-''');
-  }
-
-  test_function_parameter_kind_positional() async {
-    var library = await checkLibrary('f([x]) {}');
-    checkElementText(library, r'''
-dynamic f([dynamic x]) {}
-''');
-  }
-
-  test_function_parameter_kind_required() async {
-    var library = await checkLibrary('f(x) {}');
-    checkElementText(library, r'''
-dynamic f(dynamic x) {}
-''');
-  }
-
-  test_function_parameter_parameters() async {
-    var library = await checkLibrary('f(g(x, y)) {}');
-    checkElementText(library, r'''
-dynamic f((dynamic, dynamic) → dynamic g) {}
-''');
-  }
-
-  test_function_parameter_return_type() async {
-    var library = await checkLibrary('f(int g()) {}');
-    checkElementText(library, r'''
-dynamic f(() → int g) {}
-''');
-  }
-
-  test_function_parameter_return_type_void() async {
-    var library = await checkLibrary('f(void g()) {}');
-    checkElementText(library, r'''
-dynamic f(() → void g) {}
-''');
-  }
-
-  test_function_parameter_type() async {
-    var library = await checkLibrary('f(int i) {}');
-    checkElementText(library, r'''
-dynamic f(int i) {}
-''');
-  }
-
-  test_function_parameters() async {
-    var library = await checkLibrary('f(x, y) {}');
-    checkElementText(library, r'''
-dynamic f(dynamic x, dynamic y) {}
-''');
-  }
-
-  test_function_return_type() async {
-    var library = await checkLibrary('int f() => null;');
-    checkElementText(library, r'''
-int f() {}
-''');
-  }
-
-  test_function_return_type_implicit() async {
-    var library = await checkLibrary('f() => null;');
-    checkElementText(library, r'''
-dynamic f() {}
-''');
-  }
-
-  test_function_return_type_void() async {
-    var library = await checkLibrary('void f() {}');
-    checkElementText(library, r'''
-void f() {}
-''');
-  }
-
-  test_function_type_parameter() async {
-    var library = await checkLibrary('T f<T, U>(U u) => null;');
-    checkElementText(library, r'''
-T f<T, U>(U u) {}
-''');
-  }
-
-  test_function_type_parameter_with_function_typed_parameter() async {
-    var library = await checkLibrary('void f<T, U>(T x(U u)) {}');
-    checkElementText(library, r'''
-void f<T, U>((U) → T x) {}
-''');
-  }
-
-  test_function_typed_parameter_implicit() async {
-    var library = await checkLibrary('f(g()) => null;');
-    expect(
-        library
-            .definingCompilationUnit.functions[0].parameters[0].hasImplicitType,
-        isFalse);
-  }
-
-  test_functions() async {
-    var library = await checkLibrary('f() {} g() {}');
-    checkElementText(library, r'''
-dynamic f() {}
-dynamic g() {}
-''');
-  }
-
-  test_futureOr() async {
-    var library = await checkLibrary('import "dart:async"; FutureOr<int> x;');
-    if (isStrongMode) {
-      checkElementText(library, r'''
-import 'dart:async';
-FutureOr<int> x;
-''');
-    } else {
-      checkElementText(library, r'''
-import 'dart:async';
-dynamic x;
-''');
-    }
-    var variables = library.definingCompilationUnit.topLevelVariables;
-    expect(variables, hasLength(1));
-    if (isStrongMode) {
-      expect(variables[0].type.toString(), 'FutureOr<int>');
-    } else {
-      expect(variables[0].type.toString(), 'dynamic');
-    }
-  }
-
-  test_futureOr_const() async {
-    var library =
-        await checkLibrary('import "dart:async"; const x = FutureOr;');
-    if (isStrongMode) {
-      checkElementText(library, r'''
-import 'dart:async';
-const Type x =
-        FutureOr/*location: dart:async;FutureOr*/;
-''');
-    } else {
-      checkElementText(library, r'''
-import 'dart:async';
-const dynamic x =
-        FutureOr/*location: dart:async;FutureOr*/;
-''');
-    }
-    var variables = library.definingCompilationUnit.topLevelVariables;
-    expect(variables, hasLength(1));
-    var x = variables[0] as ConstTopLevelVariableElementImpl;
-    if (isStrongMode) {
-      expect(x.type.toString(), 'Type');
-    } else {
-      expect(x.type.toString(), 'dynamic');
-    }
-    expect(x.constantInitializer.toString(), 'FutureOr');
-  }
-
-  test_futureOr_inferred() async {
-    var library = await checkLibrary('''
-import "dart:async";
-FutureOr<int> f() => null;
-var x = f();
-var y = x.then((z) => z.asDouble());
-''');
-    if (isStrongMode) {
-      checkElementText(library, r'''
-import 'dart:async';
-FutureOr<int> x;
-dynamic y;
-FutureOr<int> f() {}
-''');
-    } else {
-      checkElementText(library, r'''
-import 'dart:async';
-dynamic x;
-dynamic y;
-dynamic f() {}
-''');
-    }
-    var variables = library.definingCompilationUnit.topLevelVariables;
-    expect(variables, hasLength(2));
-    var x = variables[0];
-    expect(x.name, 'x');
-    var y = variables[1];
-    expect(y.name, 'y');
-    if (isStrongMode) {
-      expect(x.type.toString(), 'FutureOr<int>');
-      expect(y.type.toString(), 'dynamic');
-    } else {
-      expect(x.type.toString(), 'dynamic');
-      expect(y.type.toString(), 'dynamic');
-    }
-  }
-
-  test_generic_gClass_gMethodStatic() async {
-    var library = await checkLibrary('''
-class C<T, U> {
-  static void m<V, W>(V v, W w) {
-    void f<X, Y>(V v, W w, X x, Y y) {
-    }
-  }
-}
-''');
-    checkElementText(library, r'''
-class C<T, U> {
-  static void m<V, W>(V v, W w) {}
-}
-''');
-  }
-
-  test_genericFunction_asFunctionReturnType() async {
-    shouldCompareLibraryElements = false;
-    var library = await checkLibrary(r'''
-int Function(int a, String b) f() => null;
-''');
-    checkElementText(library, r'''
-(int, String) → int f() {}
-''');
-  }
-
-  test_genericFunction_asFunctionTypedParameterReturnType() async {
-    shouldCompareLibraryElements = false;
-    var library = await checkLibrary(r'''
-void f(int Function(int a, String b) p(num c)) => null;
-''');
-    checkElementText(library, r'''
-void f((num) → (int, String) → int p) {}
-''');
-  }
-
-  test_genericFunction_asGenericFunctionReturnType() async {
-    shouldCompareLibraryElements = false;
-    var library = await checkLibrary(r'''
-typedef F = void Function(String a) Function(int b);
-''');
-    checkElementText(library, r'''
-typedef F = (String) → void Function(int b);
-''');
-  }
-
-  test_genericFunction_asMethodReturnType() async {
-    shouldCompareLibraryElements = false;
-    var library = await checkLibrary(r'''
-class C {
-  int Function(int a, String b) m() => null;
-}
-''');
-    checkElementText(library, r'''
-class C {
-  (int, String) → int m() {}
-}
-''');
-  }
-
-  test_genericFunction_asParameterType() async {
-    shouldCompareLibraryElements = false;
-    var library = await checkLibrary(r'''
-void f(int Function(int a, String b) p) => null;
-''');
-    checkElementText(library, r'''
-void f((int, String) → int p) {}
-''');
-  }
-
-  test_genericFunction_asTopLevelVariableType() async {
-    shouldCompareLibraryElements = false;
-    var library = await checkLibrary(r'''
-int Function(int a, String b) v;
-''');
-    checkElementText(library, r'''
-(int, String) → int v;
-''');
-  }
-
-  test_getter_documented() async {
-    var library = await checkLibrary('''
-// Extra comment so doc comment offset != 0
-/**
- * Docs
- */
-get x => null;''');
-    checkElementText(library, r'''
-/**
- * Docs
- */
-dynamic get x {}
-''');
-  }
-
-  test_getter_external() async {
-    var library = await checkLibrary('external int get x;');
-    checkElementText(library, r'''
-external int get x;
-''');
-  }
-
-  test_getter_inferred_type_nonStatic_implicit_return() async {
-    var library = await checkLibrary(
-        'class C extends D { get f => null; } abstract class D { int get f; }');
-    if (isStrongMode) {
-      checkElementText(library, r'''
-class C extends D {
-  int get f {}
-}
-abstract class D {
-  int get f;
-}
-''');
-    } else {
-      checkElementText(library, r'''
-class C extends D {
-  dynamic get f {}
-}
-abstract class D {
-  int get f;
-}
-''');
-    }
-  }
-
-  test_getters() async {
-    var library = await checkLibrary('int get x => null; get y => null;');
-    checkElementText(library, r'''
-int get x {}
-dynamic get y {}
-''');
-  }
-
-  @failingTest
-  test_implicitConstructor_named_const() async {
-    // TODO(paulberry, scheglov): get this to pass
-    var library = await checkLibrary('''
-class C {
-  final Object x;
-  const C.named(this.x);
-}
-const x = C.named(42);
-''');
-    checkElementText(library, 'TODO(paulberry, scheglov)');
-  }
-
-  test_implicitTopLevelVariable_getterFirst() async {
-    var library =
-        await checkLibrary('int get x => 0; void set x(int value) {}');
-    checkElementText(library, r'''
-int get x {}
-void set x(int value) {}
-''');
-  }
-
-  test_implicitTopLevelVariable_setterFirst() async {
-    var library =
-        await checkLibrary('void set x(int value) {} int get x => 0;');
-    checkElementText(library, r'''
-void set x(int value) {}
-int get x {}
-''');
-  }
-
-  test_import_configurations_useDefault() async {
-    context.declaredVariables =
-        new DeclaredVariables.fromMap({'dart.library.io': 'false'});
-    addLibrarySource('/foo.dart', 'class A {}');
-    addLibrarySource('/foo_io.dart', 'class A {}');
-    addLibrarySource('/foo_html.dart', 'class A {}');
-    var library = await checkLibrary(r'''
-import 'foo.dart'
-  if (dart.library.io) 'foo_io.dart'
-  if (dart.library.html) 'foo_html.dart';
-
-class B extends A {}
-''');
-    checkElementText(library, r'''
-import 'foo.dart';
-class B extends A {
-}
-''');
-    var typeA = library.definingCompilationUnit.getType('B').supertype;
-    expect(typeA.element.source.shortName, 'foo.dart');
-  }
-
-  test_import_configurations_useFirst() async {
-    context.declaredVariables = new DeclaredVariables.fromMap(
-        {'dart.library.io': 'true', 'dart.library.html': 'true'});
-    addLibrarySource('/foo.dart', 'class A {}');
-    addLibrarySource('/foo_io.dart', 'class A {}');
-    addLibrarySource('/foo_html.dart', 'class A {}');
-    var library = await checkLibrary(r'''
-import 'foo.dart'
-  if (dart.library.io) 'foo_io.dart'
-  if (dart.library.html) 'foo_html.dart';
-
-class B extends A {}
-''');
-    checkElementText(library, r'''
-import 'foo_io.dart';
-class B extends A {
-}
-''');
-    var typeA = library.definingCompilationUnit.getType('B').supertype;
-    expect(typeA.element.source.shortName, 'foo_io.dart');
-  }
-
-  test_import_deferred() async {
-    addLibrarySource('/a.dart', 'f() {}');
-    var library = await checkLibrary('''
-import 'a.dart' deferred as p;
-main() {
-  p.f();
-  }
-''');
-    checkElementText(library, r'''
-import 'a.dart' deferred as p;
-dynamic main() {}
-''');
-  }
-
-  test_import_export() async {
-    addLibrary('dart:async');
-    var library = await checkLibrary('''
-import 'dart:async' as i1;
-export 'dart:math';
-import 'dart:async' as i2;
-export 'dart:math';
-import 'dart:async' as i3;
-export 'dart:math';
-''');
-    checkElementText(library, r'''
-import 'dart:async' as i1;
-import 'dart:async' as i2;
-import 'dart:async' as i3;
-export 'dart:math';
-export 'dart:math';
-export 'dart:math';
-''');
-  }
-
-  test_import_hide() async {
-    addLibrary('dart:async');
-    var library = await checkLibrary('''
-import 'dart:async' hide Stream, Completer; Future f;
-''');
-    checkElementText(library, r'''
-import 'dart:async' hide Stream, Completer;
-Future<dynamic> f;
-''');
-  }
-
-  test_import_invalidUri_metadata() async {
-    allowMissingFiles = true;
-    shouldCompareLibraryElements = false;
-    var library = await checkLibrary('''
-@foo
-import '';
-''');
-    checkElementText(library, r'''
-@#invalidConst
-import '<unresolved>';
-''');
-  }
-
-  test_import_multiple_combinators() async {
-    addLibrary('dart:async');
-    var library = await checkLibrary('''
-import "dart:async" hide Stream show Future;
-Future f;
-''');
-    checkElementText(library, r'''
-import 'dart:async' hide Stream show Future;
-Future<dynamic> f;
-''');
-  }
-
-  test_import_prefixed() async {
-    addLibrarySource('/a.dart', 'library a; class C {}');
-    var library = await checkLibrary('import "a.dart" as a; a.C c;');
-
-    expect(library.imports[0].prefix.nameOffset, 19);
-    expect(library.imports[0].prefix.nameLength, 1);
-
-    checkElementText(library, r'''
-import 'a.dart' as a;
-C c;
-''');
-  }
-
-  test_import_self() async {
-    var library = await checkLibrary('''
-import 'test.dart' as p;
-class C {}
-class D extends p.C {} // Prevent "unused import" warning
-''');
-    expect(library.imports, hasLength(2));
-    expect(library.imports[0].importedLibrary.location, library.location);
-    expect(library.imports[1].importedLibrary.isDartCore, true);
-    checkElementText(library, r'''
-import 'test.dart' as p;
-class C {
-}
-class D extends C {
-}
-''');
-  }
-
-  test_import_short_absolute() async {
-    testFile = '/my/project/bin/test.dart';
-    // Note: "/a.dart" resolves differently on Windows vs. Posix.
-    var destinationPath =
-        resourceProvider.pathContext.fromUri(Uri.parse('/a.dart'));
-    addLibrarySource(destinationPath, 'class C {}');
-    var library = await checkLibrary('import "/a.dart"; C c;');
-    checkElementText(library, r'''
-import 'a.dart';
-C c;
-''');
-  }
-
-  test_import_show() async {
-    addLibrary('dart:async');
-    var library = await checkLibrary('''
-import "dart:async" show Future, Stream;
-Future f;
-Stream s;
-''');
-    checkElementText(library, r'''
-import 'dart:async' show Future, Stream;
-Future<dynamic> f;
-Stream<dynamic> s;
-''');
-  }
-
-  test_imports() async {
-    addLibrarySource('/a.dart', 'library a; class C {}');
-    addLibrarySource('/b.dart', 'library b; class D {}');
-    var library =
-        await checkLibrary('import "a.dart"; import "b.dart"; C c; D d;');
-    checkElementText(library, r'''
-import 'a.dart';
-import 'b.dart';
-C c;
-D d;
-''');
-  }
-
-  @failingTest
-  void test_infer_generic_typedef_complex() async {
-    // TODO(paulberry, scheglov): get this test to pass.
-    var library = await checkLibrary('''
-typedef F<T> = D<T,U> Function<U>();
-class C<V> {
-  const C(F<V> f);
-}
-class D<T,U> {}
-D<int,U> f<U>() => null;
-const x = const C(f);
-''');
-    checkElementText(library, '''TODO(paulberry, scheglov)''');
-  }
-
-  void test_infer_generic_typedef_simple() async {
-    var library = await checkLibrary('''
-typedef F = D<T> Function<T>();
-class C {
-  const C(F f);
-}
-class D<T> {}
-D<T> f<T>() => null;
-const x = const C(f);
-''');
-    if (isStrongMode) {
-      checkElementText(library, '''
-typedef F = D<T> Function<T>();
-class C {
-  const C(<T>() → D<T> f);
-}
-class D<T> {
-}
-const C x = const
-        C/*location: test.dart;C*/(
-        f/*location: test.dart;f*/);
-D<T> f<T>() {}
-''');
-    } else {
-      checkElementText(library, '''
-typedef F = D<T> Function<T>();
-class C {
-  const C(<T>() → D<T> f);
-}
-class D<T> {
-}
-const dynamic x = const
-        C/*location: test.dart;C*/(
-        f/*location: test.dart;f*/);
-D<T> f<T>() {}
-''');
-    }
-  }
-
-  test_infer_instanceCreation_fromArguments() async {
-    var library = await checkLibrary('''
-class A {}
-
-class B extends A {}
-
-class S<T extends A> {
-  S(T _);
-}
-
-var s = new S(new B());
-''');
-    if (isStrongMode) {
-      checkElementText(library, '''
-class A {
-}
-class B extends A {
-}
-class S<T extends A> {
-  S(T _);
-}
-S<B> s;
-''');
-    } else {
-      checkElementText(library, '''
-class A {
-}
-class B extends A {
-}
-class S<T extends A> {
-  S(T _);
-}
-dynamic s;
-''');
-    }
-  }
-
-  test_infer_property_set() async {
-    var library = await checkLibrary('''
-class A {
-  B b;
-}
-class B {
-  C get c => null;
-  void set c(C value) {}
-}
-class C {}
-class D extends C {}
-var a = new A();
-var x = a.b.c ??= new D();
-''');
-    if (isStrongMode) {
-      checkElementText(library, '''
-class A {
-  B b;
-}
-class B {
-  C get c {}
-  void set c(C value) {}
-}
-class C {
-}
-class D extends C {
-}
-A a;
-C x;
-''');
-    } else {
-      checkElementText(library, '''
-class A {
-  B b;
-}
-class B {
-  C get c {}
-  void set c(C value) {}
-}
-class C {
-}
-class D extends C {
-}
-dynamic a;
-dynamic x;
-''');
-    }
-  }
-
-  test_inference_issue_32394() async {
-    // Test the type inference involed in dartbug.com/32394
-    var library = await checkLibrary('''
-var x = y.map((a) => a.toString());
-var y = [3];
-var z = x.toList();
-''');
-    if (isStrongMode) {
-      checkElementText(library, '''
-Iterable<String> x;
-List<int> y;
-List<String> z;
-''');
-    } else {
-      checkElementText(library, '''
-dynamic x;
-dynamic y;
-dynamic z;
-''');
-    }
-  }
-
-  test_inference_map() async {
-    var library = await checkLibrary('''
-class C {
-  int p;
-}
-var x = <C>[];
-var y = x.map((c) => c.p);
-''');
-    if (isStrongMode) {
-      checkElementText(library, '''
-class C {
-  int p;
-}
-List<C> x;
-Iterable<int> y;
-''');
-    } else {
-      checkElementText(library, '''
-class C {
-  int p;
-}
-dynamic x;
-dynamic y;
-''');
-    }
-  }
-
-  test_inferred_function_type_for_variable_in_generic_function() async {
-    // In the code below, `x` has an inferred type of `() => int`, with 2
-    // (unused) type parameters from the enclosing top level function.
-    var library = await checkLibrary('''
-f<U, V>() {
-  var x = () => 0;
-}
-''');
-    checkElementText(library, r'''
-dynamic f<U, V>() {}
-''');
-  }
-
-  test_inferred_function_type_in_generic_class_constructor() async {
-    // In the code below, `() => () => 0` has an inferred return type of
-    // `() => int`, with 2 (unused) type parameters from the enclosing class.
-    var library = await checkLibrary('''
-class C<U, V> {
-  final x;
-  C() : x = (() => () => 0);
-}
-''');
-    checkElementText(library, r'''
-class C<U, V> {
-  final dynamic x;
-  C();
-}
-''');
-  }
-
-  test_inferred_function_type_in_generic_class_getter() async {
-    // In the code below, `() => () => 0` has an inferred return type of
-    // `() => int`, with 2 (unused) type parameters from the enclosing class.
-    var library = await checkLibrary('''
-class C<U, V> {
-  get x => () => () => 0;
-}
-''');
-    checkElementText(library, r'''
-class C<U, V> {
-  dynamic get x {}
-}
-''');
-  }
-
-  test_inferred_function_type_in_generic_class_in_generic_method() async {
-    // In the code below, `() => () => 0` has an inferred return type of
-    // `() => int`, with 3 (unused) type parameters from the enclosing class
-    // and method.
-    var library = await checkLibrary('''
-class C<T> {
-  f<U, V>() {
-    print(() => () => 0);
-  }
-}
-''');
-    checkElementText(library, r'''
-class C<T> {
-  dynamic f<U, V>() {}
-}
-''');
-  }
-
-  test_inferred_function_type_in_generic_class_setter() async {
-    // In the code below, `() => () => 0` has an inferred return type of
-    // `() => int`, with 2 (unused) type parameters from the enclosing class.
-    var library = await checkLibrary('''
-class C<U, V> {
-  void set x(value) {
-    print(() => () => 0);
-  }
-}
-''');
-    checkElementText(library, r'''
-class C<U, V> {
-  void set x(dynamic value) {}
-}
-''');
-  }
-
-  test_inferred_function_type_in_generic_closure() async {
-    if (!isStrongMode) {
-      // The test below uses generic comment syntax because proper generic
-      // method syntax doesn't support generic closures.  So it can only run in
-      // strong mode.
-      // TODO(paulberry): once proper generic method syntax supports generic
-      // closures, rewrite the test below without using generic comment syntax,
-      // and remove this hack.  See dartbug.com/25819
-      return;
-    }
-    // In the code below, `<U, V>() => () => 0` has an inferred return type of
-    // `() => int`, with 3 (unused) type parameters.
-    var library = await checkLibrary('''
-f<T>() {
-  print(/*<U, V>*/() => () => 0);
-}
-''');
-    if (isStrongMode) {
-      checkElementText(library, r'''
-dynamic f<T>() {}
-''');
-    } else {
-      checkElementText(library, r'''
-''');
-    }
-  }
-
-  test_inferred_generic_function_type_in_generic_closure() async {
-    if (!isStrongMode) {
-      // The test below uses generic comment syntax because proper generic
-      // method syntax doesn't support generic closures.  So it can only run in
-      // strong mode.
-      // TODO(paulberry): once proper generic method syntax supports generic
-      // closures, rewrite the test below without using generic comment syntax,
-      // and remove this hack.  See dartbug.com/25819
-      return;
-    }
-    // In the code below, `<U, V>() => <W, X, Y, Z>() => 0` has an inferred
-    // return type of `() => int`, with 7 (unused) type parameters.
-    var library = await checkLibrary('''
-f<T>() {
-  print(/*<U, V>*/() => /*<W, X, Y, Z>*/() => 0);
-}
-''');
-    if (isStrongMode) {
-      checkElementText(library, r'''
-dynamic f<T>() {}
-''');
-    } else {
-      checkElementText(library, r'''
-''');
-    }
-  }
-
-  test_inferred_type_is_typedef() async {
-    var library = await checkLibrary('typedef int F(String s);'
-        ' class C extends D { var v; }'
-        ' abstract class D { F get v; }');
-    if (isStrongMode) {
-      checkElementText(library, r'''
-typedef F = int Function(String s);
-class C extends D {
-  (String) → int v;
-}
-abstract class D {
-  (String) → int get v;
-}
-''');
-    } else {
-      checkElementText(library, r'''
-typedef F = int Function(String s);
-class C extends D {
-  dynamic v;
-}
-abstract class D {
-  (String) → int get v;
-}
-''');
-    }
-  }
-
-  test_inferred_type_refers_to_bound_type_param() async {
-    var library = await checkLibrary('''
-class C<T> extends D<int, T> {
-  var v;
-}
-abstract class D<U, V> {
-  Map<V, U> get v;
-}
-''');
-    if (isStrongMode) {
-      checkElementText(library, r'''
-class C<T> extends D<int, T> {
-  Map<T, int> v;
-}
-abstract class D<U, V> {
-  Map<V, U> get v;
-}
-''');
-    } else {
-      checkElementText(library, r'''
-class C<T> extends D<int, T> {
-  dynamic v;
-}
-abstract class D<U, V> {
-  Map<V, U> get v;
-}
-''');
-    }
-  }
-
-  test_inferred_type_refers_to_function_typed_param_of_typedef() async {
-    var library = await checkLibrary('''
-typedef void F(int g(String s));
-h(F f) => null;
-var v = h(/*info:INFERRED_TYPE_CLOSURE*/(y) {});
-''');
-    checkElementText(library, r'''
-typedef F = void Function((String) → int g);
-dynamic v;
-dynamic h(((String) → int) → void f) {}
-''');
-  }
-
-  test_inferred_type_refers_to_function_typed_parameter_type_generic_class() async {
-    var library = await checkLibrary('''
-class C<T, U> extends D<U, int> {
-  void f(int x, g) {}
-}
-abstract class D<V, W> {
-  void f(int x, W g(V s));
-}''');
-    if (isStrongMode) {
-      checkElementText(library, r'''
-class C<T, U> extends D<U, int> {
-  void f(int x, (U) → int g) {}
-}
-abstract class D<V, W> {
-  void f(int x, (V) → W g);
-}
-''');
-    } else {
-      checkElementText(library, r'''
-class C<T, U> extends D<U, int> {
-  void f(int x, dynamic g) {}
-}
-abstract class D<V, W> {
-  void f(int x, (V) → W g);
-}
-''');
-    }
-  }
-
-  test_inferred_type_refers_to_function_typed_parameter_type_other_lib() async {
-    addLibrarySource('/a.dart', '''
-import 'b.dart';
-abstract class D extends E {}
-''');
-    addLibrarySource('/b.dart', '''
-abstract class E {
-  void f(int x, int g(String s));
-}
-''');
-    var library = await checkLibrary('''
-import 'a.dart';
-class C extends D {
-  void f(int x, g) {}
-}
-''');
-    if (isStrongMode) {
-      checkElementText(library, r'''
-import 'a.dart';
-class C extends D {
-  void f(int x, (String) → int g) {}
-}
-''');
-    } else {
-      checkElementText(library, r'''
-import 'a.dart';
-class C extends D {
-  void f(int x, dynamic g) {}
-}
-''');
-    }
-  }
-
-  test_inferred_type_refers_to_method_function_typed_parameter_type() async {
-    var library = await checkLibrary('class C extends D { void f(int x, g) {} }'
-        ' abstract class D { void f(int x, int g(String s)); }');
-    if (isStrongMode) {
-      checkElementText(library, r'''
-class C extends D {
-  void f(int x, (String) → int g) {}
-}
-abstract class D {
-  void f(int x, (String) → int g);
-}
-''');
-    } else {
-      checkElementText(library, r'''
-class C extends D {
-  void f(int x, dynamic g) {}
-}
-abstract class D {
-  void f(int x, (String) → int g);
-}
-''');
-    }
-  }
-
-  test_inferred_type_refers_to_nested_function_typed_param() async {
-    var library = await checkLibrary('''
-f(void g(int x, void h())) => null;
-var v = f((x, y) {});
-''');
-    checkElementText(library, r'''
-dynamic v;
-dynamic f((int, () → void) → void g) {}
-''');
-  }
-
-  test_inferred_type_refers_to_nested_function_typed_param_named() async {
-    var library = await checkLibrary('''
-f({void g(int x, void h())}) => null;
-var v = f(g: (x, y) {});
-''');
-    checkElementText(library, r'''
-dynamic v;
-dynamic f({(int, () → void) → void g}) {}
-''');
-  }
-
-  test_inferred_type_refers_to_setter_function_typed_parameter_type() async {
-    var library = await checkLibrary('class C extends D { void set f(g) {} }'
-        ' abstract class D { void set f(int g(String s)); }');
-    if (isStrongMode) {
-      checkElementText(library, r'''
-class C extends D {
-  void set f((String) → int g) {}
-}
-abstract class D {
-  void set f((String) → int g);
-}
-''');
-    } else {
-      checkElementText(library, r'''
-class C extends D {
-  void set f(dynamic g) {}
-}
-abstract class D {
-  void set f((String) → int g);
-}
-''');
-    }
-  }
-
-  test_inferredType_definedInSdkLibraryPart() async {
-    addSource('/a.dart', r'''
-import 'dart:async';
-class A {
-  m(Stream p) {}
-}
-''');
-    LibraryElement library = await checkLibrary(r'''
-import 'a.dart';
-class B extends A {
-  m(p) {}
-}
-  ''');
-    if (isStrongMode) {
-      checkElementText(library, r'''
-import 'a.dart';
-class B extends A {
-  dynamic m(Stream<dynamic> p) {}
-}
-''');
-    } else {
-      checkElementText(library, r'''
-import 'a.dart';
-class B extends A {
-  dynamic m(dynamic p) {}
-}
-''');
-    }
-    ClassElement b = library.definingCompilationUnit.types[0];
-    ParameterElement p = b.methods[0].parameters[0];
-    // This test should verify that we correctly record inferred types,
-    // when the type is defined in a part of an SDK library. So, test that
-    // the type is actually in a part.
-    Element streamElement = p.type.element;
-    if (streamElement is ClassElement) {
-      expect(streamElement.source, isNot(streamElement.library.source));
-    }
-  }
-
-  test_inferredType_implicitCreation() async {
-    shouldCompareLibraryElements = false;
-    var library = await checkLibrary(r'''
-class A {
-  A();
-  A.named();
-}
-var a1 = A();
-var a2 = A.named();
-''');
-    if (isStrongMode) {
-      checkElementText(library, r'''
-class A {
-  A();
-  A.named();
-}
-A a1;
-A a2;
-''');
-    } else {
-      checkElementText(library, r'''
-class A {
-  A();
-  A.named();
-}
-dynamic a1;
-dynamic a2;
-''');
-    }
-  }
-
-  test_inferredType_implicitCreation_prefixed() async {
-    shouldCompareLibraryElements = false;
-    addLibrarySource('/foo.dart', '''
-class A {
-  A();
-  A.named();
-}
-''');
-    var library = await checkLibrary('''
-import 'foo.dart' as foo;
-var a1 = foo.A();
-var a2 = foo.A.named();
-''');
-    if (isStrongMode) {
-      checkElementText(library, r'''
-import 'foo.dart' as foo;
-A a1;
-A a2;
-''');
-    } else {
-      checkElementText(library, r'''
-import 'foo.dart' as foo;
-dynamic a1;
-dynamic a2;
-''');
-    }
-  }
-
-  test_inferredType_usesSyntheticFunctionType_functionTypedParam() async {
-    // AnalysisContext does not set the enclosing element for the synthetic
-    // FunctionElement created for the [f, g] type argument.
-    shouldCompareLibraryElements = false;
-    var library = await checkLibrary('''
-int f(int x(String y)) => null;
-String g(int x(String y)) => null;
-var v = [f, g];
-''');
-    if (isStrongMode) {
-      checkElementText(library, r'''
-List<((String) → int) → Object> v;
-int f((String) → int x) {}
-String g((String) → int x) {}
-''');
-    } else {
-      checkElementText(library, r'''
-dynamic v;
-int f((String) → int x) {}
-String g((String) → int x) {}
-''');
-    }
-  }
-
-  test_inheritance_errors() async {
-    var library = await checkLibrary('''
-abstract class A {
-  int m();
-}
-
-abstract class B {
-  String m();
-}
-
-abstract class C implements A, B {}
-
-abstract class D extends C {
-  var f;
-}
-''');
-    checkElementText(library, r'''
-abstract class A {
-  int m();
-}
-abstract class B {
-  String m();
-}
-abstract class C implements A, B {
-}
-abstract class D extends C {
-  dynamic f;
-}
-''');
-  }
-
-  test_initializer_executable_with_return_type_from_closure() async {
-    var library = await checkLibrary('var v = () => 0;');
-    if (isStrongMode) {
-      checkElementText(library, r'''
-() → int v;
-''');
-    } else {
-      checkElementText(library, r'''
-dynamic v;
-''');
-    }
-  }
-
-  test_initializer_executable_with_return_type_from_closure_await_dynamic() async {
-    var library = await checkLibrary('var v = (f) async => await f;');
-    if (isStrongMode) {
-      checkElementText(library, r'''
-(dynamic) → Future<dynamic> v;
-''');
-    } else {
-      checkElementText(library, r'''
-dynamic v;
-''');
-    }
-  }
-
-  test_initializer_executable_with_return_type_from_closure_await_future3_int() async {
-    var library = await checkLibrary(r'''
-import 'dart:async';
-var v = (Future<Future<Future<int>>> f) async => await f;
-''');
-    if (isStrongMode) {
-      if (isSharedFrontEnd) {
-        checkElementText(library, r'''
-import 'dart:async';
-(Future<Future<Future<int>>>) → Future<Future<int>> v;
-''');
-      } else {
-        // The analyzer type system over-flattens - see dartbug.com/31887
-        checkElementText(library, r'''
-import 'dart:async';
-(Future<Future<Future<int>>>) → Future<int> v;
-''');
-      }
-    } else {
-      checkElementText(library, r'''
-import 'dart:async';
-dynamic v;
-''');
-    }
-  }
-
-  test_initializer_executable_with_return_type_from_closure_await_future_int() async {
-    var library = await checkLibrary(r'''
-import 'dart:async';
-var v = (Future<int> f) async => await f;
-''');
-    if (isStrongMode) {
-      checkElementText(library, r'''
-import 'dart:async';
-(Future<int>) → Future<int> v;
-''');
-    } else {
-      checkElementText(library, r'''
-import 'dart:async';
-dynamic v;
-''');
-    }
-  }
-
-  test_initializer_executable_with_return_type_from_closure_await_future_noArg() async {
-    var library = await checkLibrary(r'''
-import 'dart:async';
-var v = (Future f) async => await f;
-''');
-    if (isStrongMode) {
-      checkElementText(library, r'''
-import 'dart:async';
-(Future<dynamic>) → Future<dynamic> v;
-''');
-    } else {
-      checkElementText(library, r'''
-import 'dart:async';
-dynamic v;
-''');
-    }
-  }
-
-  test_initializer_executable_with_return_type_from_closure_field() async {
-    var library = await checkLibrary('''
-class C {
-  var v = () => 0;
-}
-''');
-    if (isStrongMode) {
-      checkElementText(library, r'''
-class C {
-  () → int v;
-}
-''');
-    } else {
-      checkElementText(library, r'''
-class C {
-  dynamic v;
-}
-''');
-    }
-  }
-
-  test_initializer_executable_with_return_type_from_closure_local() async {
-    var library = await checkLibrary('''
-void f() {
-  int u = 0;
-  var v = () => 0;
-}
-''');
-    checkElementText(library, r'''
-void f() {}
-''');
-  }
-
-  test_instantiateToBounds_boundRefersToEarlierTypeArgument() async {
-    var library = await checkLibrary('''
-class C<S extends num, T extends C<S, T>> {}
-C c;
-''');
-    if (isStrongMode) {
-      checkElementText(library, r'''
-class C<S extends num, T extends C<S, T>> {
-}
-C<num, C<num, dynamic>> c;
-''');
-    } else {
-      checkElementText(library, r'''
-class C<S extends num, T extends C<S, T>> {
-}
-C<dynamic, dynamic> c;
-''');
-    }
-  }
-
-  test_instantiateToBounds_boundRefersToItself() async {
-    var library = await checkLibrary('''
-class C<T extends C<T>> {}
-C c;
-var c2 = new C();
-class B {
-  var c3 = new C();
-}
-''');
-    if (isStrongMode) {
-      checkElementText(library, r'''
-class C<T extends C<T>> {
-}
-class B {
-  C<C<dynamic>> c3;
-}
-C<C<dynamic>> c;
-C<C<dynamic>> c2;
-''');
-    } else {
-      checkElementText(library, r'''
-class C<T extends C<T>> {
-}
-class B {
-  dynamic c3;
-}
-C<dynamic> c;
-dynamic c2;
-''');
-    }
-  }
-
-  test_instantiateToBounds_boundRefersToLaterTypeArgument() async {
-    var library = await checkLibrary('''
-class C<T extends C<T, U>, U extends num> {}
-C c;
-''');
-    if (isStrongMode) {
-      checkElementText(library, r'''
-class C<T extends C<T, U>, U extends num> {
-}
-C<C<dynamic, num>, num> c;
-''');
-    } else {
-      checkElementText(library, r'''
-class C<T extends C<T, U>, U extends num> {
-}
-C<dynamic, dynamic> c;
-''');
-    }
-  }
-
-  test_instantiateToBounds_functionTypeAlias_reexported() async {
-    addLibrarySource('/a.dart', r'''
-class O {}
-typedef T F<T extends O>(T p);
-''');
-    addLibrarySource('/b.dart', r'''
-export 'a.dart' show F;
-''');
-    var library = await checkLibrary('''
-import 'b.dart';
-class C {
-  F f() => null;
-}
-''');
-    if (isStrongMode) {
-      checkElementText(library, r'''
-import 'b.dart';
-class C {
-  (O) → O f() {}
-}
-''');
-    } else {
-      checkElementText(library, r'''
-import 'b.dart';
-class C {
-  (dynamic) → dynamic f() {}
-}
-''');
-    }
-  }
-
-  test_instantiateToBounds_functionTypeAlias_simple() async {
-    var library = await checkLibrary('''
-typedef F<T extends num>(T p);
-F f;
-''');
-    if (isStrongMode) {
-      checkElementText(library, r'''
-typedef F<T extends num> = dynamic Function(T p);
-(num) → dynamic f;
-''');
-    } else {
-      checkElementText(library, r'''
-typedef F<T extends num> = dynamic Function(T p);
-(dynamic) → dynamic f;
-''');
-    }
-  }
-
-  test_instantiateToBounds_simple() async {
-    var library = await checkLibrary('''
-class C<T extends num> {}
-C c;
-''');
-    if (isStrongMode) {
-      checkElementText(library, r'''
-class C<T extends num> {
-}
-C<num> c;
-''');
-    } else {
-      checkElementText(library, r'''
-class C<T extends num> {
-}
-C<dynamic> c;
-''');
-    }
-  }
-
-  test_invalid_annotation_prefixed_constructor() async {
-    shouldCompareLibraryElements = false;
-    addLibrarySource('/a.dart', r'''
-class C {
-  const C.named();
-}
-''');
-    var library = await checkLibrary('''
-import "a.dart" as a;
-@a.C.named
-class D {}
-''');
-    checkElementText(library, r'''
-import 'a.dart' as a;
-@#invalidConst
-class D {
-}
-''');
-  }
-
-  test_invalid_annotation_unprefixed_constructor() async {
-    shouldCompareLibraryElements = false;
-    addLibrarySource('/a.dart', r'''
-class C {
-  const C.named();
-}
-''');
-    var library = await checkLibrary('''
-import "a.dart";
-@C.named
-class D {}
-''');
-    checkElementText(library, r'''
-import 'a.dart';
-@#invalidConst
-class D {
-}
-''');
-  }
-
-  test_invalid_importPrefix_asTypeArgument() async {
-    var library = await checkLibrary('''
-import 'dart:async' as ppp;
-class C {
-  List<ppp> v;
-}
-''');
-    checkElementText(library, r'''
-import 'dart:async' as ppp;
-class C {
-  List<dynamic> v;
-}
-''');
-  }
-
-  test_invalid_nameConflict_imported() async {
-    shouldCompareLibraryElements = false;
-    namesThatCannotBeResolved.add('V');
-    addLibrarySource('/a.dart', 'V() {}');
-    addLibrarySource('/b.dart', 'V() {}');
-    var library = await checkLibrary('''
-import 'a.dart';
-import 'b.dart';
-foo([p = V]) {}
-''');
-    checkElementText(library, r'''
-import 'a.dart';
-import 'b.dart';
-dynamic foo([dynamic p = #invalidConst]) {}
-''');
-  }
-
-  test_invalid_nameConflict_imported_exported() async {
-    shouldCompareLibraryElements = false;
-    namesThatCannotBeResolved.add('V');
-    addLibrarySource('/a.dart', 'V() {}');
-    addLibrarySource('/b.dart', 'V() {}');
-    addLibrarySource('/c.dart', r'''
-export 'a.dart';
-export 'b.dart';
-''');
-    var library = await checkLibrary('''
-import 'c.dart';
-foo([p = V]) {}
-''');
-    checkElementText(library, r'''
-import 'c.dart';
-dynamic foo([dynamic p = #invalidConst]) {}
-''');
-  }
-
-  test_invalid_nameConflict_local() async {
-    shouldCompareLibraryElements = false;
-    namesThatCannotBeResolved.add('V');
-    var library = await checkLibrary('''
-foo([p = V]) {}
-V() {}
-var V;
-''');
-    checkElementText(library, r'''
-dynamic V;
-dynamic foo([dynamic p = #invalidConst]) {}
-dynamic V() {}
-''');
-  }
-
-  test_invalid_setterParameter_fieldFormalParameter() async {
-    var library = await checkLibrary('''
-class C {
-  int foo;
-  void set bar(this.foo) {}
-}
-''');
-    checkElementText(library, r'''
-class C {
-  int foo;
-  void set bar(dynamic this.foo) {}
-}
-''');
-  }
-
-  test_invalid_setterParameter_fieldFormalParameter_self() async {
-    var library = await checkLibrary('''
-class C {
-  set x(this.x) {}
-}
-''');
-    if (isStrongMode) {
-      checkElementText(library, r'''
-class C {
-  void set x(dynamic this.x) {}
-}
-''');
-    } else {
-      checkElementText(library, r'''
-class C {
-  dynamic set x(dynamic this.x) {}
-}
-''');
-    }
-  }
-
-  test_invalidUri_part_emptyUri() async {
-    allowMissingFiles = true;
-    shouldCompareLibraryElements = false;
-    var library = await checkLibrary(r'''
-part '';
-class B extends A {}
-''');
-    checkElementText(library, r'''
-part '<unresolved>';
-class B {
-}
---------------------
-unit: null
-
-''');
-  }
-
-  test_invalidUris() async {
-    allowMissingFiles = true;
-    shouldCompareLibraryElements = false;
-    var library = await checkLibrary(r'''
-import '[invalid uri]';
-import '[invalid uri]:foo.dart';
-import 'a1.dart';
-import '[invalid uri]';
-import '[invalid uri]:foo.dart';
-
-export '[invalid uri]';
-export '[invalid uri]:foo.dart';
-export 'a2.dart';
-export '[invalid uri]';
-export '[invalid uri]:foo.dart';
-
-part '[invalid uri]';
-part 'a3.dart';
-part '[invalid uri]';
-''');
-    checkElementText(library, r'''
-import '<unresolved>';
-import '<unresolved>';
-import 'a1.dart';
-import '<unresolved>';
-import '<unresolved>';
-export '<unresolved>';
-export '<unresolved>';
-export 'a2.dart';
-export '<unresolved>';
-export '<unresolved>';
-part '<unresolved>';
-part 'a3.dart';
-part '<unresolved>';
---------------------
-unit: null
-
---------------------
-unit: a3.dart
-
---------------------
-unit: null
-
-''');
-  }
-
-  test_library() async {
-    var library = await checkLibrary('');
-    checkElementText(library, r'''
-''');
-  }
-
-  test_library_documented_lines() async {
-    var library = await checkLibrary('''
-/// aaa
-/// bbb
-library test;
-''');
-    checkElementText(library, r'''
-/// aaa
-/// bbb
-library test;
-''');
-  }
-
-  test_library_documented_stars() async {
-    var library = await checkLibrary('''
-/**
- * aaa
- * bbb
- */
-library test;''');
-    checkElementText(library, r'''
-/**
- * aaa
- * bbb
- */
-library test;
-''');
-  }
-
-  test_library_name_with_spaces() async {
-    var library = await checkLibrary('library foo . bar ;');
-    checkElementText(library, r'''
-library foo.bar;
-''');
-  }
-
-  test_library_named() async {
-    var library = await checkLibrary('library foo.bar;');
-    checkElementText(library, r'''
-library foo.bar;
-''');
-  }
-
-  test_localFunctions() async {
-    var library = await checkLibrary(r'''
-f() {
-  f1() {}
-  {
-    f2() {}
-  }
-}
-''');
-    checkElementText(library, r'''
-dynamic f() {}
-''');
-  }
-
-  test_localFunctions_inConstructor() async {
-    var library = await checkLibrary(r'''
-class C {
-  C() {
-    f() {}
-  }
-}
-''');
-    checkElementText(library, r'''
-class C {
-  C();
-}
-''');
-  }
-
-  test_localFunctions_inMethod() async {
-    var library = await checkLibrary(r'''
-class C {
-  m() {
-    f() {}
-  }
-}
-''');
-    checkElementText(library, r'''
-class C {
-  dynamic m() {}
-}
-''');
-  }
-
-  test_localFunctions_inTopLevelGetter() async {
-    var library = await checkLibrary(r'''
-get g {
-  f() {}
-}
-''');
-    checkElementText(library, r'''
-dynamic get g {}
-''');
-  }
-
-  test_localLabels_inConstructor() async {
-    var library = await checkLibrary(r'''
-class C {
-  C() {
-    aaa: while (true) {}
-    bbb: switch (42) {
-      ccc: case 0:
-        break;
-    }
-  }
-}
-''', allowErrors: true);
-    checkElementText(library, r'''
-class C {
-  C();
-}
-''');
-  }
-
-  test_localLabels_inMethod() async {
-    var library = await checkLibrary(r'''
-class C {
-  m() {
-    aaa: while (true) {}
-    bbb: switch (42) {
-      ccc: case 0:
-        break;
-    }
-  }
-}
-''', allowErrors: true);
-    checkElementText(library, r'''
-class C {
-  dynamic m() {}
-}
-''');
-  }
-
-  test_localLabels_inTopLevelFunction() async {
-    var library = await checkLibrary(r'''
-main() {
-  aaa: while (true) {}
-  bbb: switch (42) {
-    ccc: case 0:
-      break;
-  }
-}
-''', allowErrors: true);
-    checkElementText(library, r'''
-dynamic main() {}
-''');
-  }
-
-  test_main_class() async {
-    var library = await checkLibrary('class main {}');
-    checkElementText(library, r'''
-class main {
-}
-''');
-  }
-
-  test_main_class_alias() async {
-    var library =
-        await checkLibrary('class main = C with D; class C {} class D {}');
-    checkElementText(library, r'''
-class alias main extends C with D {
-  synthetic main() = C;
-}
-class C {
-}
-class D {
-}
-''');
-  }
-
-  test_main_class_alias_via_export() async {
-    addLibrarySource('/a.dart', 'class main = C with D; class C {} class D {}');
-    var library = await checkLibrary('export "a.dart";');
-    checkElementText(library, r'''
-export 'a.dart';
-''');
-  }
-
-  test_main_class_via_export() async {
-    addLibrarySource('/a.dart', 'class main {}');
-    var library = await checkLibrary('export "a.dart";');
-    checkElementText(library, r'''
-export 'a.dart';
-''');
-  }
-
-  test_main_getter() async {
-    var library = await checkLibrary('get main => null;');
-    checkElementText(library, r'''
-dynamic get main {}
-''');
-  }
-
-  test_main_getter_via_export() async {
-    addLibrarySource('/a.dart', 'get main => null;');
-    var library = await checkLibrary('export "a.dart";');
-    checkElementText(library, r'''
-export 'a.dart';
-''');
-  }
-
-  test_main_typedef() async {
-    var library = await checkLibrary('typedef main();');
-    checkElementText(library, r'''
-typedef main = dynamic Function();
-''');
-  }
-
-  test_main_typedef_via_export() async {
-    addLibrarySource('/a.dart', 'typedef main();');
-    var library = await checkLibrary('export "a.dart";');
-    checkElementText(library, r'''
-export 'a.dart';
-''');
-  }
-
-  test_main_variable() async {
-    var library = await checkLibrary('var main;');
-    checkElementText(library, r'''
-dynamic main;
-''');
-  }
-
-  test_main_variable_via_export() async {
-    addLibrarySource('/a.dart', 'var main;');
-    var library = await checkLibrary('export "a.dart";');
-    checkElementText(library, r'''
-export 'a.dart';
-''');
-  }
-
-  test_member_function_async() async {
-    var library = await checkLibrary(r'''
-import 'dart:async';
-class C {
-  Future f() async {}
-}
-''');
-    checkElementText(library, r'''
-import 'dart:async';
-class C {
-  Future<dynamic> f() async {}
-}
-''');
-  }
-
-  test_member_function_asyncStar() async {
-    var library = await checkLibrary(r'''
-import 'dart:async';
-class C {
-  Stream f() async* {}
-}
-''');
-    checkElementText(library, r'''
-import 'dart:async';
-class C {
-  Stream<dynamic> f() async* {}
-}
-''');
-  }
-
-  test_member_function_syncStar() async {
-    var library = await checkLibrary(r'''
-class C {
-  Iterable<int> f() sync* {
-    yield 42;
-  }
-}
-''');
-    checkElementText(library, r'''
-class C {
-  Iterable<int> f() sync* {}
-}
-''');
-  }
-
-  test_metadata_classDeclaration() async {
-    var library = await checkLibrary(r'''
-const a = null;
-const b = null;
-@a
-@b
-class C {}''');
-    checkElementText(library, r'''
-@
-        a/*location: test.dart;a?*/
-@
-        b/*location: test.dart;b?*/
-class C {
-}
-const dynamic a = null;
-const dynamic b = null;
-''');
-  }
-
-  test_metadata_classTypeAlias() async {
-    var library = await checkLibrary(
-        'const a = null; @a class C = D with E; class D {} class E {}');
-    checkElementText(library, r'''
-@
-        a/*location: test.dart;a?*/
-class alias C extends D with E {
-  synthetic C() = D;
-}
-class D {
-}
-class E {
-}
-const dynamic a = null;
-''');
-  }
-
-  test_metadata_constructor_call_named() async {
-    var library = await checkLibrary('''
-class A {
-  const A.named();
-}
-@A.named()
-class C {}
-''');
-    checkElementText(library, r'''
-class A {
-  const A.named();
-}
-@
-        A/*location: test.dart;A*/.
-        named/*location: test.dart;A;named*/()
-class C {
-}
-''');
-  }
-
-  test_metadata_constructor_call_named_prefixed() async {
-    addLibrarySource('/foo.dart', 'class A { const A.named(); }');
-    var library = await checkLibrary('''
-import 'foo.dart' as foo;
-@foo.A.named()
-class C {}
-''');
-    checkElementText(library, r'''
-import 'foo.dart' as foo;
-@
-        A/*location: foo.dart;A*/.
-        named/*location: foo.dart;A;named*/()
-class C {
-}
-''');
-  }
-
-  test_metadata_constructor_call_unnamed() async {
-    var library = await checkLibrary('class A { const A(); } @A() class C {}');
-    checkElementText(library, r'''
-class A {
-  const A();
-}
-@
-        A/*location: test.dart;A*/()
-class C {
-}
-''');
-  }
-
-  test_metadata_constructor_call_unnamed_prefixed() async {
-    addLibrarySource('/foo.dart', 'class A { const A(); }');
-    var library =
-        await checkLibrary('import "foo.dart" as foo; @foo.A() class C {}');
-    checkElementText(library, r'''
-import 'foo.dart' as foo;
-@
-        A/*location: foo.dart;A*/()
-class C {
-}
-''');
-  }
-
-  test_metadata_constructor_call_with_args() async {
-    var library =
-        await checkLibrary('class A { const A(x); } @A(null) class C {}');
-    checkElementText(library, r'''
-class A {
-  const A(dynamic x);
-}
-@
-        A/*location: test.dart;A*/(null)
-class C {
-}
-''');
-  }
-
-  test_metadata_constructorDeclaration_named() async {
-    var library =
-        await checkLibrary('const a = null; class C { @a C.named(); }');
-    checkElementText(library, r'''
-class C {
-  @
-        a/*location: test.dart;a?*/
-  C.named();
-}
-const dynamic a = null;
-''');
-  }
-
-  test_metadata_constructorDeclaration_unnamed() async {
-    var library = await checkLibrary('const a = null; class C { @a C(); }');
-    checkElementText(library, r'''
-class C {
-  @
-        a/*location: test.dart;a?*/
-  C();
-}
-const dynamic a = null;
-''');
-  }
-
-  test_metadata_enumConstantDeclaration() async {
-    var library = await checkLibrary('const a = null; enum E { @a v }');
-    checkElementText(library, r'''
-enum E {
-  synthetic final int index;
-  synthetic static const List<E> values;
-  @
-        a/*location: test.dart;a?*/
-  static const E v;
-  String toString() {}
-}
-const dynamic a = null;
-''');
-  }
-
-  test_metadata_enumDeclaration() async {
-    var library = await checkLibrary('const a = null; @a enum E { v }');
-    checkElementText(library, r'''
-@
-        a/*location: test.dart;a?*/
-enum E {
-  synthetic final int index;
-  synthetic static const List<E> values;
-  static const E v;
-  String toString() {}
-}
-const dynamic a = null;
-''');
-  }
-
-  test_metadata_exportDirective() async {
-    addLibrarySource('/foo.dart', '');
-    var library = await checkLibrary('@a export "foo.dart"; const a = null;');
-    checkElementText(library, r'''
-@
-        a/*location: test.dart;a?*/
-export 'foo.dart';
-const dynamic a = null;
-''');
-  }
-
-  test_metadata_fieldDeclaration() async {
-    var library = await checkLibrary('const a = null; class C { @a int x; }');
-    checkElementText(library, r'''
-class C {
-  @
-        a/*location: test.dart;a?*/
-  int x;
-}
-const dynamic a = null;
-''');
-  }
-
-  test_metadata_fieldFormalParameter() async {
-    var library = await checkLibrary('''
-const a = null;
-class C {
-  var x;
-  C(@a this.x);
-}
-''');
-    checkElementText(library, r'''
-class C {
-  dynamic x;
-  C(@
-        a/*location: test.dart;a?*/ dynamic this.x);
-}
-const dynamic a = null;
-''');
-  }
-
-  test_metadata_fieldFormalParameter_withDefault() async {
-    var library = await checkLibrary(
-        'const a = null; class C { var x; C([@a this.x = null]); }');
-    checkElementText(library, r'''
-class C {
-  dynamic x;
-  C([@
-        a/*location: test.dart;a?*/ dynamic this.x = null]);
-}
-const dynamic a = null;
-''');
-  }
-
-  test_metadata_functionDeclaration_function() async {
-    var library = await checkLibrary('''
-const a = null;
-@a
-f() {}
-''');
-    checkElementText(library, r'''
-const dynamic a = null;
-@
-        a/*location: test.dart;a?*/
-dynamic f() {}
-''');
-  }
-
-  test_metadata_functionDeclaration_getter() async {
-    var library = await checkLibrary('const a = null; @a get f => null;');
-    checkElementText(library, r'''
-const dynamic a = null;
-@
-        a/*location: test.dart;a?*/
-dynamic get f {}
-''');
-  }
-
-  test_metadata_functionDeclaration_setter() async {
-    var library = await checkLibrary('const a = null; @a set f(value) {}');
-    if (isStrongMode) {
-      checkElementText(library, r'''
-const dynamic a = null;
-@
-        a/*location: test.dart;a?*/
-void set f(dynamic value) {}
-''');
-    } else {
-      checkElementText(library, r'''
-const dynamic a = null;
-@
-        a/*location: test.dart;a?*/
-dynamic set f(dynamic value) {}
-''');
-    }
-  }
-
-  test_metadata_functionTypeAlias() async {
-    var library = await checkLibrary('const a = null; @a typedef F();');
-    checkElementText(library, r'''
-@
-        a/*location: test.dart;a?*/
-typedef F = dynamic Function();
-const dynamic a = null;
-''');
-  }
-
-  test_metadata_functionTypedFormalParameter() async {
-    var library = await checkLibrary('const a = null; f(@a g()) {}');
-    checkElementText(library, r'''
-const dynamic a = null;
-dynamic f(@
-        a/*location: test.dart;a?*/ () → dynamic g) {}
-''');
-  }
-
-  test_metadata_functionTypedFormalParameter_withDefault() async {
-    var library = await checkLibrary('const a = null; f([@a g() = null]) {}');
-    checkElementText(library, r'''
-const dynamic a = null;
-dynamic f([@
-        a/*location: test.dart;a?*/ () → dynamic g = null]) {}
-''');
-  }
-
-  test_metadata_importDirective() async {
-    addLibrarySource('/foo.dart', 'const b = null;');
-    var library = await checkLibrary('@a import "foo.dart"; const a = b;');
-    checkElementText(library, r'''
-@
-        a/*location: test.dart;a?*/
-import 'foo.dart';
-const dynamic a =
-        b/*location: foo.dart;b?*/;
-''');
-  }
-
-  test_metadata_invalid_classDeclaration() async {
-    shouldCompareLibraryElements = false;
-    var library = await checkLibrary('f(_) {} @f(42) class C {}');
-    checkElementText(library, r'''
-@#invalidConst
-class C {
-}
-dynamic f(dynamic _) {}
-''');
-  }
-
-  test_metadata_libraryDirective() async {
-    var library = await checkLibrary('@a library L; const a = null;');
-    checkElementText(library, r'''
-@
-        a/*location: test.dart;a?*/
-library L;
-const dynamic a = null;
-''');
-  }
-
-  test_metadata_methodDeclaration_getter() async {
-    var library =
-        await checkLibrary('const a = null; class C { @a get m => null; }');
-    checkElementText(library, r'''
-class C {
-  @
-        a/*location: test.dart;a?*/
-  dynamic get m {}
-}
-const dynamic a = null;
-''');
-  }
-
-  test_metadata_methodDeclaration_method() async {
-    var library = await checkLibrary(r'''
-const a = null;
-const b = null;
-class C {
-  @a
-  @b
-  m() {}
-}
-''');
-    checkElementText(library, r'''
-class C {
-  @
-        a/*location: test.dart;a?*/
-  @
-        b/*location: test.dart;b?*/
-  dynamic m() {}
-}
-const dynamic a = null;
-const dynamic b = null;
-''');
-  }
-
-  test_metadata_methodDeclaration_setter() async {
-    var library = await checkLibrary('''
-const a = null;
-class C {
-  @a
-  set m(value) {}
-}
-''');
-    if (isStrongMode) {
-      checkElementText(library, r'''
-class C {
-  @
-        a/*location: test.dart;a?*/
-  void set m(dynamic value) {}
-}
-const dynamic a = null;
-''');
-    } else {
-      checkElementText(library, r'''
-class C {
-  @
-        a/*location: test.dart;a?*/
-  dynamic set m(dynamic value) {}
-}
-const dynamic a = null;
-''');
-    }
-  }
-
-  test_metadata_partDirective() async {
-    addSource('/foo.dart', 'part of L;');
-    var library = await checkLibrary('''
-library L;
-@a
-part 'foo.dart';
-const a = null;''');
-    checkElementText(library, r'''
-library L;
-@
-        a/*location: test.dart;a?*/
-part 'foo.dart';
-const dynamic a = null;
---------------------
-unit: foo.dart
-
-''');
-  }
-
-  test_metadata_prefixed_variable() async {
-    addLibrarySource('/a.dart', 'const b = null;');
-    var library = await checkLibrary('import "a.dart" as a; @a.b class C {}');
-    if (isSharedFrontEnd) {
-      checkElementText(library, r'''
-import 'a.dart' as a;
-@
-        b/*location: a.dart;b?*/
-class C {
-}
-''');
-    } else {
-      checkElementText(library, r'''
-import 'a.dart' as a;
-@
-        a/*location: test.dart;a*/.
-        b/*location: a.dart;b?*/
-class C {
-}
-''');
-    }
-  }
-
-  test_metadata_simpleFormalParameter() async {
-    var library = await checkLibrary('const a = null; f(@a x) {}');
-    checkElementText(library, r'''
-const dynamic a = null;
-dynamic f(@
-        a/*location: test.dart;a?*/ dynamic x) {}
-''');
-  }
-
-  test_metadata_simpleFormalParameter_withDefault() async {
-    var library = await checkLibrary('const a = null; f([@a x = null]) {}');
-    checkElementText(library, r'''
-const dynamic a = null;
-dynamic f([@
-        a/*location: test.dart;a?*/ dynamic x = null]) {}
-''');
-  }
-
-  test_metadata_topLevelVariableDeclaration() async {
-    var library = await checkLibrary('const a = null; @a int v;');
-    checkElementText(library, r'''
-const dynamic a = null;
-@
-        a/*location: test.dart;a?*/
-int v;
-''');
-  }
-
-  test_metadata_typeParameter_ofClass() async {
-    var library = await checkLibrary('const a = null; class C<@a T> {}');
-    checkElementText(library, r'''
-class C<T> {
-}
-const dynamic a = null;
-''');
-  }
-
-  test_metadata_typeParameter_ofClassTypeAlias() async {
-    var library = await checkLibrary('''
-const a = null;
-class C<@a T> = D with E;
-class D {}
-class E {}''');
-    checkElementText(library, r'''
-class alias C<T> extends D with E {
-  synthetic C() = D;
-}
-class D {
-}
-class E {
-}
-const dynamic a = null;
-''');
-  }
-
-  test_metadata_typeParameter_ofFunction() async {
-    var library = await checkLibrary('const a = null; f<@a T>() {}');
-    checkElementText(library, r'''
-const dynamic a = null;
-dynamic f<T>() {}
-''');
-  }
-
-  test_metadata_typeParameter_ofTypedef() async {
-    var library = await checkLibrary('const a = null; typedef F<@a T>();');
-    checkElementText(library, r'''
-typedef F<T> = dynamic Function();
-const dynamic a = null;
-''');
-  }
-
-  test_method_documented() async {
-    var library = await checkLibrary('''
-class C {
-  /**
-   * Docs
-   */
-  f() {}
-}''');
-    checkElementText(library, r'''
-class C {
-  /**
-   * Docs
-   */
-  dynamic f() {}
-}
-''');
-  }
-
-  test_method_inferred_type_nonStatic_implicit_param() async {
-    var library = await checkLibrary('class C extends D { void f(value) {} }'
-        ' abstract class D { void f(int value); }');
-    if (isStrongMode) {
-      checkElementText(library, r'''
-class C extends D {
-  void f(int value) {}
-}
-abstract class D {
-  void f(int value);
-}
-''');
-    } else {
-      checkElementText(library, r'''
-class C extends D {
-  void f(dynamic value) {}
-}
-abstract class D {
-  void f(int value);
-}
-''');
-    }
-  }
-
-  test_method_inferred_type_nonStatic_implicit_return() async {
-    var library = await checkLibrary('''
-class C extends D {
-  f() => null;
-}
-abstract class D {
-  int f();
-}
-''');
-    if (isStrongMode) {
-      checkElementText(library, r'''
-class C extends D {
-  int f() {}
-}
-abstract class D {
-  int f();
-}
-''');
-    } else {
-      checkElementText(library, r'''
-class C extends D {
-  dynamic f() {}
-}
-abstract class D {
-  int f();
-}
-''');
-    }
-  }
-
-  test_method_type_parameter() async {
-    var library = await checkLibrary('class C { T f<T, U>(U u) => null; }');
-    checkElementText(library, r'''
-class C {
-  T f<T, U>(U u) {}
-}
-''');
-  }
-
-  test_method_type_parameter_in_generic_class() async {
-    var library = await checkLibrary('''
-class C<T, U> {
-  V f<V, W>(T t, U u, W w) => null;
-}
-''');
-    checkElementText(library, r'''
-class C<T, U> {
-  V f<V, W>(T t, U u, W w) {}
-}
-''');
-  }
-
-  test_method_type_parameter_with_function_typed_parameter() async {
-    var library = await checkLibrary('class C { void f<T, U>(T x(U u)) {} }');
-    checkElementText(library, r'''
-class C {
-  void f<T, U>((U) → T x) {}
-}
-''');
-  }
-
-  test_methodInvocation_implicitCall() async {
-    var library = await checkLibrary(r'''
-class A {
-  double call() => 0.0;
-}
-class B {
-  A a;
-}
-var c = new B().a();
-''');
-    if (isStrongMode) {
-      checkElementText(library, r'''
-class A {
-  double call() {}
-}
-class B {
-  A a;
-}
-double c;
-''');
-    } else {
-      checkElementText(library, r'''
-class A {
-  double call() {}
-}
-class B {
-  A a;
-}
-dynamic c;
-''');
-    }
-  }
-
-  test_mixin() async {
-    var library = await checkLibrary(r'''
-class A {}
-class B {}
-class C {}
-class D {}
-
-mixin M<T extends num, U> on A, B implements C, D {
-  T f;
-  U get g => 0;
-  set s(int v) {}
-  int m(double v) => 0;
-}
-''');
-    checkElementText(library, r'''
-class A {
-}
-class B {
-}
-class C {
-}
-class D {
-}
-mixin M<T extends num, U> on A, B implements C, D {
-  T f;
-  U get g {}
-  void set s(int v) {}
-  int m(double v) {}
-}
-''');
-  }
-
-  test_mixin_implicitObjectSuperclassConstraint() async {
-    var library = await checkLibrary(r'''
-mixin M {}
-''');
-    checkElementText(library, r'''
-mixin M on Object {
-}
-''');
-  }
-
-  test_nameConflict_exportedAndLocal() async {
-    namesThatCannotBeResolved.add('V');
-    addLibrarySource('/a.dart', 'class C {}');
-    addLibrarySource('/c.dart', '''
-export 'a.dart';
-class C {}
-''');
-    var library = await checkLibrary('''
-import 'c.dart';
-C v = null;
-''');
-    checkElementText(library, r'''
-import 'c.dart';
-C v;
-''');
-  }
-
-  test_nameConflict_exportedAndLocal_exported() async {
-    namesThatCannotBeResolved.add('V');
-    addLibrarySource('/a.dart', 'class C {}');
-    addLibrarySource('/c.dart', '''
-export 'a.dart';
-class C {}
-''');
-    addLibrarySource('/d.dart', 'export "c.dart";');
-    var library = await checkLibrary('''
-import 'd.dart';
-C v = null;
-''');
-    checkElementText(library, r'''
-import 'd.dart';
-C v;
-''');
-  }
-
-  test_nameConflict_exportedAndParted() async {
-    namesThatCannotBeResolved.add('V');
-    addLibrarySource('/a.dart', 'class C {}');
-    addLibrarySource('/b.dart', '''
-part of lib;
-class C {}
-''');
-    addLibrarySource('/c.dart', '''
-library lib;
-export 'a.dart';
-part 'b.dart';
-''');
-    var library = await checkLibrary('''
-import 'c.dart';
-C v = null;
-''');
-    checkElementText(library, r'''
-import 'c.dart';
-C v;
-''');
-  }
-
-  test_nameConflict_importWithRelativeUri_exportWithAbsolute() async {
-    if (resourceProvider.pathContext.separator != '/') {
-      return;
-    }
-
-    addLibrarySource('/a.dart', 'class A {}');
-    addLibrarySource('/b.dart', 'export "/a.dart";');
-    var library = await checkLibrary('''
-import 'a.dart';
-import 'b.dart';
-A v = null;
-''');
-    checkElementText(library, r'''
-import 'a.dart';
-import 'b.dart';
-A v;
-''');
-  }
-
-  test_nested_generic_functions_in_generic_class_with_function_typed_params() async {
-    var library = await checkLibrary('''
-class C<T, U> {
-  void g<V, W>() {
-    void h<X, Y>(void p(T t, U u, V v, W w, X x, Y y)) {
-    }
-  }
-}
-''');
-    checkElementText(library, r'''
-class C<T, U> {
-  void g<V, W>() {}
-}
-''');
-  }
-
-  test_nested_generic_functions_in_generic_class_with_local_variables() async {
-    var library = await checkLibrary('''
-class C<T, U> {
-  void g<V, W>() {
-    void h<X, Y>() {
-      T t;
-      U u;
-      V v;
-      W w;
-      X x;
-      Y y;
-    }
-  }
-}
-''');
-    checkElementText(library, r'''
-class C<T, U> {
-  void g<V, W>() {}
-}
-''');
-  }
-
-  test_nested_generic_functions_with_function_typed_param() async {
-    var library = await checkLibrary('''
-void f<T, U>() {
-  void g<V, W>() {
-    void h<X, Y>(void p(T t, U u, V v, W w, X x, Y y)) {
-    }
-  }
-}
-''');
-    checkElementText(library, r'''
-void f<T, U>() {}
-''');
-  }
-
-  test_nested_generic_functions_with_local_variables() async {
-    var library = await checkLibrary('''
-void f<T, U>() {
-  void g<V, W>() {
-    void h<X, Y>() {
-      T t;
-      U u;
-      V v;
-      W w;
-      X x;
-      Y y;
-    }
-  }
-}
-''');
-    checkElementText(library, r'''
-void f<T, U>() {}
-''');
-  }
-
-  test_operator() async {
-    var library =
-        await checkLibrary('class C { C operator+(C other) => null; }');
-    checkElementText(library, r'''
-class C {
-  C +(C other) {}
-}
-''');
-  }
-
-  test_operator_equal() async {
-    var library = await checkLibrary('''
-class C {
-  bool operator==(Object other) => false;
-}
-''');
-    checkElementText(library, r'''
-class C {
-  bool ==(Object other) {}
-}
-''');
-  }
-
-  test_operator_external() async {
-    var library =
-        await checkLibrary('class C { external C operator+(C other); }');
-    checkElementText(library, r'''
-class C {
-  external C +(C other) {}
-}
-''');
-  }
-
-  test_operator_greater_equal() async {
-    var library = await checkLibrary('''
-class C {
-  bool operator>=(C other) => false;
-}
-''');
-    checkElementText(library, r'''
-class C {
-  bool >=(C other) {}
-}
-''');
-  }
-
-  test_operator_index() async {
-    var library =
-        await checkLibrary('class C { bool operator[](int i) => null; }');
-    checkElementText(library, r'''
-class C {
-  bool [](int i) {}
-}
-''');
-  }
-
-  test_operator_index_set() async {
-    var library = await checkLibrary('''
-class C {
-  void operator[]=(int i, bool v) {}
-}
-''');
-    checkElementText(library, r'''
-class C {
-  void []=(int i, bool v) {}
-}
-''');
-  }
-
-  test_operator_less_equal() async {
-    var library = await checkLibrary('''
-class C {
-  bool operator<=(C other) => false;
-}
-''');
-    checkElementText(library, r'''
-class C {
-  bool <=(C other) {}
-}
-''');
-  }
-
-  test_parameter() async {
-    var library = await checkLibrary('void main(int p) {}');
-    checkElementText(
-        library,
-        r'''
-void main@5(int p@14) {}
-''',
-        withOffsets: true);
-  }
-
-  test_parameter_checked() async {
-    // Note: due to dartbug.com/27393, the keyword "checked" is identified by
-    // its presence in a library called "meta".  If that bug is fixed, this test
-    // my need to be changed.
-    var library = await checkLibrary(r'''
-library meta;
-const checked = null;
-class A<T> {
-  void f(@checked T t) {}
-}
-''');
-    checkElementText(library, r'''
-library meta;
-class A<T> {
-  void f(@
-        checked/*location: test.dart;checked?*/ covariant T t) {}
-}
-const dynamic checked = null;
-''');
-  }
-
-  test_parameter_checked_inherited() async {
-    // Note: due to dartbug.com/27393, the keyword "checked" is identified by
-    // its presence in a library called "meta".  If that bug is fixed, this test
-    // my need to be changed.
-    var library = await checkLibrary(r'''
-library meta;
-const checked = null;
-class A<T> {
-  void f(@checked T t) {}
-}
-class B<T> extends A<T> {
-  void f(T t) {}
-}
-''');
-    if (isStrongMode) {
-      checkElementText(library, r'''
-library meta;
-class A<T> {
-  void f(@
-        checked/*location: test.dart;checked?*/ covariant T t) {}
-}
-class B<T> extends A<T> {
-  void f(covariant T t) {}
-}
-const dynamic checked = null;
-''');
-    } else {
-      checkElementText(library, r'''
-library meta;
-class A<T> {
-  void f(@
-        checked/*location: test.dart;checked?*/ covariant T t) {}
-}
-class B<T> extends A<T> {
-  void f(T t) {}
-}
-const dynamic checked = null;
-''');
-    }
-  }
-
-  test_parameter_covariant() async {
-    var library = await checkLibrary('class C { void m(covariant C c) {} }');
-    checkElementText(library, r'''
-class C {
-  void m(covariant C c) {}
-}
-''');
-  }
-
-  test_parameter_covariant_inherited() async {
-    var library = await checkLibrary(r'''
-class A<T> {
-  void f(covariant T t) {}
-}
-class B<T> extends A<T> {
-  void f(T t) {}
-}
-''');
-    if (isStrongMode) {
-      checkElementText(library, r'''
-class A<T> {
-  void f(covariant T t) {}
-}
-class B<T> extends A<T> {
-  void f(covariant T t) {}
-}
-''');
-    } else {
-      checkElementText(library, r'''
-class A<T> {
-  void f(covariant T t) {}
-}
-class B<T> extends A<T> {
-  void f(T t) {}
-}
-''');
-    }
-  }
-
-  test_parameter_parameters() async {
-    var library = await checkLibrary('class C { f(g(x, y)) {} }');
-    checkElementText(library, r'''
-class C {
-  dynamic f((dynamic, dynamic) → dynamic g) {}
-}
-''');
-  }
-
-  test_parameter_parameters_in_generic_class() async {
-    var library = await checkLibrary('class C<A, B> { f(A g(B x)) {} }');
-    checkElementText(library, r'''
-class C<A, B> {
-  dynamic f((B) → A g) {}
-}
-''');
-  }
-
-  test_parameter_return_type() async {
-    var library = await checkLibrary('class C { f(int g()) {} }');
-    checkElementText(library, r'''
-class C {
-  dynamic f(() → int g) {}
-}
-''');
-  }
-
-  test_parameter_return_type_void() async {
-    var library = await checkLibrary('class C { f(void g()) {} }');
-    checkElementText(library, r'''
-class C {
-  dynamic f(() → void g) {}
-}
-''');
-  }
-
-  test_parameterTypeNotInferred_constructor() async {
-    // Strong mode doesn't do type inference on constructor parameters, so it's
-    // ok that we don't store inferred type info for them in summaries.
-    var library = await checkLibrary('''
-class C {
-  C.positional([x = 1]);
-  C.named({x: 1});
-}
-''');
-    checkElementText(library, r'''
-class C {
-  C.positional([dynamic x = 1]);
-  C.named({dynamic x: 1});
-}
-''');
-  }
-
-  test_parameterTypeNotInferred_initializingFormal() async {
-    // Strong mode doesn't do type inference on initializing formals, so it's
-    // ok that we don't store inferred type info for them in summaries.
-    var library = await checkLibrary('''
-class C {
-  var x;
-  C.positional([this.x = 1]);
-  C.named({this.x: 1});
-}
-''');
-    checkElementText(library, r'''
-class C {
-  dynamic x;
-  C.positional([dynamic this.x = 1]);
-  C.named({dynamic this.x: 1});
-}
-''');
-  }
-
-  test_parameterTypeNotInferred_staticMethod() async {
-    // Strong mode doesn't do type inference on parameters of static methods,
-    // so it's ok that we don't store inferred type info for them in summaries.
-    var library = await checkLibrary('''
-class C {
-  static void positional([x = 1]) {}
-  static void named({x: 1}) {}
-}
-''');
-    checkElementText(library, r'''
-class C {
-  static void positional([dynamic x = 1]) {}
-  static void named({dynamic x: 1}) {}
-}
-''');
-  }
-
-  test_parameterTypeNotInferred_topLevelFunction() async {
-    // Strong mode doesn't do type inference on parameters of top level
-    // functions, so it's ok that we don't store inferred type info for them in
-    // summaries.
-    var library = await checkLibrary('''
-void positional([x = 1]) {}
-void named({x: 1}) {}
-''');
-    checkElementText(library, r'''
-void positional([dynamic x = 1]) {}
-void named({dynamic x: 1}) {}
-''');
-  }
-
-  test_parts() async {
-    addSource('/a.dart', 'part of my.lib;');
-    addSource('/b.dart', 'part of my.lib;');
-    var library =
-        await checkLibrary('library my.lib; part "a.dart"; part "b.dart";');
-    checkElementText(library, r'''
-library my.lib;
-part 'a.dart';
-part 'b.dart';
---------------------
-unit: a.dart
-
---------------------
-unit: b.dart
-
-''');
-  }
-
-  test_parts_invalidUri() async {
-    allowMissingFiles = true;
-    shouldCompareLibraryElements = false;
-    addSource('/foo/bar.dart', 'part of my.lib;');
-    var library = await checkLibrary('library my.lib; part "foo/";');
-    checkElementText(library, r'''
-library my.lib;
-part '<unresolved>';
---------------------
-unit: null
-
-''');
-  }
-
-  test_parts_invalidUri_nullStringValue() async {
-    allowMissingFiles = true;
-    shouldCompareLibraryElements = false;
-    addSource('/foo/bar.dart', 'part of my.lib;');
-    var library = await checkLibrary(r'''
-library my.lib;
-part "${foo}/bar.dart";
-''');
-    checkElementText(library, r'''
-library my.lib;
-part '<unresolved>';
---------------------
-unit: null
-
-''');
-  }
-
-  test_propagated_type_refers_to_closure() async {
-    var library = await checkLibrary('''
-void f() {
-  var x = () => 0;
-  var y = x;
-}
-''');
-    checkElementText(library, r'''
-void f() {}
-''');
-  }
-
-  test_setter_covariant() async {
-    var library =
-        await checkLibrary('class C { void set x(covariant int value); }');
-    checkElementText(library, r'''
-class C {
-  void set x(covariant int value);
-}
-''');
-  }
-
-  test_setter_documented() async {
-    var library = await checkLibrary('''
-// Extra comment so doc comment offset != 0
-/**
- * Docs
- */
-void set x(value) {}''');
-    checkElementText(library, r'''
-/**
- * Docs
- */
-void set x(dynamic value) {}
-''');
-  }
-
-  test_setter_external() async {
-    var library = await checkLibrary('external void set x(int value);');
-    checkElementText(library, r'''
-external void set x(int value);
-''');
-  }
-
-  test_setter_inferred_type_conflictingInheritance() async {
-    var library = await checkLibrary('''
-class A {
-  int t;
-}
-class B extends A {
-  double t;
-}
-class C extends A implements B {
-}
-class D extends C {
-  void set t(p) {}
-}
-''');
-    checkElementText(library, r'''
-class A {
-  int t;
-}
-class B extends A {
-  double t;
-}
-class C extends A implements B {
-}
-class D extends C {
-  void set t(dynamic p) {}
-}
-''');
-  }
-
-  test_setter_inferred_type_nonStatic_implicit_param() async {
-    var library =
-        await checkLibrary('class C extends D { void set f(value) {} }'
-            ' abstract class D { void set f(int value); }');
-    if (isStrongMode) {
-      checkElementText(library, r'''
-class C extends D {
-  void set f(int value) {}
-}
-abstract class D {
-  void set f(int value);
-}
-''');
-    } else {
-      checkElementText(library, r'''
-class C extends D {
-  void set f(dynamic value) {}
-}
-abstract class D {
-  void set f(int value);
-}
-''');
-    }
-  }
-
-  test_setter_inferred_type_static_implicit_return() async {
-    var library = await checkLibrary('''
-class C {
-  static set f(int value) {}
-}
-''');
-    if (isStrongMode) {
-      checkElementText(library, r'''
-class C {
-  static void set f(int value) {}
-}
-''');
-    } else {
-      checkElementText(library, r'''
-class C {
-  static dynamic set f(int value) {}
-}
-''');
-    }
-  }
-
-  test_setter_inferred_type_top_level_implicit_return() async {
-    var library = await checkLibrary('set f(int value) {}');
-    if (isStrongMode) {
-      checkElementText(library, r'''
-void set f(int value) {}
-''');
-    } else {
-      checkElementText(library, r'''
-dynamic set f(int value) {}
-''');
-    }
-  }
-
-  test_setters() async {
-    var library =
-        await checkLibrary('void set x(int value) {} set y(value) {}');
-    if (isStrongMode) {
-      checkElementText(library, r'''
-void set x(int value) {}
-void set y(dynamic value) {}
-''');
-    } else {
-      checkElementText(library, r'''
-void set x(int value) {}
-dynamic set y(dynamic value) {}
-''');
-    }
-  }
-
-  test_syntheticFunctionType_genericClosure() async {
-    if (!isStrongMode) {
-      return;
-    }
-    var library = await checkLibrary('''
-final v = f() ? <T>(T t) => 0 : <T>(T t) => 1;
-bool f() => true;
-''');
-    checkElementText(library, r'''
-final (<bottom>) → int v;
-bool f() {}
-''');
-  }
-
-  test_syntheticFunctionType_genericClosure_inGenericFunction() async {
-    if (!isStrongMode) {
-      return;
-    }
-    var library = await checkLibrary('''
-void f<T, U>(bool b) {
-  final v = b ? <V>(T t, U u, V v) => 0 : <V>(T t, U u, V v) => 1;
-}
-''');
-    checkElementText(library, r'''
-void f<T, U>(bool b) {}
-''');
-  }
-
-  test_syntheticFunctionType_inGenericClass() async {
-    var library = await checkLibrary('''
-class C<T, U> {
-  var v = f() ? (T t, U u) => 0 : (T t, U u) => 1;
-}
-bool f() => false;
-''');
-    if (isStrongMode) {
-      checkElementText(library, r'''
-class C<T, U> {
-  (T, U) → int v;
-}
-bool f() {}
-''');
-    } else {
-      checkElementText(library, r'''
-class C<T, U> {
-  dynamic v;
-}
-bool f() {}
-''');
-    }
-  }
-
-  test_syntheticFunctionType_inGenericFunction() async {
-    var library = await checkLibrary('''
-void f<T, U>(bool b) {
-  var v = b ? (T t, U u) => 0 : (T t, U u) => 1;
-}
-''');
-    checkElementText(library, r'''
-void f<T, U>(bool b) {}
-''');
-  }
-
-  test_syntheticFunctionType_noArguments() async {
-    var library = await checkLibrary('''
-final v = f() ? () => 0 : () => 1;
-bool f() => true;
-''');
-    if (isStrongMode) {
-      checkElementText(library, r'''
-final () → int v;
-bool f() {}
-''');
-    } else {
-      checkElementText(library, r'''
-final dynamic v;
-bool f() {}
-''');
-    }
-  }
-
-  test_syntheticFunctionType_withArguments() async {
-    var library = await checkLibrary('''
-final v = f() ? (int x, String y) => 0 : (int x, String y) => 1;
-bool f() => true;
-''');
-    if (isStrongMode) {
-      checkElementText(library, r'''
-final (int, String) → int v;
-bool f() {}
-''');
-    } else {
-      checkElementText(library, r'''
-final dynamic v;
-bool f() {}
-''');
-    }
-  }
-
-  test_type_arguments_explicit_dynamic_dynamic() async {
-    var library = await checkLibrary('Map<dynamic, dynamic> m;');
-    checkElementText(library, r'''
-Map<dynamic, dynamic> m;
-''');
-  }
-
-  test_type_arguments_explicit_dynamic_int() async {
-    var library = await checkLibrary('Map<dynamic, int> m;');
-    checkElementText(library, r'''
-Map<dynamic, int> m;
-''');
-  }
-
-  test_type_arguments_explicit_String_dynamic() async {
-    var library = await checkLibrary('Map<String, dynamic> m;');
-    checkElementText(library, r'''
-Map<String, dynamic> m;
-''');
-  }
-
-  test_type_arguments_explicit_String_int() async {
-    var library = await checkLibrary('Map<String, int> m;');
-    checkElementText(library, r'''
-Map<String, int> m;
-''');
-  }
-
-  test_type_arguments_implicit() async {
-    var library = await checkLibrary('Map m;');
-    checkElementText(library, r'''
-Map<dynamic, dynamic> m;
-''');
-  }
-
-  test_type_dynamic() async {
-    var library = await checkLibrary('dynamic d;');
-    checkElementText(library, r'''
-dynamic d;
-''');
-  }
-
-  test_type_inference_based_on_loadLibrary() async {
-    addLibrarySource('/a.dart', '');
-    var library = await checkLibrary('''
-import 'a.dart' deferred as a;
-var x = a.loadLibrary;
-''');
-    if (isStrongMode) {
-      checkElementText(library, '''
-import 'a.dart' deferred as a;
-() → Future<dynamic> x;
-''');
-    } else {
-      checkElementText(library, '''
-import 'a.dart' deferred as a;
-dynamic x;
-''');
-    }
-  }
-
-  test_type_inference_closure_with_function_typed_parameter() async {
-    var library = await checkLibrary('''
-var x = (int f(String x)) => 0;
-''');
-    if (isStrongMode) {
-      checkElementText(library, '''
-((String) → int) → int x;
-''');
-    } else {
-      checkElementText(library, '''
-dynamic x;
-''');
-    }
-  }
-
-  test_type_inference_closure_with_function_typed_parameter_new() async {
-    var library = await checkLibrary('''
-var x = (int Function(String) f) => 0;
-''');
-    if (isStrongMode) {
-      checkElementText(library, '''
-((String) → int) → int x;
-''');
-    } else {
-      checkElementText(library, '''
-dynamic x;
-''');
-    }
-  }
-
-  test_type_inference_depends_on_exported_variable() async {
-    addLibrarySource('/a.dart', 'export "b.dart";');
-    addLibrarySource('/b.dart', 'var x = 0;');
-    var library = await checkLibrary('''
-import 'a.dart';
-var y = x;
-''');
-    if (isStrongMode) {
-      checkElementText(library, '''
-import 'a.dart';
-int y;
-''');
-    } else {
-      checkElementText(library, '''
-import 'a.dart';
-dynamic y;
-''');
-    }
-  }
-
-  test_type_inference_nested_function() async {
-    var library = await checkLibrary('''
-var x = (t) => (u) => t + u;
-''');
-    if (isStrongMode) {
-      checkElementText(library, '''
-(dynamic) → (dynamic) → dynamic x;
-''');
-    } else {
-      checkElementText(library, '''
-dynamic x;
-''');
-    }
-  }
-
-  test_type_inference_nested_function_with_parameter_types() async {
-    var library = await checkLibrary('''
-var x = (int t) => (int u) => t + u;
-''');
-    if (isStrongMode) {
-      checkElementText(library, '''
-(int) → (int) → int x;
-''');
-    } else {
-      checkElementText(library, '''
-dynamic x;
-''');
-    }
-  }
-
-  test_type_inference_of_closure_with_default_value() async {
-    var library = await checkLibrary('''
-var x = ([y: 0]) => y;
-''');
-    if (isStrongMode) {
-      checkElementText(library, '''
-([dynamic]) → dynamic x;
-''');
-    } else {
-      checkElementText(library, '''
-dynamic x;
-''');
-    }
-  }
-
-  test_type_invalid_topLevelVariableElement_asType() async {
-    var library = await checkLibrary('''
-class C<T extends V> {}
-typedef V F(V p);
-V f(V p) {}
-V V2 = null;
-int V = 0;
-''', allowErrors: true);
-    checkElementText(library, r'''
-typedef F = dynamic Function(dynamic p);
-class C<T extends dynamic> {
-}
-dynamic V2;
-int V;
-dynamic f(dynamic p) {}
-''');
-  }
-
-  test_type_invalid_topLevelVariableElement_asTypeArgument() async {
-    var library = await checkLibrary('''
-var V;
-static List<V> V2;
-''', allowErrors: true);
-    checkElementText(library, r'''
-dynamic V;
-List<dynamic> V2;
-''');
-  }
-
-  test_type_invalid_typeParameter_asPrefix() async {
-    var library = await checkLibrary('''
-class C<T> {
-  m(T.K p) {}
-}
-''', allowErrors: true);
-    checkElementText(library, r'''
-class C<T> {
-  dynamic m(dynamic p) {}
-}
-''');
-  }
-
-  test_type_reference_lib_to_lib() async {
-    var library = await checkLibrary('''
-class C {}
-enum E { v }
-typedef F();
-C c;
-E e;
-F f;''');
-    checkElementText(library, r'''
-typedef F = dynamic Function();
-enum E {
-  synthetic final int index;
-  synthetic static const List<E> values;
-  static const E v;
-  String toString() {}
-}
-class C {
-}
-C c;
-E e;
-() → dynamic f;
-''');
-  }
-
-  test_type_reference_lib_to_part() async {
-    addSource('/a.dart', 'part of l; class C {} enum E { v } typedef F();');
-    var library =
-        await checkLibrary('library l; part "a.dart"; C c; E e; F f;');
-    checkElementText(library, r'''
-library l;
-part 'a.dart';
-C c;
-E e;
-() → dynamic f;
---------------------
-unit: a.dart
-
-typedef F = dynamic Function();
-enum E {
-  synthetic final int index;
-  synthetic static const List<E> values;
-  static const E v;
-  String toString() {}
-}
-class C {
-}
-''');
-  }
-
-  test_type_reference_part_to_lib() async {
-    addSource('/a.dart', 'part of l; C c; E e; F f;');
-    var library = await checkLibrary(
-        'library l; part "a.dart"; class C {} enum E { v } typedef F();');
-    checkElementText(library, r'''
-library l;
-part 'a.dart';
-typedef F = dynamic Function();
-enum E {
-  synthetic final int index;
-  synthetic static const List<E> values;
-  static const E v;
-  String toString() {}
-}
-class C {
-}
---------------------
-unit: a.dart
-
-C c;
-E e;
-() → dynamic f;
-''');
-  }
-
-  test_type_reference_part_to_other_part() async {
-    addSource('/a.dart', 'part of l; class C {} enum E { v } typedef F();');
-    addSource('/b.dart', 'part of l; C c; E e; F f;');
-    var library =
-        await checkLibrary('library l; part "a.dart"; part "b.dart";');
-    checkElementText(library, r'''
-library l;
-part 'a.dart';
-part 'b.dart';
---------------------
-unit: a.dart
-
-typedef F = dynamic Function();
-enum E {
-  synthetic final int index;
-  synthetic static const List<E> values;
-  static const E v;
-  String toString() {}
-}
-class C {
-}
---------------------
-unit: b.dart
-
-C c;
-E e;
-() → dynamic f;
-''');
-  }
-
-  test_type_reference_part_to_part() async {
-    addSource('/a.dart',
-        'part of l; class C {} enum E { v } typedef F(); C c; E e; F f;');
-    var library = await checkLibrary('library l; part "a.dart";');
-    checkElementText(library, r'''
-library l;
-part 'a.dart';
---------------------
-unit: a.dart
-
-typedef F = dynamic Function();
-enum E {
-  synthetic final int index;
-  synthetic static const List<E> values;
-  static const E v;
-  String toString() {}
-}
-class C {
-}
-C c;
-E e;
-() → dynamic f;
-''');
-  }
-
-  test_type_reference_to_class() async {
-    var library = await checkLibrary('class C {} C c;');
-    checkElementText(library, r'''
-class C {
-}
-C c;
-''');
-  }
-
-  test_type_reference_to_class_with_type_arguments() async {
-    var library = await checkLibrary('class C<T, U> {} C<int, String> c;');
-    checkElementText(library, r'''
-class C<T, U> {
-}
-C<int, String> c;
-''');
-  }
-
-  test_type_reference_to_class_with_type_arguments_implicit() async {
-    var library = await checkLibrary('class C<T, U> {} C c;');
-    checkElementText(library, r'''
-class C<T, U> {
-}
-C<dynamic, dynamic> c;
-''');
-  }
-
-  test_type_reference_to_enum() async {
-    var library = await checkLibrary('enum E { v } E e;');
-    checkElementText(library, r'''
-enum E {
-  synthetic final int index;
-  synthetic static const List<E> values;
-  static const E v;
-  String toString() {}
-}
-E e;
-''');
-  }
-
-  test_type_reference_to_import() async {
-    addLibrarySource('/a.dart', 'class C {} enum E { v } typedef F();');
-    var library = await checkLibrary('import "a.dart"; C c; E e; F f;');
-    checkElementText(library, r'''
-import 'a.dart';
-C c;
-E e;
-() → dynamic f;
-''');
-  }
-
-  test_type_reference_to_import_export() async {
-    addLibrarySource('/a.dart', 'export "b.dart";');
-    addLibrarySource('/b.dart', 'class C {} enum E { v } typedef F();');
-    var library = await checkLibrary('import "a.dart"; C c; E e; F f;');
-    checkElementText(library, r'''
-import 'a.dart';
-C c;
-E e;
-() → dynamic f;
-''');
-  }
-
-  test_type_reference_to_import_export_export() async {
-    addLibrarySource('/a.dart', 'export "b.dart";');
-    addLibrarySource('/b.dart', 'export "c.dart";');
-    addLibrarySource('/c.dart', 'class C {} enum E { v } typedef F();');
-    var library = await checkLibrary('import "a.dart"; C c; E e; F f;');
-    checkElementText(library, r'''
-import 'a.dart';
-C c;
-E e;
-() → dynamic f;
-''');
-  }
-
-  test_type_reference_to_import_export_export_in_subdirs() async {
-    addLibrarySource('/a/a.dart', 'export "b/b.dart";');
-    addLibrarySource('/a/b/b.dart', 'export "../c/c.dart";');
-    addLibrarySource('/a/c/c.dart', 'class C {} enum E { v } typedef F();');
-    var library = await checkLibrary('import "a/a.dart"; C c; E e; F f;');
-    checkElementText(library, r'''
-import 'a.dart';
-C c;
-E e;
-() → dynamic f;
-''');
-  }
-
-  test_type_reference_to_import_export_in_subdirs() async {
-    addLibrarySource('/a/a.dart', 'export "b/b.dart";');
-    addLibrarySource('/a/b/b.dart', 'class C {} enum E { v } typedef F();');
-    var library = await checkLibrary('import "a/a.dart"; C c; E e; F f;');
-    checkElementText(library, r'''
-import 'a.dart';
-C c;
-E e;
-() → dynamic f;
-''');
-  }
-
-  test_type_reference_to_import_part() async {
-    addLibrarySource('/a.dart', 'library l; part "b.dart";');
-    addSource('/b.dart', 'part of l; class C {} enum E { v } typedef F();');
-    var library = await checkLibrary('import "a.dart"; C c; E e; F f;');
-    checkElementText(library, r'''
-import 'a.dart';
-C c;
-E e;
-() → dynamic f;
-''');
-  }
-
-  test_type_reference_to_import_part2() async {
-    addLibrarySource('/a.dart', 'library l; part "p1.dart"; part "p2.dart";');
-    addSource('/p1.dart', 'part of l; class C1 {}');
-    addSource('/p2.dart', 'part of l; class C2 {}');
-    var library = await checkLibrary('import "a.dart"; C1 c1; C2 c2;');
-    checkElementText(library, r'''
-import 'a.dart';
-C1 c1;
-C2 c2;
-''');
-  }
-
-  test_type_reference_to_import_part_in_subdir() async {
-    addLibrarySource('/a/b.dart', 'library l; part "c.dart";');
-    addSource('/a/c.dart', 'part of l; class C {} enum E { v } typedef F();');
-    var library = await checkLibrary('import "a/b.dart"; C c; E e; F f;');
-    checkElementText(library, r'''
-import 'b.dart';
-C c;
-E e;
-() → dynamic f;
-''');
-  }
-
-  test_type_reference_to_import_relative() async {
-    addLibrarySource('/a.dart', 'class C {} enum E { v } typedef F();');
-    var library = await checkLibrary('import "a.dart"; C c; E e; F f;');
-    checkElementText(library, r'''
-import 'a.dart';
-C c;
-E e;
-() → dynamic f;
-''');
-  }
-
-  test_type_reference_to_typedef() async {
-    var library = await checkLibrary('typedef F(); F f;');
-    checkElementText(library, r'''
-typedef F = dynamic Function();
-() → dynamic f;
-''');
-  }
-
-  test_type_reference_to_typedef_with_type_arguments() async {
-    var library =
-        await checkLibrary('typedef U F<T, U>(T t); F<int, String> f;');
-    checkElementText(library, r'''
-typedef F<T, U> = U Function(T t);
-(int) → String f;
-''');
-  }
-
-  test_type_reference_to_typedef_with_type_arguments_implicit() async {
-    var library = await checkLibrary('typedef U F<T, U>(T t); F f;');
-    checkElementText(library, r'''
-typedef F<T, U> = U Function(T t);
-(dynamic) → dynamic f;
-''');
-  }
-
-  test_type_unresolved() async {
-    var library = await checkLibrary('C c;', allowErrors: true);
-    checkElementText(library, r'''
-dynamic c;
-''');
-  }
-
-  test_type_unresolved_prefixed() async {
-    var library = await checkLibrary('import "dart:core" as core; core.C c;',
-        allowErrors: true);
-    checkElementText(library, r'''
-import 'dart:core' as core;
-dynamic c;
-''');
-  }
-
-  test_typedef_documented() async {
-    var library = await checkLibrary('''
-// Extra comment so doc comment offset != 0
-/**
- * Docs
- */
-typedef F();''');
-    checkElementText(library, r'''
-/**
- * Docs
- */
-typedef F = dynamic Function();
-''');
-  }
-
-  test_typedef_generic() async {
-    var library = await checkLibrary(
-        'typedef F<T> = int Function<S>(List<S> list, num Function<A>(A), T);');
-    checkElementText(library, r'''
-typedef F<T> = int Function<S>(List<S> list, <A>(A) → num , T );
-''');
-  }
-
-  test_typedef_generic_asFieldType() async {
-    shouldCompareLibraryElements = false;
-    var library = await checkLibrary(r'''
-typedef Foo<S> = S Function<T>(T x);
-class A {
-  Foo<int> f;
-}
-''');
-    checkElementText(library, r'''
-typedef Foo<S> = S Function<T>(T x);
-class A {
-  <T>(T) → int f;
-}
-''');
-  }
-
-  test_typedef_parameter_parameters() async {
-    var library = await checkLibrary('typedef F(g(x, y));');
-    checkElementText(library, r'''
-typedef F = dynamic Function((dynamic, dynamic) → dynamic g);
-''');
-  }
-
-  test_typedef_parameter_parameters_in_generic_class() async {
-    var library = await checkLibrary('typedef F<A, B>(A g(B x));');
-    checkElementText(library, r'''
-typedef F<A, B> = dynamic Function((B) → A g);
-''');
-  }
-
-  test_typedef_parameter_return_type() async {
-    var library = await checkLibrary('typedef F(int g());');
-    checkElementText(library, r'''
-typedef F = dynamic Function(() → int g);
-''');
-  }
-
-  test_typedef_parameter_type() async {
-    var library = await checkLibrary('typedef F(int i);');
-    checkElementText(library, r'''
-typedef F = dynamic Function(int i);
-''');
-  }
-
-  test_typedef_parameter_type_generic() async {
-    var library = await checkLibrary('typedef F<T>(T t);');
-    checkElementText(library, r'''
-typedef F<T> = dynamic Function(T t);
-''');
-  }
-
-  test_typedef_parameters() async {
-    var library = await checkLibrary('typedef F(x, y);');
-    checkElementText(library, r'''
-typedef F = dynamic Function(dynamic x, dynamic y);
-''');
-  }
-
-  test_typedef_parameters_named() async {
-    var library = await checkLibrary('typedef F({y, z, x});');
-    if (isSharedFrontEnd) {
-      checkElementText(library, r'''
-typedef F = dynamic Function({dynamic x}, {dynamic y}, {dynamic z});
-''');
-    } else {
-      checkElementText(library, r'''
-typedef F = dynamic Function({dynamic y}, {dynamic z}, {dynamic x});
-''');
-    }
-  }
-
-  test_typedef_return_type() async {
-    var library = await checkLibrary('typedef int F();');
-    checkElementText(library, r'''
-typedef F = int Function();
-''');
-  }
-
-  test_typedef_return_type_generic() async {
-    var library = await checkLibrary('typedef T F<T>();');
-    checkElementText(library, r'''
-typedef F<T> = T Function();
-''');
-  }
-
-  test_typedef_return_type_implicit() async {
-    var library = await checkLibrary('typedef F();');
-    checkElementText(library, r'''
-typedef F = dynamic Function();
-''');
-  }
-
-  test_typedef_return_type_void() async {
-    var library = await checkLibrary('typedef void F();');
-    checkElementText(library, r'''
-typedef F = void Function();
-''');
-  }
-
-  test_typedef_type_parameters() async {
-    var library = await checkLibrary('typedef U F<T, U>(T t);');
-    checkElementText(library, r'''
-typedef F<T, U> = U Function(T t);
-''');
-  }
-
-  test_typedef_type_parameters_bound() async {
-    var library = await checkLibrary(
-        'typedef U F<T extends Object, U extends D>(T t); class D {}');
-    checkElementText(library, r'''
-typedef F<T, U extends D> = U Function(T t);
-class D {
-}
-''');
-  }
-
-  test_typedef_type_parameters_bound_recursive() async {
-    shouldCompareLibraryElements = false;
-    var library = await checkLibrary('typedef void F<T extends F>();');
-    // Typedefs cannot reference themselves.
-    checkElementText(library, r'''
-typedef F<T extends () → void> = void Function();
-''');
-  }
-
-  test_typedef_type_parameters_bound_recursive2() async {
-    shouldCompareLibraryElements = false;
-    var library = await checkLibrary('typedef void F<T extends List<F>>();');
-    // Typedefs cannot reference themselves.
-    checkElementText(library, r'''
-typedef F<T extends List<() → void>> = void Function();
-''');
-  }
-
-  test_typedef_type_parameters_f_bound_complex() async {
-    var library = await checkLibrary('typedef U F<T extends List<U>, U>(T t);');
-    checkElementText(library, r'''
-typedef F<T extends List<U>, U> = U Function(T t);
-''');
-  }
-
-  test_typedef_type_parameters_f_bound_simple() async {
-    var library = await checkLibrary('typedef U F<T extends U, U>(T t);');
-    checkElementText(library, r'''
-typedef F<T extends U, U> = U Function(T t);
-''');
-  }
-
-  test_typedefs() async {
-    var library = await checkLibrary('f() {} g() {}');
-    checkElementText(library, r'''
-dynamic f() {}
-dynamic g() {}
-''');
-  }
-
-  @failingTest
-  test_unresolved_annotation_instanceCreation_argument_super() async {
-    // TODO(scheglov) fix https://github.com/dart-lang/sdk/issues/28553
-    var library = await checkLibrary('''
-class A {
-  const A(_);
-}
-
-@A(super)
-class C {}
-''', allowErrors: true);
-    checkElementText(library, r'''
-class A {
-  A(_);
-}
-
-class C {
-  synthetic C();
-}
-''');
-  }
-
-  test_unresolved_annotation_instanceCreation_argument_this() async {
-    shouldCompareLibraryElements = false;
-    var library = await checkLibrary('''
-class A {
-  const A(_);
-}
-
-@A(this)
-class C {}
-''', allowErrors: true);
-    checkElementText(library, r'''
-class A {
-  const A(dynamic _);
-}
-@#invalidConst
-class C {
-}
-''');
-  }
-
-  test_unresolved_annotation_namedConstructorCall_noClass() async {
-    shouldCompareLibraryElements = false;
-    var library =
-        await checkLibrary('@foo.bar() class C {}', allowErrors: true);
-    checkElementText(library, r'''
-@#invalidConst
-class C {
-}
-''');
-  }
-
-  test_unresolved_annotation_namedConstructorCall_noConstructor() async {
-    shouldCompareLibraryElements = false;
-    var library =
-        await checkLibrary('@String.foo() class C {}', allowErrors: true);
-    checkElementText(library, r'''
-@#invalidConst
-class C {
-}
-''');
-  }
-
-  test_unresolved_annotation_prefixedIdentifier_badPrefix() async {
-    shouldCompareLibraryElements = false;
-    var library = await checkLibrary('@foo.bar class C {}', allowErrors: true);
-    checkElementText(library, r'''
-@#invalidConst
-class C {
-}
-''');
-  }
-
-  test_unresolved_annotation_prefixedIdentifier_noDeclaration() async {
-    shouldCompareLibraryElements = false;
-    var library = await checkLibrary(
-        'import "dart:async" as foo; @foo.bar class C {}',
-        allowErrors: true);
-    checkElementText(library, r'''
-import 'dart:async' as foo;
-@#invalidConst
-class C {
-}
-''');
-  }
-
-  test_unresolved_annotation_prefixedNamedConstructorCall_badPrefix() async {
-    shouldCompareLibraryElements = false;
-    var library =
-        await checkLibrary('@foo.bar.baz() class C {}', allowErrors: true);
-    checkElementText(library, r'''
-@#invalidConst
-class C {
-}
-''');
-  }
-
-  test_unresolved_annotation_prefixedNamedConstructorCall_noClass() async {
-    shouldCompareLibraryElements = false;
-    var library = await checkLibrary(
-        'import "dart:async" as foo; @foo.bar.baz() class C {}',
-        allowErrors: true);
-    checkElementText(library, r'''
-import 'dart:async' as foo;
-@#invalidConst
-class C {
-}
-''');
-  }
-
-  test_unresolved_annotation_prefixedNamedConstructorCall_noConstructor() async {
-    shouldCompareLibraryElements = false;
-    var library = await checkLibrary(
-        'import "dart:async" as foo; @foo.Future.bar() class C {}',
-        allowErrors: true);
-    checkElementText(library, r'''
-import 'dart:async' as foo;
-@#invalidConst
-class C {
-}
-''');
-  }
-
-  test_unresolved_annotation_prefixedUnnamedConstructorCall_badPrefix() async {
-    shouldCompareLibraryElements = false;
-    var library =
-        await checkLibrary('@foo.bar() class C {}', allowErrors: true);
-    checkElementText(library, r'''
-@#invalidConst
-class C {
-}
-''');
-  }
-
-  test_unresolved_annotation_prefixedUnnamedConstructorCall_noClass() async {
-    shouldCompareLibraryElements = false;
-    var library = await checkLibrary(
-        'import "dart:async" as foo; @foo.bar() class C {}',
-        allowErrors: true);
-    checkElementText(library, r'''
-import 'dart:async' as foo;
-@#invalidConst
-class C {
-}
-''');
-  }
-
-  test_unresolved_annotation_simpleIdentifier() async {
-    shouldCompareLibraryElements = false;
-    var library = await checkLibrary('@foo class C {}', allowErrors: true);
-    checkElementText(library, r'''
-@#invalidConst
-class C {
-}
-''');
-  }
-
-  test_unresolved_annotation_unnamedConstructorCall_noClass() async {
-    shouldCompareLibraryElements = false;
-    var library = await checkLibrary('@foo() class C {}', allowErrors: true);
-    checkElementText(library, r'''
-@#invalidConst
-class C {
-}
-''');
-  }
-
-  test_unresolved_export() async {
-    allowMissingFiles = true;
-    var library = await checkLibrary("export 'foo.dart';", allowErrors: true);
-    checkElementText(library, r'''
-export 'foo.dart';
-''');
-  }
-
-  test_unresolved_import() async {
-    allowMissingFiles = true;
-    var library = await checkLibrary("import 'foo.dart';", allowErrors: true);
-    LibraryElement importedLibrary = library.imports[0].importedLibrary;
-    expect(importedLibrary.loadLibraryFunction, isNotNull);
-    expect(importedLibrary.publicNamespace, isNotNull);
-    expect(importedLibrary.exportNamespace, isNotNull);
-    checkElementText(library, r'''
-import 'foo.dart';
-''');
-  }
-
-  test_unresolved_part() async {
-    allowMissingFiles = true;
-    var library = await checkLibrary("part 'foo.dart';", allowErrors: true);
-    checkElementText(library, r'''
-part 'foo.dart';
---------------------
-unit: foo.dart
-
-''');
-  }
-
-  test_unused_type_parameter() async {
-    shouldCompareLibraryElements = false;
-    var library = await checkLibrary('''
-class C<T> {
-  void f() {}
-}
-C<int> c;
-var v = c.f;
-''');
-    if (isStrongMode) {
-      checkElementText(library, r'''
-class C<T> {
-  void f() {}
-}
-C<int> c;
-() → void v;
-''');
-    } else {
-      checkElementText(library, r'''
-class C<T> {
-  void f() {}
-}
-C<int> c;
-dynamic v;
-''');
-    }
-  }
-
-  test_variable() async {
-    var library = await checkLibrary('int x = 0;');
-    checkElementText(
-        library,
-        r'''
-int x@4;
-synthetic int get x@4 {}
-synthetic void set x@4(int _x@4) {}
-''',
-        withOffsets: true,
-        withSyntheticAccessors: true);
-  }
-
-  test_variable_const() async {
-    var library = await checkLibrary('const int i = 0;');
-    checkElementText(library, r'''
-const int i = 0;
-''');
-  }
-
-  test_variable_documented() async {
-    var library = await checkLibrary('''
-// Extra comment so doc comment offset != 0
-/**
- * Docs
- */
-var x;''');
-    checkElementText(library, r'''
-/**
- * Docs
- */
-dynamic x;
-''');
-  }
-
-  test_variable_final() async {
-    var library = await checkLibrary('final int x = 0;');
-    checkElementText(library, r'''
-final int x;
-''');
-  }
-
-  test_variable_final_top_level_untyped() async {
-    var library = await checkLibrary('final v = 0;');
-    if (isStrongMode) {
-      checkElementText(library, r'''
-final int v;
-''');
-    } else {
-      checkElementText(library, r'''
-final dynamic v;
-''');
-    }
-  }
-
-  test_variable_getterInLib_setterInPart() async {
-    addSource('/a.dart', '''
-part of my.lib;
-void set x(int _) {}
-''');
-    var library = await checkLibrary('''
-library my.lib;
-part 'a.dart';
-int get x => 42;''');
-    checkElementText(library, r'''
-library my.lib;
-part 'a.dart';
-int get x {}
---------------------
-unit: a.dart
-
-void set x(int _) {}
-''');
-  }
-
-  test_variable_getterInPart_setterInLib() async {
-    addSource('/a.dart', '''
-part of my.lib;
-int get x => 42;
-''');
-    var library = await checkLibrary('''
-library my.lib;
-part 'a.dart';
-void set x(int _) {}
-''');
-    checkElementText(library, r'''
-library my.lib;
-part 'a.dart';
-void set x(int _) {}
---------------------
-unit: a.dart
-
-int get x {}
-''');
-  }
-
-  test_variable_getterInPart_setterInPart() async {
-    addSource('/a.dart', 'part of my.lib; int get x => 42;');
-    addSource('/b.dart', 'part of my.lib; void set x(int _) {}');
-    var library =
-        await checkLibrary('library my.lib; part "a.dart"; part "b.dart";');
-    checkElementText(library, r'''
-library my.lib;
-part 'a.dart';
-part 'b.dart';
---------------------
-unit: a.dart
-
-int get x {}
---------------------
-unit: b.dart
-
-void set x(int _) {}
-''');
-  }
-
-  test_variable_implicit_type() async {
-    var library = await checkLibrary('var x;');
-    checkElementText(library, r'''
-dynamic x;
-''');
-  }
-
-  test_variable_inferred_type_implicit_initialized() async {
-    var library = await checkLibrary('var v = 0;');
-    if (isStrongMode) {
-      checkElementText(library, r'''
-int v;
-''');
-    } else {
-      checkElementText(library, r'''
-dynamic v;
-''');
-    }
-  }
-
-  test_variable_propagatedType_const_noDep() async {
-    var library = await checkLibrary('const i = 0;');
-    if (isStrongMode) {
-      checkElementText(library, r'''
-const int i = 0;
-''');
-    } else {
-      checkElementText(library, r'''
-const dynamic i = 0;
-''');
-    }
-  }
-
-  test_variable_propagatedType_final_dep_inLib() async {
-    addLibrarySource('/a.dart', 'final a = 1;');
-    var library = await checkLibrary('import "a.dart"; final b = a / 2;');
-    if (isStrongMode) {
-      checkElementText(library, r'''
-import 'a.dart';
-final double b;
-''');
-    } else {
-      checkElementText(library, r'''
-import 'a.dart';
-final dynamic b;
-''');
-    }
-  }
-
-  test_variable_propagatedType_final_dep_inPart() async {
-    addSource('/a.dart', 'part of lib; final a = 1;');
-    var library =
-        await checkLibrary('library lib; part "a.dart"; final b = a / 2;');
-    if (isStrongMode) {
-      checkElementText(library, r'''
-library lib;
-part 'a.dart';
-final double b;
---------------------
-unit: a.dart
-
-final int a;
-''');
-    } else {
-      checkElementText(library, r'''
-library lib;
-part 'a.dart';
-final dynamic b;
---------------------
-unit: a.dart
-
-final dynamic a;
-''');
-    }
-  }
-
-  test_variable_propagatedType_final_noDep() async {
-    var library = await checkLibrary('final i = 0;');
-    if (isStrongMode) {
-      checkElementText(library, r'''
-final int i;
-''');
-    } else {
-      checkElementText(library, r'''
-final dynamic i;
-''');
-    }
-  }
-
-  test_variable_propagatedType_implicit_dep() async {
-    // The propagated type is defined in a library that is not imported.
-    addLibrarySource('/a.dart', 'class C {}');
-    addLibrarySource('/b.dart', 'import "a.dart"; C f() => null;');
-    var library = await checkLibrary('import "b.dart"; final x = f();');
-    if (isStrongMode) {
-      checkElementText(library, r'''
-import 'b.dart';
-final C x;
-''');
-    } else {
-      checkElementText(library, r'''
-import 'b.dart';
-final dynamic x;
-''');
-    }
-  }
-
-  test_variable_setterInPart_getterInPart() async {
-    addSource('/a.dart', 'part of my.lib; void set x(int _) {}');
-    addSource('/b.dart', 'part of my.lib; int get x => 42;');
-    var library =
-        await checkLibrary('library my.lib; part "a.dart"; part "b.dart";');
-    checkElementText(library, r'''
-library my.lib;
-part 'a.dart';
-part 'b.dart';
---------------------
-unit: a.dart
-
-void set x(int _) {}
---------------------
-unit: b.dart
-
-int get x {}
-''');
-  }
-
-  test_variables() async {
-    var library = await checkLibrary('int i; int j;');
-    checkElementText(library, r'''
-int i;
-int j;
-''');
-  }
-}
-
 class TestSummaryResynthesizer extends SummaryResynthesizer {
   final Map<String, UnlinkedUnit> unlinkedSummaries;
   final Map<String, LinkedLibrary> linkedSummaries;
diff --git a/pkg/analyzer/test/src/summary/summarize_ast_one_phase_test.dart b/pkg/analyzer/test/src/summary/summarize_ast_one_phase_test.dart
index 10863d3..7aa8ea8 100644
--- a/pkg/analyzer/test/src/summary/summarize_ast_one_phase_test.dart
+++ b/pkg/analyzer/test/src/summary/summarize_ast_one_phase_test.dart
@@ -18,8 +18,8 @@
     with SummaryTestCases {
   @override
   @failingTest
-  test_bottom_reference_shared() {
-    super.test_bottom_reference_shared();
+  test_closure_executable_with_bottom_return_type() {
+    super.test_closure_executable_with_bottom_return_type();
   }
 
   @override
@@ -42,30 +42,6 @@
 
   @override
   @failingTest
-  test_implicit_dependencies_follow_other_dependencies() {
-    super.test_implicit_dependencies_follow_other_dependencies();
-  }
-
-  @override
-  @failingTest
-  test_inferred_type_refers_to_function_typed_param_of_typedef() {
-    super.test_inferred_type_refers_to_function_typed_param_of_typedef();
-  }
-
-  @override
-  @failingTest
-  test_inferred_type_refers_to_nested_function_typed_param() {
-    super.test_inferred_type_refers_to_nested_function_typed_param();
-  }
-
-  @override
-  @failingTest
-  test_inferred_type_refers_to_nested_function_typed_param_named() {
-    super.test_inferred_type_refers_to_nested_function_typed_param_named();
-  }
-
-  @override
-  @failingTest
   test_initializer_executable_with_bottom_return_type() {
     super.test_initializer_executable_with_bottom_return_type();
   }
diff --git a/pkg/analyzer/test/src/summary/summarize_ast_strong_test.dart b/pkg/analyzer/test/src/summary/summarize_ast_strong_test.dart
index 6c2d84c..b83b616 100644
--- a/pkg/analyzer/test/src/summary/summarize_ast_strong_test.dart
+++ b/pkg/analyzer/test/src/summary/summarize_ast_strong_test.dart
@@ -18,12 +18,6 @@
     with SummaryTestCases {
   @override
   @failingTest
-  test_bottom_reference_shared() {
-    super.test_bottom_reference_shared();
-  }
-
-  @override
-  @failingTest
   test_closure_executable_with_imported_return_type() {
     super.test_closure_executable_with_imported_return_type();
   }
@@ -42,30 +36,6 @@
 
   @override
   @failingTest
-  test_implicit_dependencies_follow_other_dependencies() {
-    super.test_implicit_dependencies_follow_other_dependencies();
-  }
-
-  @override
-  @failingTest
-  test_inferred_type_refers_to_function_typed_param_of_typedef() {
-    super.test_inferred_type_refers_to_function_typed_param_of_typedef();
-  }
-
-  @override
-  @failingTest
-  test_inferred_type_refers_to_nested_function_typed_param() {
-    super.test_inferred_type_refers_to_nested_function_typed_param();
-  }
-
-  @override
-  @failingTest
-  test_inferred_type_refers_to_nested_function_typed_param_named() {
-    super.test_inferred_type_refers_to_nested_function_typed_param_named();
-  }
-
-  @override
-  @failingTest
   test_initializer_executable_with_bottom_return_type() {
     super.test_initializer_executable_with_bottom_return_type();
   }
diff --git a/pkg/analyzer/test/src/summary/summary_common.dart b/pkg/analyzer/test/src/summary/summary_common.dart
index 22eb0d3..daac93b 100644
--- a/pkg/analyzer/test/src/summary/summary_common.dart
+++ b/pkg/analyzer/test/src/summary/summary_common.dart
@@ -97,7 +97,12 @@
       List<double> doubles: const <double>[],
       List<String> strings: const <String>[],
       List<_EntityRefValidator> referenceValidators:
-          const <_EntityRefValidator>[]}) {
+          const <_EntityRefValidator>[],
+      bool forTypeInferenceOnly: false}) {
+    if (forTypeInferenceOnly && !containsNonConstExprs) {
+      expect(constExpr, isNull);
+      return;
+    }
     expect(constExpr, isNotNull);
     expect(constExpr.isValidConst, isValidConst);
     expect(constExpr.operations, operators);
@@ -925,11 +930,13 @@
     }
     // The synthetic executables for both `x` and `y` have type `() => `Bottom`.
     // Verify that they both use the same reference to `Bottom`.
-    serializeLibraryText('int x = null; int y = null;');
+    serializeLibraryText('var x = throw null; var y = throw null;');
     EntityRef xInitializerReturnType =
         getTypeRefForSlot(findVariable('x').initializer.inferredReturnTypeSlot);
     EntityRef yInitializerReturnType =
         getTypeRefForSlot(findVariable('y').initializer.inferredReturnTypeSlot);
+    checkLinkedTypeRef(xInitializerReturnType, null, '*bottom*');
+    checkLinkedTypeRef(yInitializerReturnType, null, '*bottom*');
     expect(xInitializerReturnType.reference, yInitializerReturnType.reference);
   }
 
@@ -1803,7 +1810,7 @@
   test_constExpr_functionExpression() {
     UnlinkedVariable variable = serializeVariableText('''
 import 'dart:async';
-const v = (f) async => await f;
+var v = (f) async => await f;
 ''');
     assertUnlinkedConst(variable.initializer.localFunctions[0].bodyExpr,
         isValidConst: false,
@@ -1811,10 +1818,9 @@
           UnlinkedExprOperation.pushParameter,
           UnlinkedExprOperation.await
         ],
-        strings: [
-          'f'
-        ],
-        ints: []);
+        strings: ['f'],
+        ints: [],
+        forTypeInferenceOnly: true);
   }
 
   test_constExpr_functionExpression_asArgument() {
@@ -2553,65 +2559,71 @@
   test_constExpr_makeTypedList_functionType() {
     UnlinkedVariable variable =
         serializeVariableText('final v = <void Function(int)>[];');
-    assertUnlinkedConst(variable.initializer.bodyExpr, operators: [
-      UnlinkedExprOperation.makeTypedList
-    ], ints: [
-      0 // Size of the list
-    ], referenceValidators: [
-      (EntityRef reference) {
-        expect(reference, new TypeMatcher<EntityRef>());
-        expect(reference.entityKind, EntityRefKind.genericFunctionType);
-        expect(reference.syntheticParams, hasLength(1));
-        {
-          final param = reference.syntheticParams[0];
-          expect(param.name, ''); // no name for generic type parameters
-          checkTypeRef(param.type, 'dart:core', 'int',
-              expectedKind: ReferenceKind.classOrEnum);
-        }
-        expect(reference.paramReference, 0);
-        expect(reference.typeParameters, hasLength(0));
-        // TODO(mfairhurst) check this references void
-        expect(reference.syntheticReturnType, isNotNull);
-      }
-    ]);
+    assertUnlinkedConst(variable.initializer.bodyExpr,
+        operators: [UnlinkedExprOperation.makeTypedList],
+        ints: [
+          0 // Size of the list
+        ],
+        referenceValidators: [
+          (EntityRef reference) {
+            expect(reference, new TypeMatcher<EntityRef>());
+            expect(reference.entityKind, EntityRefKind.genericFunctionType);
+            expect(reference.syntheticParams, hasLength(1));
+            {
+              final param = reference.syntheticParams[0];
+              expect(param.name, ''); // no name for generic type parameters
+              checkTypeRef(param.type, 'dart:core', 'int',
+                  expectedKind: ReferenceKind.classOrEnum);
+            }
+            expect(reference.paramReference, 0);
+            expect(reference.typeParameters, hasLength(0));
+            // TODO(mfairhurst) check this references void
+            expect(reference.syntheticReturnType, isNotNull);
+          }
+        ],
+        forTypeInferenceOnly: true);
   }
 
   test_constExpr_makeTypedList_functionType_withTypeParameters() {
     UnlinkedVariable variable = serializeVariableText(
         'final v = <void Function<T>(Function<Q>(T, Q))>[];');
-    assertUnlinkedConst(variable.initializer.bodyExpr, operators: [
-      UnlinkedExprOperation.makeTypedList
-    ], ints: [
-      0 // Size of the list
-    ], referenceValidators: [
-      (EntityRef reference) {
-        expect(reference, new TypeMatcher<EntityRef>());
-        expect(reference.entityKind, EntityRefKind.genericFunctionType);
-        expect(reference.syntheticParams, hasLength(1));
-        {
-          final param = reference.syntheticParams[0];
-          expect(param.type, new TypeMatcher<EntityRef>());
-          expect(param.type.entityKind, EntityRefKind.genericFunctionType);
-          expect(param.type.syntheticParams, hasLength(2));
-          {
-            final subparam = param.type.syntheticParams[0];
-            expect(subparam.name, ''); // no name for generic type parameters
-            expect(subparam.type, new TypeMatcher<EntityRef>());
-            expect(subparam.type.paramReference, 2);
+    assertUnlinkedConst(variable.initializer.bodyExpr,
+        operators: [UnlinkedExprOperation.makeTypedList],
+        ints: [
+          0 // Size of the list
+        ],
+        referenceValidators: [
+          (EntityRef reference) {
+            expect(reference, new TypeMatcher<EntityRef>());
+            expect(reference.entityKind, EntityRefKind.genericFunctionType);
+            expect(reference.syntheticParams, hasLength(1));
+            {
+              final param = reference.syntheticParams[0];
+              expect(param.type, new TypeMatcher<EntityRef>());
+              expect(param.type.entityKind, EntityRefKind.genericFunctionType);
+              expect(param.type.syntheticParams, hasLength(2));
+              {
+                final subparam = param.type.syntheticParams[0];
+                expect(
+                    subparam.name, ''); // no name for generic type parameters
+                expect(subparam.type, new TypeMatcher<EntityRef>());
+                expect(subparam.type.paramReference, 2);
+              }
+              {
+                final subparam = param.type.syntheticParams[1];
+                expect(
+                    subparam.name, ''); // no name for generic type parameters
+                expect(subparam.type, new TypeMatcher<EntityRef>());
+                expect(subparam.type.paramReference, 1);
+              }
+            }
+            expect(reference.paramReference, 0);
+            expect(reference.typeParameters, hasLength(1));
+            // TODO(mfairhurst) check this references void
+            expect(reference.syntheticReturnType, isNotNull);
           }
-          {
-            final subparam = param.type.syntheticParams[1];
-            expect(subparam.name, ''); // no name for generic type parameters
-            expect(subparam.type, new TypeMatcher<EntityRef>());
-            expect(subparam.type.paramReference, 1);
-          }
-        }
-        expect(reference.paramReference, 0);
-        expect(reference.typeParameters, hasLength(1));
-        // TODO(mfairhurst) check this references void
-        expect(reference.syntheticReturnType, isNotNull);
-      }
-    ]);
+        ],
+        forTypeInferenceOnly: true);
   }
 
   test_constExpr_makeTypedMap() {
@@ -6101,13 +6113,8 @@
           UnlinkedExprOperation.pushInt,
           UnlinkedExprOperation.assignToIndex,
         ],
-        assignmentOperators: [
-          (UnlinkedExprAssignOperator.assign)
-        ],
-        ints: [
-          5,
-          1
-        ],
+        assignmentOperators: [(UnlinkedExprAssignOperator.assign)],
+        ints: [5, 1],
         strings: [],
         referenceValidators: [
           (EntityRef r) => checkTypeRef(r, null, 'f',
@@ -6118,7 +6125,8 @@
                     new _PrefixExpectation(
                         ReferenceKind.topLevelPropertyAccessor, 'a')
                   ])
-        ]);
+        ],
+        forTypeInferenceOnly: true);
   }
 
   test_expr_assignToIndex_ofIndexExpression() {
@@ -6153,19 +6161,14 @@
           UnlinkedExprOperation.pushInt,
           UnlinkedExprOperation.assignToIndex,
         ],
-        assignmentOperators: [
-          (UnlinkedExprAssignOperator.assign)
-        ],
+        assignmentOperators: [(UnlinkedExprAssignOperator.assign)],
         ints: [
           5,
           1,
           2,
           3,
         ],
-        strings: [
-          'c',
-          'f'
-        ],
+        strings: ['c', 'f'],
         referenceValidators: [
           (EntityRef r) => checkTypeRef(r, null, 'b',
                   expectedKind: ReferenceKind.unresolved,
@@ -6173,7 +6176,8 @@
                     new _PrefixExpectation(
                         ReferenceKind.topLevelPropertyAccessor, 'a')
                   ])
-        ]);
+        ],
+        forTypeInferenceOnly: true);
   }
 
   test_expr_assignToIndex_ofTopLevelVariable() {
@@ -6189,9 +6193,7 @@
           UnlinkedExprOperation.pushInt,
           UnlinkedExprOperation.assignToIndex,
         ],
-        assignmentOperators: [
-          (UnlinkedExprAssignOperator.assign)
-        ],
+        assignmentOperators: [(UnlinkedExprAssignOperator.assign)],
         ints: [
           5,
           1,
@@ -6200,7 +6202,8 @@
         referenceValidators: [
           (EntityRef r) => checkTypeRef(r, null, 'a',
               expectedKind: ReferenceKind.topLevelPropertyAccessor)
-        ]);
+        ],
+        forTypeInferenceOnly: true);
   }
 
   test_expr_assignToProperty_ofInstanceCreation() {
@@ -6217,21 +6220,18 @@
           UnlinkedExprOperation.invokeConstructor,
           UnlinkedExprOperation.assignToProperty,
         ],
-        assignmentOperators: [
-          (UnlinkedExprAssignOperator.assign)
-        ],
+        assignmentOperators: [(UnlinkedExprAssignOperator.assign)],
         ints: [
           5,
           0,
           0,
         ],
-        strings: [
-          'f'
-        ],
+        strings: ['f'],
         referenceValidators: [
           (EntityRef r) => checkTypeRef(r, null, 'C',
               expectedKind: ReferenceKind.classOrEnum)
-        ]);
+        ],
+        forTypeInferenceOnly: true);
   }
 
   test_expr_assignToRef_classStaticField() {
@@ -6247,9 +6247,7 @@
           UnlinkedExprOperation.pushInt,
           UnlinkedExprOperation.assignToRef,
         ],
-        assignmentOperators: [
-          (UnlinkedExprAssignOperator.assign)
-        ],
+        assignmentOperators: [(UnlinkedExprAssignOperator.assign)],
         ints: [
           1,
         ],
@@ -6260,7 +6258,8 @@
                   prefixExpectations: [
                     new _PrefixExpectation(ReferenceKind.classOrEnum, 'C')
                   ])
-        ]);
+        ],
+        forTypeInferenceOnly: true);
   }
 
   test_expr_assignToRef_fieldSequence() {
@@ -6283,9 +6282,7 @@
           UnlinkedExprOperation.pushInt,
           UnlinkedExprOperation.assignToRef,
         ],
-        assignmentOperators: [
-          (UnlinkedExprAssignOperator.assign)
-        ],
+        assignmentOperators: [(UnlinkedExprAssignOperator.assign)],
         ints: [
           1,
         ],
@@ -6299,7 +6296,8 @@
                     new _PrefixExpectation(
                         ReferenceKind.topLevelPropertyAccessor, 'a')
                   ])
-        ]);
+        ],
+        forTypeInferenceOnly: true);
   }
 
   test_expr_assignToRef_postfixDecrement() {
@@ -6333,9 +6331,7 @@
           UnlinkedExprOperation.pushInt,
           UnlinkedExprOperation.assignToRef,
         ],
-        assignmentOperators: [
-          (UnlinkedExprAssignOperator.assign)
-        ],
+        assignmentOperators: [(UnlinkedExprAssignOperator.assign)],
         ints: [
           1,
         ],
@@ -6343,7 +6339,8 @@
         referenceValidators: [
           (EntityRef r) => checkTypeRef(r, null, 'a',
               expectedKind: ReferenceKind.topLevelPropertyAccessor)
-        ]);
+        ],
+        forTypeInferenceOnly: true);
   }
 
   test_expr_assignToRef_topLevelVariable_imported() {
@@ -6360,9 +6357,7 @@
           UnlinkedExprOperation.pushInt,
           UnlinkedExprOperation.assignToRef,
         ],
-        assignmentOperators: [
-          (UnlinkedExprAssignOperator.assign)
-        ],
+        assignmentOperators: [(UnlinkedExprAssignOperator.assign)],
         ints: [
           1,
         ],
@@ -6370,7 +6365,8 @@
         referenceValidators: [
           (EntityRef r) => checkTypeRef(r, absUri('/a.dart'), 'a',
               expectedKind: ReferenceKind.topLevelPropertyAccessor)
-        ]);
+        ],
+        forTypeInferenceOnly: true);
   }
 
   test_expr_assignToRef_topLevelVariable_imported_withPrefix() {
@@ -6387,9 +6383,7 @@
           UnlinkedExprOperation.pushInt,
           UnlinkedExprOperation.assignToRef,
         ],
-        assignmentOperators: [
-          (UnlinkedExprAssignOperator.assign)
-        ],
+        assignmentOperators: [(UnlinkedExprAssignOperator.assign)],
         ints: [
           1,
         ],
@@ -6400,7 +6394,8 @@
                 expectedKind: ReferenceKind.topLevelPropertyAccessor,
                 expectedPrefix: 'p');
           }
-        ]);
+        ],
+        forTypeInferenceOnly: true);
   }
 
   test_expr_cascadeSection_assignToIndex() {
@@ -6426,7 +6421,8 @@
                     new _PrefixExpectation(
                         ReferenceKind.topLevelPropertyAccessor, 'c'),
                   ])
-        ]);
+        ],
+        forTypeInferenceOnly: true);
   }
 
   test_expr_cascadeSection_assignToProperty() {
@@ -6443,15 +6439,13 @@
           UnlinkedExprOperation.invokeConstructor,
         ],
         assignmentOperators: [],
-        ints: [
-          0,
-          0
-        ],
+        ints: [0, 0],
         strings: [],
         referenceValidators: [
           (EntityRef r) => checkTypeRef(r, null, 'C',
               expectedKind: ReferenceKind.classOrEnum)
-        ]);
+        ],
+        forTypeInferenceOnly: true);
   }
 
   test_expr_cascadeSection_embedded() {
@@ -6483,7 +6477,8 @@
         referenceValidators: [
           (EntityRef r) => checkTypeRef(r, null, 'A',
               expectedKind: ReferenceKind.classOrEnum),
-        ]);
+        ],
+        forTypeInferenceOnly: true);
   }
 
   test_expr_cascadeSection_invokeMethod() {
@@ -6504,7 +6499,8 @@
         referenceValidators: [
           (EntityRef r) => checkTypeRef(r, null, 'a',
               expectedKind: ReferenceKind.topLevelPropertyAccessor),
-        ]);
+        ],
+        forTypeInferenceOnly: true);
   }
 
   test_expr_extractIndex_ofClassField() {
@@ -6522,18 +6518,13 @@
           UnlinkedExprOperation.pushInt,
           UnlinkedExprOperation.extractIndex,
         ],
-        ints: [
-          0,
-          0,
-          5
-        ],
-        strings: [
-          'items'
-        ],
+        ints: [0, 0, 5],
+        strings: ['items'],
         referenceValidators: [
           (EntityRef r) => checkTypeRef(r, null, 'C',
               expectedKind: ReferenceKind.classOrEnum)
-        ]);
+        ],
+        forTypeInferenceOnly: true);
   }
 
   test_expr_extractProperty_ofInvokeConstructor() {
@@ -6549,17 +6540,13 @@
           UnlinkedExprOperation.invokeConstructor,
           UnlinkedExprOperation.extractProperty,
         ],
-        ints: [
-          0,
-          0
-        ],
-        strings: [
-          'f'
-        ],
+        ints: [0, 0],
+        strings: ['f'],
         referenceValidators: [
           (EntityRef r) => checkTypeRef(r, null, 'C',
               expectedKind: ReferenceKind.classOrEnum)
-        ]);
+        ],
+        forTypeInferenceOnly: true);
   }
 
   test_expr_functionExpression_asArgument() {
@@ -6574,18 +6561,12 @@
           UnlinkedExprOperation.pushLocalFunctionReference,
           UnlinkedExprOperation.invokeMethodRef
         ],
-        ints: [
-          5,
-          0,
-          0,
-          0,
-          2,
-          0
-        ],
+        ints: [5, 0, 0, 0, 2, 0],
         referenceValidators: [
           (EntityRef r) => checkTypeRef(r, null, 'foo',
               expectedKind: ReferenceKind.topLevelFunction)
-        ]);
+        ],
+        forTypeInferenceOnly: true);
   }
 
   test_expr_functionExpression_asArgument_multiple() {
@@ -6601,20 +6582,12 @@
           UnlinkedExprOperation.pushLocalFunctionReference,
           UnlinkedExprOperation.invokeMethodRef
         ],
-        ints: [
-          5,
-          0,
-          0,
-          0,
-          1,
-          0,
-          3,
-          0
-        ],
+        ints: [5, 0, 0, 0, 1, 0, 3, 0],
         referenceValidators: [
           (EntityRef r) => checkTypeRef(r, null, 'foo',
               expectedKind: ReferenceKind.topLevelFunction)
-        ]);
+        ],
+        forTypeInferenceOnly: true);
   }
 
   test_expr_functionExpression_withBlockBody() {
@@ -6624,7 +6597,8 @@
     assertUnlinkedConst(variable.initializer.bodyExpr,
         isValidConst: false,
         operators: [UnlinkedExprOperation.pushLocalFunctionReference],
-        ints: [0, 0]);
+        ints: [0, 0],
+        forTypeInferenceOnly: true);
   }
 
   test_expr_functionExpression_withExpressionBody() {
@@ -6634,7 +6608,8 @@
     assertUnlinkedConst(variable.initializer.bodyExpr,
         isValidConst: false,
         operators: [UnlinkedExprOperation.pushLocalFunctionReference],
-        ints: [0, 0]);
+        ints: [0, 0],
+        forTypeInferenceOnly: true);
   }
 
   test_expr_functionExpressionInvocation_withBlockBody() {
@@ -6642,7 +6617,9 @@
 final v = ((a, b) {return 42;})(1, 2);
 ''');
     assertUnlinkedConst(variable.initializer.bodyExpr,
-        isValidConst: false, operators: [UnlinkedExprOperation.pushNull]);
+        isValidConst: false,
+        operators: [UnlinkedExprOperation.pushNull],
+        forTypeInferenceOnly: true);
   }
 
   test_expr_functionExpressionInvocation_withExpressionBody() {
@@ -6650,13 +6627,17 @@
 final v = ((a, b) => 42)(1, 2);
 ''');
     assertUnlinkedConst(variable.initializer.bodyExpr,
-        isValidConst: false, operators: [UnlinkedExprOperation.pushNull]);
+        isValidConst: false,
+        operators: [UnlinkedExprOperation.pushNull],
+        forTypeInferenceOnly: true);
   }
 
   test_expr_inClosure() {
     UnlinkedVariable variable = serializeVariableText('var v = () => 1;');
     assertUnlinkedConst(variable.initializer.localFunctions[0].bodyExpr,
-        operators: [UnlinkedExprOperation.pushInt], ints: [1]);
+        operators: [UnlinkedExprOperation.pushInt],
+        ints: [1],
+        forTypeInferenceOnly: true);
   }
 
   test_expr_inClosure_noTypeInferenceNeeded() {
@@ -6672,13 +6653,16 @@
     assertUnlinkedConst(
         variable.initializer.localFunctions[0].localFunctions[0].bodyExpr,
         operators: [UnlinkedExprOperation.pushParameter],
-        strings: ['x']);
+        strings: ['x'],
+        forTypeInferenceOnly: true);
   }
 
   test_expr_inClosure_refersToParam() {
     UnlinkedVariable variable = serializeVariableText('var v = (x) => x;');
     assertUnlinkedConst(variable.initializer.localFunctions[0].bodyExpr,
-        operators: [UnlinkedExprOperation.pushParameter], strings: ['x']);
+        operators: [UnlinkedExprOperation.pushParameter],
+        strings: ['x'],
+        forTypeInferenceOnly: true);
   }
 
   test_expr_inClosure_refersToParam_methodCall() {
@@ -6688,15 +6672,9 @@
           UnlinkedExprOperation.pushParameter,
           UnlinkedExprOperation.invokeMethod
         ],
-        strings: [
-          'x',
-          'f'
-        ],
-        ints: [
-          0,
-          0,
-          0
-        ]);
+        strings: ['x', 'f'],
+        ints: [0, 0, 0],
+        forTypeInferenceOnly: true);
   }
 
   test_expr_inClosure_refersToParam_methodCall_prefixed() {
@@ -6708,16 +6686,9 @@
           UnlinkedExprOperation.extractProperty,
           UnlinkedExprOperation.invokeMethod
         ],
-        strings: [
-          'x',
-          'y',
-          'f'
-        ],
-        ints: [
-          0,
-          0,
-          0
-        ]);
+        strings: ['x', 'y', 'f'],
+        ints: [0, 0, 0],
+        forTypeInferenceOnly: true);
   }
 
   test_expr_inClosure_refersToParam_outOfScope() {
@@ -6731,17 +6702,13 @@
           UnlinkedExprOperation.pushReference,
           UnlinkedExprOperation.conditional,
         ],
-        strings: [
-          'b'
-        ],
-        ints: [
-          0,
-          0
-        ],
+        strings: ['b'],
+        ints: [0, 0],
         referenceValidators: [
           (EntityRef r) => checkTypeRef(r, null, 'x',
               expectedKind: ReferenceKind.topLevelPropertyAccessor)
-        ]);
+        ],
+        forTypeInferenceOnly: true);
   }
 
   test_expr_inClosure_refersToParam_prefixedIdentifier() {
@@ -6751,10 +6718,8 @@
           UnlinkedExprOperation.pushParameter,
           UnlinkedExprOperation.extractProperty
         ],
-        strings: [
-          'x',
-          'y'
-        ]);
+        strings: ['x', 'y'],
+        forTypeInferenceOnly: true);
   }
 
   test_expr_inClosure_refersToParam_prefixedIdentifier_assign() {
@@ -6767,13 +6732,9 @@
           UnlinkedExprOperation.pushParameter,
           UnlinkedExprOperation.assignToProperty
         ],
-        strings: [
-          'x',
-          'y'
-        ],
-        assignmentOperators: [
-          UnlinkedExprAssignOperator.assign
-        ]);
+        strings: ['x', 'y'],
+        assignmentOperators: [UnlinkedExprAssignOperator.assign],
+        forTypeInferenceOnly: true);
   }
 
   test_expr_inClosure_refersToParam_prefixedPrefixedIdentifier() {
@@ -6784,11 +6745,8 @@
           UnlinkedExprOperation.extractProperty,
           UnlinkedExprOperation.extractProperty
         ],
-        strings: [
-          'x',
-          'y',
-          'z'
-        ]);
+        strings: ['x', 'y', 'z'],
+        forTypeInferenceOnly: true);
   }
 
   test_expr_inClosure_refersToParam_prefixedPrefixedIdentifier_assign() {
@@ -6802,14 +6760,9 @@
           UnlinkedExprOperation.extractProperty,
           UnlinkedExprOperation.assignToProperty
         ],
-        strings: [
-          'x',
-          'y',
-          'z'
-        ],
-        assignmentOperators: [
-          UnlinkedExprAssignOperator.assign
-        ]);
+        strings: ['x', 'y', 'z'],
+        assignmentOperators: [UnlinkedExprAssignOperator.assign],
+        forTypeInferenceOnly: true);
   }
 
   test_expr_invalid_typeParameter_asPrefix() {
@@ -6838,25 +6791,13 @@
           UnlinkedExprOperation.pushInt,
           UnlinkedExprOperation.invokeMethod,
         ],
-        ints: [
-          0,
-          0,
-          1,
-          2,
-          3,
-          2,
-          1,
-          0
-        ],
-        strings: [
-          'b',
-          'c',
-          'm'
-        ],
+        ints: [0, 0, 1, 2, 3, 2, 1, 0],
+        strings: ['b', 'c', 'm'],
         referenceValidators: [
           (EntityRef r) => checkTypeRef(r, null, 'C',
               expectedKind: ReferenceKind.classOrEnum)
-        ]);
+        ],
+        forTypeInferenceOnly: true);
   }
 
   test_expr_invokeMethod_withTypeParameters() {
@@ -6872,21 +6813,14 @@
           UnlinkedExprOperation.invokeConstructor,
           UnlinkedExprOperation.invokeMethod
         ],
-        ints: [
-          0,
-          0,
-          0,
-          0,
-          2
-        ],
-        strings: [
-          'f'
-        ],
+        ints: [0, 0, 0, 0, 2],
+        strings: ['f'],
         referenceValidators: [
           (EntityRef r) => checkTypeRef(r, null, 'C'),
           (EntityRef r) => checkTypeRef(r, 'dart:core', 'int'),
           (EntityRef r) => checkTypeRef(r, 'dart:core', 'String')
-        ]);
+        ],
+        forTypeInferenceOnly: true);
   }
 
   test_expr_invokeMethodRef_instance() {
@@ -6903,26 +6837,25 @@
 A a = new A();
 final v = a.b.c.m(10, 20);
 ''');
-    assertUnlinkedConst(variable.initializer.bodyExpr, operators: [
-      UnlinkedExprOperation.pushInt,
-      UnlinkedExprOperation.pushInt,
-      UnlinkedExprOperation.invokeMethodRef,
-    ], ints: [
-      10,
-      20,
-      0,
-      2,
-      0
-    ], strings: [], referenceValidators: [
-      (EntityRef r) => checkTypeRef(r, null, 'm',
-              expectedKind: ReferenceKind.unresolved,
-              prefixExpectations: [
-                new _PrefixExpectation(ReferenceKind.unresolved, 'c'),
-                new _PrefixExpectation(ReferenceKind.unresolved, 'b'),
-                new _PrefixExpectation(
-                    ReferenceKind.topLevelPropertyAccessor, 'a')
-              ])
-    ]);
+    assertUnlinkedConst(variable.initializer.bodyExpr,
+        operators: [
+          UnlinkedExprOperation.pushInt,
+          UnlinkedExprOperation.pushInt,
+          UnlinkedExprOperation.invokeMethodRef,
+        ],
+        ints: [10, 20, 0, 2, 0],
+        strings: [],
+        referenceValidators: [
+          (EntityRef r) => checkTypeRef(r, null, 'm',
+                  expectedKind: ReferenceKind.unresolved,
+                  prefixExpectations: [
+                    new _PrefixExpectation(ReferenceKind.unresolved, 'c'),
+                    new _PrefixExpectation(ReferenceKind.unresolved, 'b'),
+                    new _PrefixExpectation(
+                        ReferenceKind.topLevelPropertyAccessor, 'a')
+                  ])
+        ],
+        forTypeInferenceOnly: true);
   }
 
   test_expr_invokeMethodRef_static_importedWithPrefix() {
@@ -6935,21 +6868,22 @@
 import 'a.dart' as p;
 final v = p.C.m();
 ''');
-    assertUnlinkedConst(variable.initializer.bodyExpr, operators: [
-      UnlinkedExprOperation.invokeMethodRef,
-    ], ints: [
-      0,
-      0,
-      0
-    ], strings: [], referenceValidators: [
-      (EntityRef r) => checkTypeRef(r, null, 'm',
-              expectedKind: ReferenceKind.method,
-              prefixExpectations: [
-                new _PrefixExpectation(ReferenceKind.classOrEnum, 'C',
-                    absoluteUri: absUri('/a.dart')),
-                new _PrefixExpectation(ReferenceKind.prefix, 'p')
-              ])
-    ]);
+    assertUnlinkedConst(variable.initializer.bodyExpr,
+        operators: [
+          UnlinkedExprOperation.invokeMethodRef,
+        ],
+        ints: [0, 0, 0],
+        strings: [],
+        referenceValidators: [
+          (EntityRef r) => checkTypeRef(r, null, 'm',
+                  expectedKind: ReferenceKind.method,
+                  prefixExpectations: [
+                    new _PrefixExpectation(ReferenceKind.classOrEnum, 'C',
+                        absoluteUri: absUri('/a.dart')),
+                    new _PrefixExpectation(ReferenceKind.prefix, 'p')
+                  ])
+        ],
+        forTypeInferenceOnly: true);
   }
 
   test_expr_invokeMethodRef_with_reference_arg() {
@@ -6958,19 +6892,19 @@
 final u = null;
 final v = f(u);
 ''');
-    assertUnlinkedConst(variable.initializer.bodyExpr, operators: [
-      UnlinkedExprOperation.pushReference,
-      UnlinkedExprOperation.invokeMethodRef
-    ], ints: [
-      0,
-      1,
-      0
-    ], referenceValidators: [
-      (EntityRef r) => checkTypeRef(r, null, 'u',
-          expectedKind: ReferenceKind.topLevelPropertyAccessor),
-      (EntityRef r) => checkTypeRef(r, null, 'f',
-          expectedKind: ReferenceKind.topLevelFunction)
-    ]);
+    assertUnlinkedConst(variable.initializer.bodyExpr,
+        operators: [
+          UnlinkedExprOperation.pushReference,
+          UnlinkedExprOperation.invokeMethodRef
+        ],
+        ints: [0, 1, 0],
+        referenceValidators: [
+          (EntityRef r) => checkTypeRef(r, null, 'u',
+              expectedKind: ReferenceKind.topLevelPropertyAccessor),
+          (EntityRef r) => checkTypeRef(r, null, 'f',
+              expectedKind: ReferenceKind.topLevelFunction)
+        ],
+        forTypeInferenceOnly: true);
   }
 
   test_expr_invokeMethodRef_withTypeParameters() {
@@ -6978,102 +6912,98 @@
 f<T, U>() => null;
 final v = f<int, String>();
 ''');
-    assertUnlinkedConst(variable.initializer.bodyExpr, operators: [
-      UnlinkedExprOperation.invokeMethodRef
-    ], ints: [
-      0,
-      0,
-      2
-    ], referenceValidators: [
-      (EntityRef r) => checkTypeRef(r, null, 'f',
-          expectedKind: ReferenceKind.topLevelFunction, numTypeParameters: 2),
-      (EntityRef r) => checkTypeRef(r, 'dart:core', 'int'),
-      (EntityRef r) => checkTypeRef(r, 'dart:core', 'String')
-    ]);
+    assertUnlinkedConst(variable.initializer.bodyExpr,
+        operators: [UnlinkedExprOperation.invokeMethodRef],
+        ints: [0, 0, 2],
+        referenceValidators: [
+          (EntityRef r) => checkTypeRef(r, null, 'f',
+              expectedKind: ReferenceKind.topLevelFunction,
+              numTypeParameters: 2),
+          (EntityRef r) => checkTypeRef(r, 'dart:core', 'int'),
+          (EntityRef r) => checkTypeRef(r, 'dart:core', 'String')
+        ],
+        forTypeInferenceOnly: true);
   }
 
   test_expr_makeTypedList() {
     UnlinkedVariable variable =
         serializeVariableText('var v = <int>[11, 22, 33];');
-    assertUnlinkedConst(variable.initializer.bodyExpr, operators: [
-      UnlinkedExprOperation.makeTypedList
-    ], ints: [
-      0
-    ], referenceValidators: [
-      (EntityRef r) => checkTypeRef(r, 'dart:core', 'int',
-          expectedKind: ReferenceKind.classOrEnum)
-    ]);
+    assertUnlinkedConst(variable.initializer.bodyExpr,
+        operators: [UnlinkedExprOperation.makeTypedList],
+        ints: [0],
+        referenceValidators: [
+          (EntityRef r) => checkTypeRef(r, 'dart:core', 'int',
+              expectedKind: ReferenceKind.classOrEnum)
+        ],
+        forTypeInferenceOnly: true);
   }
 
   test_expr_makeTypedMap() {
     UnlinkedVariable variable = serializeVariableText(
         'var v = <int, String>{11: "aaa", 22: "bbb", 33: "ccc"};');
-    assertUnlinkedConst(variable.initializer.bodyExpr, operators: [
-      UnlinkedExprOperation.makeTypedMap
-    ], ints: [
-      0
-    ], referenceValidators: [
-      (EntityRef r) => checkTypeRef(r, 'dart:core', 'int',
-          expectedKind: ReferenceKind.classOrEnum),
-      (EntityRef r) => checkTypeRef(r, 'dart:core', 'String',
-          expectedKind: ReferenceKind.classOrEnum)
-    ]);
+    assertUnlinkedConst(variable.initializer.bodyExpr,
+        operators: [UnlinkedExprOperation.makeTypedMap],
+        ints: [0],
+        referenceValidators: [
+          (EntityRef r) => checkTypeRef(r, 'dart:core', 'int',
+              expectedKind: ReferenceKind.classOrEnum),
+          (EntityRef r) => checkTypeRef(r, 'dart:core', 'String',
+              expectedKind: ReferenceKind.classOrEnum)
+        ],
+        forTypeInferenceOnly: true);
   }
 
   test_expr_makeUntypedList() {
     UnlinkedVariable variable = serializeVariableText('var v = [11, 22, 33];');
-    assertUnlinkedConst(variable.initializer.bodyExpr, operators: [
-      UnlinkedExprOperation.pushInt,
-      UnlinkedExprOperation.pushInt,
-      UnlinkedExprOperation.pushInt,
-      UnlinkedExprOperation.makeUntypedList
-    ], ints: [
-      11,
-      22,
-      33,
-      3
-    ]);
+    assertUnlinkedConst(variable.initializer.bodyExpr,
+        operators: [
+          UnlinkedExprOperation.pushInt,
+          UnlinkedExprOperation.pushInt,
+          UnlinkedExprOperation.pushInt,
+          UnlinkedExprOperation.makeUntypedList
+        ],
+        ints: [11, 22, 33, 3],
+        forTypeInferenceOnly: true);
   }
 
   test_expr_makeUntypedMap() {
     UnlinkedVariable variable =
         serializeVariableText('var v = {11: "aaa", 22: "bbb", 33: "ccc"};');
-    assertUnlinkedConst(variable.initializer.bodyExpr, operators: [
-      UnlinkedExprOperation.pushInt,
-      UnlinkedExprOperation.pushString,
-      UnlinkedExprOperation.pushInt,
-      UnlinkedExprOperation.pushString,
-      UnlinkedExprOperation.pushInt,
-      UnlinkedExprOperation.pushString,
-      UnlinkedExprOperation.makeUntypedMap
-    ], ints: [
-      11,
-      22,
-      33,
-      3
-    ], strings: [
-      'aaa',
-      'bbb',
-      'ccc'
-    ]);
+    assertUnlinkedConst(variable.initializer.bodyExpr,
+        operators: [
+          UnlinkedExprOperation.pushInt,
+          UnlinkedExprOperation.pushString,
+          UnlinkedExprOperation.pushInt,
+          UnlinkedExprOperation.pushString,
+          UnlinkedExprOperation.pushInt,
+          UnlinkedExprOperation.pushString,
+          UnlinkedExprOperation.makeUntypedMap
+        ],
+        ints: [11, 22, 33, 3],
+        strings: ['aaa', 'bbb', 'ccc'],
+        forTypeInferenceOnly: true);
   }
 
   test_expr_super() {
     UnlinkedVariable variable = serializeVariableText('''
 final v = super;
 ''');
-    assertUnlinkedConst(variable.initializer.bodyExpr, operators: [
-      UnlinkedExprOperation.pushSuper,
-    ]);
+    assertUnlinkedConst(variable.initializer.bodyExpr,
+        operators: [
+          UnlinkedExprOperation.pushSuper,
+        ],
+        forTypeInferenceOnly: true);
   }
 
   test_expr_this() {
     UnlinkedVariable variable = serializeVariableText('''
 final v = this;
 ''');
-    assertUnlinkedConst(variable.initializer.bodyExpr, operators: [
-      UnlinkedExprOperation.pushThis,
-    ]);
+    assertUnlinkedConst(variable.initializer.bodyExpr,
+        operators: [
+          UnlinkedExprOperation.pushThis,
+        ],
+        forTypeInferenceOnly: true);
   }
 
   test_expr_throwException() {
@@ -7088,10 +7018,8 @@
           UnlinkedExprOperation.add,
           UnlinkedExprOperation.throwException,
         ],
-        ints: [
-          1,
-          2
-        ]);
+        ints: [1, 2],
+        forTypeInferenceOnly: true);
   }
 
   test_expr_typeCast() {
@@ -7104,13 +7032,12 @@
           UnlinkedExprOperation.pushInt,
           UnlinkedExprOperation.typeCast,
         ],
-        ints: [
-          42
-        ],
+        ints: [42],
         referenceValidators: [
           (EntityRef r) => checkTypeRef(r, 'dart:core', 'num',
               expectedKind: ReferenceKind.classOrEnum)
-        ]);
+        ],
+        forTypeInferenceOnly: true);
   }
 
   test_expr_typeCheck() {
@@ -7123,13 +7050,12 @@
           UnlinkedExprOperation.pushInt,
           UnlinkedExprOperation.typeCheck,
         ],
-        ints: [
-          42
-        ],
+        ints: [42],
         referenceValidators: [
           (EntityRef r) => checkTypeRef(r, 'dart:core', 'num',
               expectedKind: ReferenceKind.classOrEnum)
-        ]);
+        ],
+        forTypeInferenceOnly: true);
   }
 
   test_field() {
@@ -7317,14 +7243,22 @@
   test_field_static_final_untyped() {
     UnlinkedVariable variable =
         serializeClassText('class C { static final x = 0; }').fields[0];
-    expect(variable.initializer.bodyExpr, isNotNull);
+    if (containsNonConstExprs) {
+      expect(variable.initializer.bodyExpr, isNotNull);
+    } else {
+      expect(variable.initializer.bodyExpr, isNull);
+    }
     expect(variable.inheritsCovariantSlot, 0);
   }
 
   test_field_untyped() {
     UnlinkedVariable variable =
         serializeClassText('class C { var x = 0; }').fields[0];
-    expect(variable.initializer.bodyExpr, isNotNull);
+    if (containsNonConstExprs) {
+      expect(variable.initializer.bodyExpr, isNotNull);
+    } else {
+      expect(variable.initializer.bodyExpr, isNull);
+    }
     expect(variable.inheritsCovariantSlot, isNot(0));
   }
 
@@ -7426,8 +7360,8 @@
     // The dependency on b.dart is implicit, so it should be placed at the end
     // of the dependency list, after a.dart, even though the code that refers
     // to b.dart comes before the code that refers to a.dart.
-    int aDep = checkHasDependency('a.dart', fullyLinked: false);
-    int bDep = checkHasDependency('b.dart', fullyLinked: true);
+    int aDep = checkHasDependency(absUri('/a.dart'), fullyLinked: false);
+    int bDep = checkHasDependency(absUri('/b.dart'), fullyLinked: true);
     expect(aDep, lessThan(bDep));
   }
 
@@ -7808,15 +7742,10 @@
     }
     UnlinkedVariable v = serializeVariableText('''
 typedef void F(int g(String s));
-h(F f) => null;
-var v = h((y) {});
+F h() => null;
+var v = h();
 ''');
-    expect(v.initializer.localFunctions, hasLength(1));
-    UnlinkedExecutable closure = v.initializer.localFunctions[0];
-    expect(closure.parameters, hasLength(1));
-    UnlinkedParam y = closure.parameters[0];
-    expect(y.name, 'y');
-    EntityRef typeRef = getTypeRefForSlot(y.inferredTypeSlot);
+    EntityRef typeRef = getTypeRefForSlot(v.inferredTypeSlot);
     checkLinkedTypeRef(typeRef, null, 'F', expectedKind: ReferenceKind.typedef);
     expect(typeRef.implicitFunctionTypeIndices, isEmpty);
   }
@@ -7893,15 +7822,11 @@
       return;
     }
     UnlinkedVariable v = serializeVariableText('''
-f(void g(int x, void h())) => null;
-var v = f((x, y) {});
+dynamic f(void g(int x, void h())) => null;
+T extract<T>(dynamic f2(void g2(int x2, T h2)) => null;
+var v = extract(f);
 ''');
-    expect(v.initializer.localFunctions, hasLength(1));
-    UnlinkedExecutable closure = v.initializer.localFunctions[0];
-    expect(closure.parameters, hasLength(2));
-    UnlinkedParam y = closure.parameters[1];
-    expect(y.name, 'y');
-    EntityRef typeRef = getTypeRefForSlot(y.inferredTypeSlot);
+    EntityRef typeRef = getTypeRefForSlot(v.inferredTypeSlot);
     checkLinkedTypeRef(typeRef, null, 'f',
         expectedKind: ReferenceKind.topLevelFunction);
     expect(typeRef.implicitFunctionTypeIndices, [0, 1]);
@@ -7912,15 +7837,11 @@
       return;
     }
     UnlinkedVariable v = serializeVariableText('''
-f({void g(int x, void h())}) => null;
-var v = f(g: (x, y) {});
+dynamic f({void g(int x, void h())}) => null;
+T extract<T>(dynamic f2({void g(int x2, T h2)})) => null;
+var v = extract(f);
 ''');
-    expect(v.initializer.localFunctions, hasLength(1));
-    UnlinkedExecutable closure = v.initializer.localFunctions[0];
-    expect(closure.parameters, hasLength(2));
-    UnlinkedParam y = closure.parameters[1];
-    expect(y.name, 'y');
-    EntityRef typeRef = getTypeRefForSlot(y.inferredTypeSlot);
+    EntityRef typeRef = getTypeRefForSlot(v.inferredTypeSlot);
     checkLinkedTypeRef(typeRef, null, 'f',
         expectedKind: ReferenceKind.topLevelFunction);
     expect(typeRef.implicitFunctionTypeIndices, [0, 1]);
@@ -7980,6 +7901,17 @@
         numTypeParameters: 1, numTypeArguments: 1);
   }
 
+  test_inferred_type_undefined() {
+    if (skipFullyLinkedData) {
+      return;
+    }
+    UnlinkedVariable v = serializeVariableText('var v = <Undefined>[];');
+    var typeRef = getTypeRefForSlot(v.inferredTypeSlot);
+    checkLinkedTypeRef(typeRef, 'dart:core', 'List',
+        numTypeArguments: 1, numTypeParameters: 1);
+    checkLinkedDynamicTypeRef(typeRef.typeArguments[0]);
+  }
+
   test_initializer_executable_with_bottom_return_type() {
     // The synthetic executable for `v` has type `() => Bottom`.
     UnlinkedVariable variable = serializeVariableText('int v = null;');
@@ -8859,6 +8791,117 @@
     checkTypeRef(mixin.interfaces[1], null, 'D');
   }
 
+  test_mixin_superInvokedNames_methodInvocation() {
+    UnlinkedClass mixin = serializeMixinText('''
+mixin M {
+  void x() {
+    super.a();
+    super.b().c();
+  }
+}
+''');
+    expect(mixin.superInvokedNames, unorderedEquals(['a', 'b']));
+  }
+
+  test_mixin_superInvokedNames_operator_binary() {
+    UnlinkedClass mixin = serializeMixinText('''
+mixin M {
+  void x() {
+    super + 1;
+    super - 2;
+  }
+}
+''');
+    expect(mixin.superInvokedNames, unorderedEquals(['+', '-']));
+  }
+
+  test_mixin_superInvokedNames_operator_index() {
+    UnlinkedClass mixin = serializeMixinText('''
+mixin M {
+  void x() {
+    super[0];
+  }
+}
+''');
+    expect(mixin.superInvokedNames, unorderedEquals(['[]']));
+  }
+
+  test_mixin_superInvokedNames_operator_index_indexEq() {
+    UnlinkedClass mixin = serializeMixinText('''
+mixin M {
+  void x() {
+    super[0] += 1;
+  }
+}
+''');
+    expect(mixin.superInvokedNames, unorderedEquals(['[]', '[]=']));
+  }
+
+  test_mixin_superInvokedNames_operator_indexEq() {
+    UnlinkedClass mixin = serializeMixinText('''
+mixin M {
+  void x() {
+    super[0] = 1;
+  }
+}
+''');
+    expect(mixin.superInvokedNames, unorderedEquals(['[]=']));
+  }
+
+  test_mixin_superInvokedNames_operator_prefix() {
+    UnlinkedClass mixin = serializeMixinText('''
+mixin M {
+  void x() {
+    ~super;
+    -super;
+  }
+}
+''');
+    expect(mixin.superInvokedNames, unorderedEquals(['~', 'unary-']));
+  }
+
+  test_mixin_superInvokedNames_propertyAccess_get() {
+    UnlinkedClass mixin = serializeMixinText('''
+mixin M {
+  void x() {
+    super.a;
+    super.b.c;
+
+    ~super.e;
+    -super.d;
+  }
+}
+''');
+    expect(mixin.superInvokedNames, unorderedEquals(['a', 'b', 'd', 'e']));
+  }
+
+  test_mixin_superInvokedNames_propertyAccess_get_set() {
+    UnlinkedClass mixin = serializeMixinText('''
+mixin M {
+  void x() {
+    super.a++;
+    --super.b;
+    super.c += 1;
+  }
+}
+''');
+    expect(
+      mixin.superInvokedNames,
+      unorderedEquals(['a', 'b', 'c', 'a=', 'b=', 'c=']),
+    );
+  }
+
+  test_mixin_superInvokedNames_propertyAccess_set() {
+    UnlinkedClass mixin = serializeMixinText('''
+mixin M {
+  void x() {
+    super.a = 1;
+  }
+}
+''');
+    expect(mixin.superInvokedNames, unorderedEquals(['a=']));
+  }
+
   test_mixin_typeParameters() {
     UnlinkedClass mixin = serializeMixinText('mixin M<T extends num, U> {}');
     expect(mixin.typeParameters, hasLength(2));
@@ -9778,8 +9821,10 @@
   }
 
   test_variable_final_top_level_untyped() {
+    if (skipFullyLinkedData) return;
     UnlinkedVariable variable = serializeVariableText('final v = 0;');
-    expect(variable.initializer.bodyExpr, isNotNull);
+    var typeRef = getTypeRefForSlot(variable.inferredTypeSlot);
+    checkLinkedTypeRef(typeRef, 'dart:core', 'int');
   }
 
   test_variable_implicit_dynamic() {
@@ -9923,19 +9968,14 @@
           UnlinkedExprOperation.pushInt,
           UnlinkedExprOperation.add,
         ],
-        assignmentOperators: [
-          expectedAssignOperator
-        ],
-        ints: [
-          1,
-          2,
-          3
-        ],
+        assignmentOperators: [expectedAssignOperator],
+        ints: [1, 2, 3],
         strings: [],
         referenceValidators: [
           (EntityRef r) => checkTypeRef(r, null, 'a',
               expectedKind: ReferenceKind.topLevelPropertyAccessor)
-        ]);
+        ],
+        forTypeInferenceOnly: true);
   }
 
   void _assertCodeRange(CodeRange codeRange, int offset, int length) {
@@ -9975,17 +10015,14 @@
           UnlinkedExprOperation.pushInt,
           UnlinkedExprOperation.add,
         ],
-        assignmentOperators: [
-          expectedAssignmentOperator
-        ],
-        ints: [
-          2
-        ],
+        assignmentOperators: [expectedAssignmentOperator],
+        ints: [2],
         strings: [],
         referenceValidators: [
           (EntityRef r) => checkTypeRef(r, null, 'a',
               expectedKind: ReferenceKind.topLevelPropertyAccessor)
-        ]);
+        ],
+        forTypeInferenceOnly: true);
   }
 }
 
diff --git a/pkg/analyzer/test/src/summary/test_strategies.dart b/pkg/analyzer/test/src/summary/test_strategies.dart
index b12f5da..8a5da25 100644
--- a/pkg/analyzer/test/src/summary/test_strategies.dart
+++ b/pkg/analyzer/test/src/summary/test_strategies.dart
@@ -4,9 +4,13 @@
 
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/ast/token.dart';
+import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/error/listener.dart';
+import 'package:analyzer/file_system/memory_file_system.dart';
+import 'package:analyzer/src/context/context.dart';
 import 'package:analyzer/src/dart/scanner/reader.dart';
 import 'package:analyzer/src/dart/scanner/scanner.dart';
+import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/parser.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/generated/utilities_dart.dart';
@@ -18,14 +22,15 @@
 import 'package:analyzer/src/summary/prelink.dart';
 import 'package:analyzer/src/summary/summarize_ast.dart';
 import 'package:analyzer/src/summary/summarize_elements.dart';
+import 'package:analyzer/src/task/api/dart.dart';
+import 'package:analyzer/src/task/api/general.dart';
 import 'package:path/path.dart' show posix;
 import 'package:test/test.dart';
 
 import '../context/mock_sdk.dart';
+import 'resynthesize_common.dart';
 
-/**
- * Convert the given Posix style file [path] to the corresponding absolute URI.
- */
+/// Convert the given Posix style file [path] to the corresponding absolute URI.
 String absUri(String path) {
   String absolutePath = posix.absolute(path);
   return posix.toUri(absolutePath).toString();
@@ -38,15 +43,12 @@
   Token token = scanner.tokenize();
   Parser parser = new Parser(
       NonExistingSource.unknown, AnalysisErrorListener.NULL_LISTENER);
-  (parser as ParserAdapter).fastaParser.isMixinSupportEnabled = true;
   CompilationUnit unit = parser.parseCompilationUnit(token);
   unit.lineInfo = new LineInfo(scanner.lineStarts);
   return unit;
 }
 
-/**
- * Verify invariants of the given [linkedLibrary].
- */
+/// Verify invariants of the given [linkedLibrary].
 void _validateLinkedLibrary(LinkedLibrary linkedLibrary) {
   for (LinkedUnit unit in linkedLibrary.units) {
     for (LinkedReference reference in unit.references) {
@@ -80,14 +82,170 @@
   }
 }
 
-/**
- * [SerializedMockSdk] is a singleton class representing the result of
- * serializing the mock SDK to summaries.  It is computed once and then shared
- * among test invocations so that we don't bog down the tests.
- *
- * Note: should an exception occur during computation of [instance], it will
- * silently be set to null to allow other tests to complete quickly.
- */
+/// Abstract base class for tests of summary resynthesis.
+///
+/// Test classes should not extend this class directly; they should extend a
+/// class that implements this class with methods that drive summary generation.
+/// The tests themselves can then be provided via mixin, allowing summaries to
+/// be tested in a variety of ways.
+abstract class ResynthesizeTestStrategy {
+  //Future<LibraryElementImpl> checkLibrary(String text,
+  //    {bool allowErrors: false, bool dumpSummaries: false});
+
+  void set allowMissingFiles(bool value);
+
+  AnalysisContextImpl get context;
+
+  MemoryResourceProvider get resourceProvider;
+
+  void set testFile(String value);
+
+  Source get testSource;
+
+  void addLibrary(String uri);
+
+  Source addLibrarySource(String filePath, String contents);
+
+  Source addSource(String path, String contents);
+
+  Source addTestSource(String code, [Uri uri]);
+
+  void checkMinimalResynthesisWork(
+      TestSummaryResynthesizer resynthesizer, LibraryElement library);
+
+  TestSummaryResynthesizer encodeLibrary(Source source);
+
+  void prepareAnalysisContext([AnalysisOptions options]);
+}
+
+/// Implementation of [SummaryBlackBoxTestStrategy] that drives summary
+/// generation using the old two-phase API.
+class ResynthesizeTestStrategyTwoPhase extends AbstractResynthesizeTest
+    implements ResynthesizeTestStrategy {
+  final Set<Source> serializedSources = new Set<Source>();
+
+  final Map<String, UnlinkedUnitBuilder> uriToUnit =
+      <String, UnlinkedUnitBuilder>{};
+
+  PackageBundleAssembler bundleAssembler = new PackageBundleAssembler();
+
+  TestSummaryResynthesizer encodeLibrary(Source source) {
+    _serializeLibrary(source);
+
+    PackageBundle bundle =
+        new PackageBundle.fromBuffer(bundleAssembler.assemble().toBuffer());
+
+    Map<String, UnlinkedUnit> unlinkedSummaries = <String, UnlinkedUnit>{};
+    for (int i = 0; i < bundle.unlinkedUnitUris.length; i++) {
+      String uri = bundle.unlinkedUnitUris[i];
+      unlinkedSummaries[uri] = bundle.unlinkedUnits[i];
+    }
+
+    LinkedLibrary getDependency(String absoluteUri) {
+      Map<String, LinkedLibrary> sdkLibraries =
+          SerializedMockSdk.instance.uriToLinkedLibrary;
+      LinkedLibrary linkedLibrary = sdkLibraries[absoluteUri];
+      if (linkedLibrary == null && !allowMissingFiles) {
+        fail('Linker unexpectedly requested LinkedLibrary for "$absoluteUri".'
+            '  Libraries available: ${sdkLibraries.keys}');
+      }
+      return linkedLibrary;
+    }
+
+    UnlinkedUnit getUnit(String absoluteUri) {
+      UnlinkedUnit unit = uriToUnit[absoluteUri] ??
+          SerializedMockSdk.instance.uriToUnlinkedUnit[absoluteUri];
+      if (unit == null && !allowMissingFiles) {
+        fail('Linker unexpectedly requested unit for "$absoluteUri".');
+      }
+      return unit;
+    }
+
+    Set<String> nonSdkLibraryUris = serializedSources
+        .where((Source source) =>
+            !source.isInSystemLibrary &&
+            context.computeKindOf(source) == SourceKind.LIBRARY)
+        .map((Source source) => source.uri.toString())
+        .toSet();
+
+    Map<String, LinkedLibrary> linkedSummaries = link(nonSdkLibraryUris,
+        getDependency, getUnit, context.declaredVariables.get);
+
+    return new TestSummaryResynthesizer(
+        context,
+        new Map<String, UnlinkedUnit>()
+          ..addAll(SerializedMockSdk.instance.uriToUnlinkedUnit)
+          ..addAll(unlinkedSummaries),
+        new Map<String, LinkedLibrary>()
+          ..addAll(SerializedMockSdk.instance.uriToLinkedLibrary)
+          ..addAll(linkedSummaries),
+        allowMissingFiles);
+  }
+
+  UnlinkedUnit _getUnlinkedUnit(Source source) {
+    if (source == null) {
+      return new UnlinkedUnitBuilder();
+    }
+
+    String uriStr = source.uri.toString();
+    {
+      UnlinkedUnit unlinkedUnitInSdk =
+          SerializedMockSdk.instance.uriToUnlinkedUnit[uriStr];
+      if (unlinkedUnitInSdk != null) {
+        return unlinkedUnitInSdk;
+      }
+    }
+    return uriToUnit.putIfAbsent(uriStr, () {
+      int modificationTime = context.computeResult(source, MODIFICATION_TIME);
+      if (modificationTime < 0) {
+        // Source does not exist.
+        if (!allowMissingFiles) {
+          fail('Unexpectedly tried to get unlinked summary for $source');
+        }
+        return null;
+      }
+      CompilationUnit unit = context.computeResult(source, PARSED_UNIT);
+      UnlinkedUnitBuilder unlinkedUnit = serializeAstUnlinked(unit);
+      bundleAssembler.addUnlinkedUnit(source, unlinkedUnit);
+      return unlinkedUnit;
+    });
+  }
+
+  void _serializeLibrary(Source librarySource) {
+    if (librarySource == null || librarySource.isInSystemLibrary) {
+      return;
+    }
+    if (!serializedSources.add(librarySource)) {
+      return;
+    }
+
+    UnlinkedUnit getPart(String absoluteUri) {
+      Source source = context.sourceFactory.forUri(absoluteUri);
+      return _getUnlinkedUnit(source);
+    }
+
+    UnlinkedPublicNamespace getImport(String relativeUri) {
+      return getPart(relativeUri)?.publicNamespace;
+    }
+
+    UnlinkedUnit definingUnit = _getUnlinkedUnit(librarySource);
+    if (definingUnit != null) {
+      LinkedLibraryBuilder linkedLibrary = prelink(librarySource.uri.toString(),
+          definingUnit, getPart, getImport, context.declaredVariables.get);
+      linkedLibrary.dependencies.skip(1).forEach((LinkedDependency d) {
+        Source source = context.sourceFactory.forUri(d.uri);
+        _serializeLibrary(source);
+      });
+    }
+  }
+}
+
+/// [SerializedMockSdk] is a singleton class representing the result of
+/// serializing the mock SDK to summaries.  It is computed once and then shared
+/// among test invocations so that we don't bog down the tests.
+///
+/// Note: should an exception occur during computation of [instance], it will
+/// silently be set to null to allow other tests to complete quickly.
 class SerializedMockSdk {
   static final SerializedMockSdk instance = _serializeMockSdk();
 
@@ -123,10 +281,8 @@
 /// The tests themselves can then be provided via mixin, allowing summaries to
 /// be tested in a variety of ways.
 abstract class SummaryBaseTestStrategy {
-  /**
-   * Add the given source file so that it may be referenced by the file under
-   * test.
-   */
+  /// Add the given source file so that it may be referenced by the file under
+  /// test.
   void addNamedSource(String filePath, String contents);
 }
 
@@ -137,34 +293,30 @@
 /// The tests themselves can then be provided via mixin, allowing summaries to
 /// be tested in a variety of ways.
 abstract class SummaryBlackBoxTestStrategy extends SummaryBaseTestStrategy {
-  /**
-   * A test will set this to `true` if it contains `import`, `export`, or
-   * `part` declarations that deliberately refer to non-existent files.
-   */
+  /// A test will set this to `true` if it contains `import`, `export`, or
+  /// `part` declarations that deliberately refer to non-existent files.
   void set allowMissingFiles(bool value);
 
-  /**
-   * Get access to the linked summary that results from serializing and
-   * then deserializing the library under test.
-   */
+  /// Indicates whether the summary contains expressions for non-const fields.
+  ///
+  /// When one-phase summarization is in use, only const field initializer
+  /// expressions are stored in the summary.
+  bool get containsNonConstExprs;
+
+  /// Get access to the linked summary that results from serializing and
+  /// then deserializing the library under test.
   LinkedLibrary get linked;
 
-  /**
-   * `true` if the linked portion of the summary only contains prelinked data.
-   * This happens because we don't yet have a full linker; only a prelinker.
-   */
+  /// `true` if the linked portion of the summary only contains prelinked data.
+  /// This happens because we don't yet have a full linker; only a prelinker.
   bool get skipFullyLinkedData;
 
-  /**
-   * Get access to the unlinked compilation unit summaries that result from
-   * serializing and deserializing the library under test.
-   */
+  /// Get access to the unlinked compilation unit summaries that result from
+  /// serializing and deserializing the library under test.
   List<UnlinkedUnit> get unlinkedUnits;
 
-  /**
-   * Serialize the given library [text], then deserialize it and store its
-   * summary in [lib].
-   */
+  /// Serialize the given library [text], then deserialize it and store its
+  /// summary in [lib].
   void serializeLibraryText(String text, {bool allowErrors: false});
 }
 
@@ -197,6 +349,9 @@
   }
 
   @override
+  bool get containsNonConstExprs => false;
+
+  @override
   bool get skipFullyLinkedData => false;
 
   @override
@@ -314,20 +469,16 @@
 
   LibraryElementInBuildUnit get testLibrary;
 
-  /**
-   * Add the given package bundle as a dependency so that it may be referenced
-   * by the files under test.
-   */
+  /// Add the given package bundle as a dependency so that it may be referenced
+  /// by the files under test.
   void addBundle(String path, PackageBundle bundle);
 
   void createLinker(String text, {String path: '/test.dart'});
 
-  /**
-   * Link together the given file, along with any other files passed to
-   * [addNamedSource], to form a package bundle.  Reset the state of the buffers
-   * accumulated by [addNamedSource] and [addBundle] so that further bundles
-   * can be created.
-   */
+  /// Link together the given file, along with any other files passed to
+  /// [addNamedSource], to form a package bundle.  Reset the state of the
+  /// buffers accumulated by [addNamedSource] and [addBundle] so that further
+  /// bundles can be created.
   PackageBundleBuilder createPackageBundle(String text,
       {String path: '/test.dart', String uri});
 }
@@ -364,8 +515,8 @@
         _linkerInputs.linkedLibraries,
         _linkerInputs.getUnit,
         _linkerInputs.getDeclaredVariable);
-    linker = new Linker(
-        linkedLibraries, _linkerInputs.getDependency, _linkerInputs.getUnit);
+    linker = new Linker(linkedLibraries, _linkerInputs.getDependency,
+        _linkerInputs.getUnit, null);
   }
 
   @override
@@ -387,31 +538,24 @@
   }
 }
 
-/**
- * [_FilesToLink] stores information about a set of files to be linked together.
- * This information is grouped into a class to allow it to be reset easily when
- * [_SummaryBaseTestStrategyTwoPhase._createLinkerInputs] is called.
- *
- * The generic parameter [U] is the type of information stored for each
- * compilation unit.
- */
+/// [_FilesToLink] stores information about a set of files to be linked
+/// together.  This information is grouped into a class to allow it to be reset
+/// easily when [_SummaryBaseTestStrategyTwoPhase._createLinkerInputs] is
+/// called.
+///
+/// The generic parameter [U] is the type of information stored for each
+/// compilation unit.
 class _FilesToLink<U> {
-  /**
-   * Map from absolute URI to the [U] for each compilation unit passed to
-   * [addNamedSource].
-   */
+  /// Map from absolute URI to the [U] for each compilation unit passed to
+  /// [addNamedSource].
   Map<String, U> uriToUnit = <String, U>{};
 
-  /**
-   * Information about summaries to be included in the link process.
-   */
+  /// Information about summaries to be included in the link process.
   SummaryDataStore summaryDataStore = new SummaryDataStore([]);
 }
 
-/**
- * Instances of the class [_LinkerInputs] encapsulate the necessary information
- * to pass to the summary linker.
- */
+/// Instances of the class [_LinkerInputs] encapsulate the necessary information
+/// to pass to the summary linker.
 class _LinkerInputs {
   final bool _allowMissingFiles;
   final Map<String, UnlinkedUnit> _uriToUnit;
@@ -466,9 +610,7 @@
 /// using the old two-phase API.
 abstract class _SummaryBaseTestStrategyTwoPhase
     implements SummaryBaseTestStrategy {
-  /**
-   * Information about the files to be linked.
-   */
+  /// Information about the files to be linked.
   _FilesToLink<UnlinkedUnitBuilder> _filesToLink =
       new _FilesToLink<UnlinkedUnitBuilder>();
 
@@ -529,6 +671,9 @@
   }
 
   @override
+  bool get containsNonConstExprs => true;
+
+  @override
   void serializeLibraryText(String text, {bool allowErrors: false}) {
     Map<String, UnlinkedUnitBuilder> uriToUnit = this._filesToLink.uriToUnit;
     _linkerInputs = _createLinkerInputs(text);
diff --git a/pkg/analyzer/test/src/task/options_test.dart b/pkg/analyzer/test/src/task/options_test.dart
index 4f0a651..e2a8682 100644
--- a/pkg/analyzer/test/src/task/options_test.dart
+++ b/pkg/analyzer/test/src/task/options_test.dart
@@ -245,7 +245,6 @@
         removeCode(StrongModeCode.NOT_INSTANTIATED_BOUND);
         removeCode(StrongModeCode.TOP_LEVEL_CYCLE);
         removeCode(StrongModeCode.TOP_LEVEL_FUNCTION_LITERAL_BLOCK);
-        removeCode(StrongModeCode.TOP_LEVEL_FUNCTION_LITERAL_PARAMETER);
         removeCode(StrongModeCode.TOP_LEVEL_IDENTIFIER_NO_TYPE);
         removeCode(StrongModeCode.TOP_LEVEL_INSTANCE_GETTER);
         removeCode(StrongModeCode.TOP_LEVEL_INSTANCE_METHOD);
diff --git a/pkg/analyzer/test/src/task/strong/checker_test.dart b/pkg/analyzer/test/src/task/strong/checker_test.dart
index 2bd64ac..994a8bd 100644
--- a/pkg/analyzer/test/src/task/strong/checker_test.dart
+++ b/pkg/analyzer/test/src/task/strong/checker_test.dart
@@ -647,29 +647,29 @@
 typedef dynamic A(dynamic x);
 class B {
   int call(int x) => x;
-  double col(double x) => x;
+  bool col(bool x) => x;
 }
 void main() {
   {
     B f = new B();
     int x;
-    double y;
+    bool y;
     x = f(3);
-    x = /*error:INVALID_ASSIGNMENT*/f.col(3.0);
+    x = /*error:INVALID_ASSIGNMENT*/f.col(true);
     y = /*error:INVALID_ASSIGNMENT*/f(3);
-    y = f.col(3.0);
-    f(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/3.0);
+    y = f.col(true);
+    f(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/true);
     f.col(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/3);
   }
   {
     Function f = new B();
     int x;
-    double y;
+    bool y;
     x = /*info:DYNAMIC_CAST, info:DYNAMIC_INVOKE*/f(3);
-    x = /*info:DYNAMIC_CAST, info:DYNAMIC_INVOKE*/f./*error:UNDEFINED_METHOD*/col(3.0);
+    x = /*info:DYNAMIC_CAST, info:DYNAMIC_INVOKE*/f./*error:UNDEFINED_METHOD*/col(true);
     y = /*info:DYNAMIC_CAST, info:DYNAMIC_INVOKE*/f(3);
-    y = /*info:DYNAMIC_CAST, info:DYNAMIC_INVOKE*/f./*error:UNDEFINED_METHOD*/col(3.0);
-    /*info:DYNAMIC_INVOKE*/f(3.0);
+    y = /*info:DYNAMIC_CAST, info:DYNAMIC_INVOKE*/f./*error:UNDEFINED_METHOD*/col(true);
+    /*info:DYNAMIC_INVOKE*/f(true);
     // Through type propagation, we know f is actually a B, hence the
     // hint.
     /*info:DYNAMIC_INVOKE*/f./*error:UNDEFINED_METHOD*/col(3);
@@ -679,22 +679,22 @@
     B b = new B();
     f = /* error:INVALID_ASSIGNMENT*/b;
     int x;
-    double y;
+    bool y;
     x = /*info:DYNAMIC_CAST*/f(3);
     y = /*info:DYNAMIC_CAST*/f(3);
-    f(3.0);
+    f(true);
   }
   {
     dynamic g = new B();
-    /*info:DYNAMIC_INVOKE*/g.call(32.0);
-    /*info:DYNAMIC_INVOKE*/g.col(42.0);
-    /*info:DYNAMIC_INVOKE*/g.foo(42.0);
+    /*info:DYNAMIC_INVOKE*/g.call(true);
+    /*info:DYNAMIC_INVOKE*/g.col(true);
+    /*info:DYNAMIC_INVOKE*/g.foo(true);
     /*info:DYNAMIC_INVOKE*/g.x;
     A f = /* error:INVALID_ASSIGNMENT*/new B();
     B b = new B();
     f = /*error:INVALID_ASSIGNMENT*/b;
-    /*info:DYNAMIC_INVOKE*/f./*error:UNDEFINED_METHOD*/col(42.0);
-    /*info:DYNAMIC_INVOKE*/f./*error:UNDEFINED_METHOD*/foo(42.0);
+    /*info:DYNAMIC_INVOKE*/f./*error:UNDEFINED_METHOD*/col(true);
+    /*info:DYNAMIC_INVOKE*/f./*error:UNDEFINED_METHOD*/foo(true);
     /*info:DYNAMIC_INVOKE*/f./*error:UNDEFINED_GETTER*/x;
   }
 }
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 177475c..b2e2a7a 100644
--- a/pkg/analyzer/test/src/task/strong/inferred_type_test.dart
+++ b/pkg/analyzer/test/src/task/strong/inferred_type_test.dart
@@ -1886,11 +1886,12 @@
   printInt(/*info:DOWN_CAST_IMPLICIT*/myMax(1, 2));
   printInt(myMax(1, 2) as int);
 
-  // Mixing int and double means return type is num.
+  // An int context means doubles are rejected
   printInt(max(1, /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/2.0));
   printInt(min(1, /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/2.0));
-  printDouble(max(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/1, 2.0));
-  printDouble(min(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/1, 2.0));
+  // A double context means ints are accepted as doubles
+  printDouble(max(1, 2.0));
+  printDouble(min(1, 2.0));
 
   // Types other than int and double are not accepted.
   printInt(
diff --git a/pkg/analyzer/test/src/task/strong_mode_driver_test.dart b/pkg/analyzer/test/src/task/strong_mode_driver_test.dart
deleted file mode 100644
index e459d9e..0000000
--- a/pkg/analyzer/test/src/task/strong_mode_driver_test.dart
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
-// for 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_reflective_loader/test_reflective_loader.dart';
-
-import 'strong_mode_test.dart';
-
-main() {
-  defineReflectiveSuite(() {
-    defineReflectiveTests(InstanceMemberInferrerTest_Driver);
-  });
-}
-
-@reflectiveTest
-class InstanceMemberInferrerTest_Driver extends InstanceMemberInferrerTest {
-  @override
-  bool get enableNewAnalysisDriver => true;
-}
diff --git a/pkg/analyzer/test/src/task/strong_mode_test.dart b/pkg/analyzer/test/src/task/strong_mode_test.dart
index b0cec78..cbf2625 100644
--- a/pkg/analyzer/test/src/task/strong_mode_test.dart
+++ b/pkg/analyzer/test/src/task/strong_mode_test.dart
@@ -5,9 +5,6 @@
 import 'dart:async';
 
 import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/dart/element/type.dart';
-import 'package:analyzer/src/dart/resolver/inheritance_manager.dart';
-import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/task/strong_mode.dart';
 import 'package:test/test.dart';
@@ -17,438 +14,12 @@
 
 main() {
   defineReflectiveSuite(() {
-    defineReflectiveTests(InstanceMemberInferrerTest);
     defineReflectiveTests(SetFieldTypeTest);
     defineReflectiveTests(VariableGathererTest);
   });
 }
 
 @reflectiveTest
-class InstanceMemberInferrerTest extends ResolverTestCase {
-  InstanceMemberInferrer createInferrer(LibraryElement library) {
-    AnalysisContext context = library.context;
-    var inheritanceManager = new InheritanceManager(library);
-    return new InstanceMemberInferrer(
-        context.typeProvider, (_) => inheritanceManager,
-        typeSystem: context.typeSystem);
-  }
-
-  /**
-   * Add a source with the given [content] and return the result of resolving
-   * the source.
-   */
-  Future<CompilationUnitElement> resolve(String content) async {
-    Source source = addNamedSource('/test.dart', content);
-    if (enableNewAnalysisDriver) {
-      var analysisResult = await computeAnalysisResult(source);
-      return analysisResult.unit.declaredElement;
-    } else {
-      return analysisContext
-          .resolveCompilationUnit2(source, source)
-          .declaredElement;
-    }
-  }
-
-  test_inferCompilationUnit_invalid_inheritanceCycle() async {
-    CompilationUnitElement unit = await resolve('''
-class A extends C {}
-class B extends A {}
-class C extends B {}
-''');
-    _runInferrer(unit);
-  }
-
-  test_inferCompilationUnit_method_parameter_multiple_different() async {
-    String methodName = 'm';
-    CompilationUnitElement unit = await resolve('''
-class A {
-  $methodName(int p) => 0;
-}
-class B {
-  $methodName(double p) => 0;
-}
-class C implements A, B {
-  $methodName(p) => 0;
-}
-''');
-    ClassElement classC = unit.getType('C');
-    MethodElement methodC = classC.getMethod(methodName);
-    ParameterElement parameterC = methodC.parameters[0];
-    expect(parameterC.type.isDynamic, isTrue);
-
-    _runInferrer(unit);
-
-    expect(parameterC.type.isDynamic, isTrue);
-  }
-
-  test_inferCompilationUnit_method_parameter_multiple_named_different() async {
-    String methodName = 'm';
-    CompilationUnitElement unit = await resolve('''
-class A {
-  $methodName({int p}) => 0;
-}
-class B {
-  $methodName({int q}) => 0;
-}
-class C implements A, B {
-  $methodName({p}) => 0;
-}
-''');
-    ClassElement classC = unit.getType('C');
-    MethodElement methodC = classC.getMethod(methodName);
-    ParameterElement parameterC = methodC.parameters[0];
-    expect(parameterC.type.isDynamic, isTrue);
-
-    _runInferrer(unit);
-
-    expect(parameterC.type.isDynamic, isTrue);
-  }
-
-  test_inferCompilationUnit_method_parameter_multiple_named_same() async {
-    String methodName = 'm';
-    CompilationUnitElement unit = await resolve('''
-class A {
-  $methodName({int p}) => 0;
-}
-class B {
-  $methodName({int p}) => 0;
-}
-class C implements A, B {
-  $methodName({p}) => 0;
-}
-''');
-    ClassElement classA = unit.getType('A');
-    MethodElement methodA = classA.getMethod(methodName);
-    ParameterElement parameterA = methodA.parameters[0];
-    DartType expectedType = parameterA.type;
-    ClassElement classC = unit.getType('C');
-    MethodElement methodC = classC.getMethod(methodName);
-    ParameterElement parameterC = methodC.parameters[0];
-    if (previewDart2) {
-      expect(parameterC.type.isDynamic, isFalse);
-    } else {
-      expect(parameterC.type.isDynamic, isTrue);
-    }
-
-    _runInferrer(unit);
-
-    expect(parameterC.type, expectedType);
-  }
-
-  test_inferCompilationUnit_method_parameter_multiple_namedAndRequired() async {
-    String methodName = 'm';
-    CompilationUnitElement unit = await resolve('''
-class A {
-  $methodName({int p}) => 0;
-}
-class B {
-  $methodName(int p) => 0;
-}
-class C implements A, B {
-  $methodName(p) => 0;
-}
-''');
-    ClassElement classC = unit.getType('C');
-    MethodElement methodC = classC.getMethod(methodName);
-    ParameterElement parameterC = methodC.parameters[0];
-    expect(parameterC.type.isDynamic, isTrue);
-
-    _runInferrer(unit);
-
-    expect(parameterC.type.isDynamic, isTrue);
-  }
-
-  test_inferCompilationUnit_method_parameter_multiple_optionalAndRequired() async {
-    String methodName = 'm';
-    CompilationUnitElement unit = await resolve('''
-class A {
-  $methodName(int p) => 0;
-}
-class B {
-  $methodName([int p]) => 0;
-}
-class C implements A, B {
-  $methodName(p) => 0;
-}
-''');
-    ClassElement classA = unit.getType('A');
-    MethodElement methodA = classA.getMethod(methodName);
-    ParameterElement parameterA = methodA.parameters[0];
-    DartType expectedType = parameterA.type;
-    ClassElement classC = unit.getType('C');
-    MethodElement methodC = classC.getMethod(methodName);
-    ParameterElement parameterC = methodC.parameters[0];
-    if (previewDart2) {
-      expect(parameterC.type.isDynamic, isFalse);
-    } else {
-      expect(parameterC.type.isDynamic, isTrue);
-    }
-
-    _runInferrer(unit);
-
-    expect(parameterC.type, expectedType);
-  }
-
-  test_inferCompilationUnit_method_parameter_single_generic() async {
-    String methodName = 'm';
-    CompilationUnitElement unit = await resolve('''
-class A<E> {
-  $methodName(E p) => 0;
-}
-class C<E> implements A<E> {
-  $methodName(p) => 0;
-}
-''');
-    ClassElement classC = unit.getType('C');
-    DartType typeCE = classC.typeParameters[0].type;
-    MethodElement methodC = classC.getMethod(methodName);
-    ParameterElement parameterC = methodC.parameters[0];
-    if (previewDart2) {
-      expect(parameterC.type.isDynamic, isFalse);
-    } else {
-      expect(parameterC.type.isDynamic, isTrue);
-    }
-    expect(methodC.type.typeArguments, [typeCE]);
-
-    _runInferrer(unit);
-
-    expect(parameterC.type, classC.typeParameters[0].type);
-    expect(methodC.type.typeArguments, [typeCE],
-        reason: 'function type should still have type arguments');
-  }
-
-  test_inferCompilationUnit_method_return_multiple_different() async {
-    String methodName = 'm';
-    CompilationUnitElement unit = await resolve('''
-class A {
-  int $methodName() => 0;
-}
-class B {
-  double $methodName() => 0.0;
-}
-class C implements A, B {
-  $methodName() => 0;
-}
-''');
-    ClassElement classC = unit.getType('C');
-    MethodElement methodC = classC.getMethod(methodName);
-    expect(methodC.returnType.isDynamic, isTrue);
-
-    _runInferrer(unit);
-
-    expect(methodC.returnType.isDynamic, isTrue);
-  }
-
-  test_inferCompilationUnit_method_return_multiple_different_generic() async {
-    String methodName = 'm';
-    CompilationUnitElement unit = await resolve('''
-class A<E> {
-  E $methodName() => null;
-}
-class B<E> {
-  E $methodName() => null;
-}
-class C implements A<int>, B<double> {
-  $methodName() => null;
-}
-''');
-    ClassElement classC = unit.getType('C');
-    MethodElement methodC = classC.getMethod(methodName);
-    expect(methodC.returnType.isDynamic, isTrue);
-
-    _runInferrer(unit);
-
-    expect(methodC.returnType.isDynamic, isTrue);
-  }
-
-  test_inferCompilationUnit_method_return_multiple_dynamic() async {
-    String methodName = 'm';
-    CompilationUnitElement unit = await resolve('''
-class A {
-  int $methodName() => 0;
-}
-class B {
-  $methodName() => 0;
-}
-class C implements A, B {
-  $methodName() => 0;
-}
-''');
-    ClassElement classC = unit.getType('C');
-    MethodElement methodC = classC.getMethod(methodName);
-    expect(methodC.returnType.isDynamic, isTrue);
-
-    _runInferrer(unit);
-
-    expect(methodC.returnType.isDynamic, isTrue);
-  }
-
-  test_inferCompilationUnit_method_return_multiple_same_generic() async {
-    String methodName = 'm';
-    CompilationUnitElement unit = await resolve('''
-class A<E> {
-  E $methodName() => 0;
-}
-class B<E> {
-  E $methodName() => 0;
-}
-class C<E> implements A<E>, B<E> {
-  $methodName() => 0;
-}
-''');
-    ClassElement classC = unit.getType('C');
-    MethodElement methodC = classC.getMethod(methodName);
-    if (previewDart2) {
-      expect(methodC.returnType.isDynamic, isFalse);
-    } else {
-      expect(methodC.returnType.isDynamic, isTrue);
-    }
-
-    _runInferrer(unit);
-
-    expect(methodC.returnType, classC.typeParameters[0].type);
-  }
-
-  test_inferCompilationUnit_method_return_multiple_same_nonVoid() async {
-    String methodName = 'm';
-    CompilationUnitElement unit = await resolve('''
-class A {
-  int $methodName() => 0;
-}
-class B {
-  int $methodName() => 0;
-}
-class C implements A, B {
-  $methodName() => 0;
-}
-''');
-    ClassElement classA = unit.getType('A');
-    MethodElement methodA = classA.getMethod(methodName);
-    DartType expectedType = methodA.returnType;
-    ClassElement classC = unit.getType('C');
-    MethodElement methodC = classC.getMethod(methodName);
-    if (previewDart2) {
-      expect(methodC.returnType.isDynamic, isFalse);
-    } else {
-      expect(methodC.returnType.isDynamic, isTrue);
-    }
-
-    _runInferrer(unit);
-
-    expect(methodC.returnType, expectedType);
-  }
-
-  test_inferCompilationUnit_method_return_multiple_same_void() async {
-    String methodName = 'm';
-    CompilationUnitElement unit = await resolve('''
-class A {
-  void $methodName() {};
-}
-class B {
-  void $methodName() {};
-}
-class C implements A, B {
-  $methodName() {};
-}
-''');
-    ClassElement classA = unit.getType('A');
-    MethodElement methodA = classA.getMethod(methodName);
-    DartType expectedType = methodA.returnType;
-    ClassElement classC = unit.getType('C');
-    MethodElement methodC = classC.getMethod(methodName);
-    if (previewDart2) {
-      expect(methodC.returnType.isDynamic, isFalse);
-    } else {
-      expect(methodC.returnType.isDynamic, isTrue);
-    }
-
-    _runInferrer(unit);
-
-    expect(methodC.returnType, expectedType);
-  }
-
-  test_inferCompilationUnit_method_return_multiple_void() async {
-    String methodName = 'm';
-    CompilationUnitElement unit = await resolve('''
-class A {
-  int $methodName() => 0;
-}
-class B {
-  void $methodName() => 0;
-}
-class C implements A, B {
-  $methodName() => 0;
-}
-''');
-    ClassElement classC = unit.getType('C');
-    MethodElement methodC = classC.getMethod(methodName);
-    expect(methodC.returnType.isDynamic, isTrue);
-
-    _runInferrer(unit);
-
-    expect(methodC.returnType.isDynamic, isTrue);
-  }
-
-  test_inferCompilationUnit_method_return_single() async {
-    String methodName = 'm';
-    CompilationUnitElement unit = await resolve('''
-class A {
-  int $methodName() => 0;
-}
-class B extends A {
-  $methodName() => 0;
-}
-''');
-    ClassElement classA = unit.getType('A');
-    MethodElement methodA = classA.getMethod(methodName);
-    ClassElement classB = unit.getType('B');
-    MethodElement methodB = classB.getMethod(methodName);
-    if (previewDart2) {
-      expect(methodB.returnType.isDynamic, isFalse);
-    } else {
-      expect(methodB.returnType.isDynamic, isTrue);
-    }
-
-    _runInferrer(unit);
-
-    expect(methodB.returnType, methodA.returnType);
-  }
-
-  test_inferCompilationUnit_method_return_single_generic() async {
-    String methodName = 'm';
-    CompilationUnitElement unit = await resolve('''
-class A<E> {
-  E $methodName() => 0;
-}
-class B<E> extends A<E> {
-  $methodName() => 0;
-}
-''');
-    ClassElement classB = unit.getType('B');
-    DartType typeBE = classB.typeParameters[0].type;
-    MethodElement methodB = classB.getMethod(methodName);
-    if (previewDart2) {
-      expect(methodB.returnType.isDynamic, isFalse);
-    } else {
-      expect(methodB.returnType.isDynamic, isTrue);
-    }
-    expect(methodB.type.typeArguments, [typeBE]);
-
-    _runInferrer(unit);
-
-    expect(methodB.returnType, classB.typeParameters[0].type);
-    expect(methodB.type.typeArguments, [typeBE],
-        reason: 'function type should still have type arguments');
-  }
-
-  InstanceMemberInferrer _runInferrer(CompilationUnitElement unit) {
-    InstanceMemberInferrer inferrer = createInferrer(unit.library);
-    inferrer.inferCompilationUnit(unit);
-    return inferrer;
-  }
-}
-
-@reflectiveTest
 class SetFieldTypeTest extends ResolverTestCase {
   test_setter_withoutParameter() async {
     Source source = addSource('''
diff --git a/pkg/analyzer/test/src/task/test_all.dart b/pkg/analyzer/test/src/task/test_all.dart
index 92e46d2..8d02ae5 100644
--- a/pkg/analyzer/test/src/task/test_all.dart
+++ b/pkg/analyzer/test/src/task/test_all.dart
@@ -18,7 +18,6 @@
 import 'options_test.dart' as options_test;
 import 'options_work_manager_test.dart' as options_work_manager_test;
 import 'strong/test_all.dart' as strong_mode_test_all;
-import 'strong_mode_driver_test.dart' as strong_mode_driver_test;
 import 'strong_mode_test.dart' as strong_mode_test;
 import 'yaml_test.dart' as yaml_test;
 
@@ -37,7 +36,6 @@
     options_test.main();
     options_work_manager_test.main();
     strong_mode_test_all.main();
-    strong_mode_driver_test.main();
     strong_mode_test.main();
     yaml_test.main();
   }, name: 'task');
diff --git a/pkg/analyzer/tool/generate_files b/pkg/analyzer/tool/generate_files
index 0dbecaf..ad2a71e 100755
--- a/pkg/analyzer/tool/generate_files
+++ b/pkg/analyzer/tool/generate_files
@@ -43,5 +43,6 @@
 VM_OPTIONS+=("--packages=${ROOT_DIR}/.packages")
 
 cd "${SCRIPT_DIR}"
+"${DART}" "${VM_OPTIONS[@]}" "messages/generate.dart"
 "${DART}" "${VM_OPTIONS[@]}" "summary/generate.dart"
 "${DART}" "${VM_OPTIONS[@]}" "task_dependency_graph/generate.dart"
diff --git a/pkg/analyzer/tool/messages/generate.dart b/pkg/analyzer/tool/messages/generate.dart
new file mode 100644
index 0000000..61e3f65
--- /dev/null
+++ b/pkg/analyzer/tool/messages/generate.dart
@@ -0,0 +1,267 @@
+/**
+ * This file contains code to generate scanner and parser message
+ * based on the information in pkg/front_end/messages.yaml.
+ *
+ * For each message in messages.yaml that contains an 'index:' field,
+ * this tool generates an error with the name specified by the 'analyzerCode:'
+ * field and an entry in the fastaAnalyzerErrorList for that generated error.
+ * The text in the 'analyzerCode:' field must contain the name of the class
+ * containing the error and the name of the error separated by a `.`
+ * (e.g. ParserErrorCode.EQUALITY_CANNOT_BE_EQUALITY_OPERAND).
+ *
+ * It is expected that 'pkg/front_end/tool/fasta generate-messages'
+ * has already been successfully run.
+ */
+import 'dart:io';
+
+import 'package:analyzer/error/error.dart';
+import 'package:analyzer/src/dart/error/syntactic_errors.dart';
+import 'package:front_end/src/codegen/tools.dart';
+import 'package:front_end/src/testing/package_root.dart' as pkgRoot;
+import 'package:path/path.dart';
+import 'package:yaml/yaml.dart' show loadYaml;
+
+main() async {
+  String analyzerPkgPath = normalize(join(pkgRoot.packageRoot, 'analyzer'));
+  String frontEndPkgPath = normalize(join(pkgRoot.packageRoot, 'front_end'));
+
+  Map<dynamic, dynamic> messagesYaml = loadYaml(
+      await new File(join(frontEndPkgPath, 'messages.yaml'))
+          .readAsStringSync());
+  String errorConverterSource = await new File(join(analyzerPkgPath,
+          joinAll(posix.split('lib/src/fasta/error_converter.dart'))))
+      .readAsStringSync();
+  String syntacticErrorsSource = await new File(join(analyzerPkgPath,
+          joinAll(posix.split('lib/src/dart/error/syntactic_errors.dart'))))
+      .readAsStringSync();
+
+  final codeGenerator = new _SyntacticErrorGenerator(
+      messagesYaml, errorConverterSource, syntacticErrorsSource);
+
+  await GeneratedContent.generateAll(analyzerPkgPath, <GeneratedContent>[
+    new GeneratedFile('lib/src/dart/error/syntactic_errors.g.dart',
+        (String pkgPath) async {
+      codeGenerator.generateFormatCode();
+      return codeGenerator.out.toString();
+    }),
+  ]);
+
+  codeGenerator
+    ..checkForManualChanges()
+    ..printSummary();
+}
+
+class _SyntacticErrorGenerator {
+  final Map messagesYaml;
+  final String errorConverterSource;
+  final String syntacticErrorsSource;
+  final translatedEntries = <Map>[];
+  final out = new StringBuffer('''
+//
+// THIS FILE IS GENERATED. DO NOT EDIT.
+//
+// Instead modify 'pkg/front_end/messages.yaml' and run
+// 'dart pkg/analyzer/tool/messages/generate.dart' to update.
+
+part of 'syntactic_errors.dart';
+
+''');
+  _SyntacticErrorGenerator(
+      this.messagesYaml, this.errorConverterSource, this.syntacticErrorsSource);
+
+  void generateFormatCode() {
+    messagesYaml.forEach((name, entry) {
+      if (entry is Map) {
+        if (entry['index'] is int && entry['analyzerCode'] is String) {
+          translatedEntries.add(entry);
+        }
+      }
+    });
+    generateFastaAnalyzerErrorCodeList();
+    generateErrorCodes();
+  }
+
+  void generateFastaAnalyzerErrorCodeList() {
+    final sorted = new List<Map>(translatedEntries.length);
+    for (var entry in translatedEntries) {
+      var index = entry['index'];
+      if (index is int && index >= 1 && index <= sorted.length) {
+        if (sorted[index - 1] == null) {
+          sorted[index - 1] = entry;
+          continue;
+        }
+      }
+      throw shouldRunFastaGenerateMessagesFirst;
+    }
+    out.writeln('final fastaAnalyzerErrorCodes = <ErrorCode>[null,');
+    for (var entry in sorted) {
+      List<String> name = nameForEntry(entry);
+      out.writeln('_${name[1]},');
+    }
+    out.writeln('];');
+  }
+
+  void generateErrorCodes() {
+    final sortedErrorCodes = <String>[];
+    final entryMap = <String, Map>{};
+    for (var entry in translatedEntries) {
+      final name = nameForEntry(entry);
+      final errorCode = name[1];
+      sortedErrorCodes.add(errorCode);
+      if (entryMap[errorCode] == null) {
+        entryMap[errorCode] = entry;
+      } else {
+        throw 'Error: Duplicate error code $errorCode';
+      }
+    }
+    sortedErrorCodes.sort();
+    for (var errorCode in sortedErrorCodes) {
+      final entry = entryMap[errorCode];
+      final className = nameForEntry(entry)[0];
+      out.writeln();
+      out.writeln('const $className _$errorCode =');
+      out.writeln('const $className(');
+      out.writeln("'$errorCode',");
+      out.writeln('"${entry['template']}"');
+      final tip = entry['tip'];
+      if (tip is String) {
+        out.writeln(',correction: "$tip"');
+      }
+      out.writeln(');');
+    }
+  }
+
+  void checkForManualChanges() {
+    // Check for ParserErrorCodes that could be removed from
+    // error_converter.dart now that those ParserErrorCodes are auto generated.
+    int converterCount = 0;
+    for (Map entry in translatedEntries) {
+      final name = nameForEntry(entry);
+      final errorCode = name[1];
+      if (errorConverterSource.contains(errorCode)) {
+        if (converterCount == 0) {
+          print('');
+          print('The following ParserErrorCodes could be removed'
+              ' from error_converter.dart:');
+        }
+        print('  $errorCode');
+        ++converterCount;
+      }
+    }
+    if (converterCount > 3) {
+      print('  $converterCount total');
+    }
+
+    // Check that the public ParserErrorCodes have been updated
+    // to reference the generated codes.
+    int publicCount = 0;
+    for (Map entry in translatedEntries) {
+      final name = nameForEntry(entry);
+      final errorCode = name[1];
+      if (!syntacticErrorsSource.contains('_$errorCode')) {
+        if (publicCount == 0) {
+          print('');
+          print('The following ParserErrorCodes should be updated'
+              ' in syntactic_errors.dart');
+          print('to reference the associated generated error code:');
+        }
+        print('  static const ParserErrorCode $errorCode = _$errorCode;');
+        ++publicCount;
+      }
+    }
+
+    // Fail if there are manual changes to be made, but do so
+    // in a fire and forget manner so that the files are still generated.
+    if (converterCount > 0 || publicCount > 0) {
+      print('');
+      throw 'Error: missing manual code changes';
+    }
+  }
+
+  void printSummary() {
+    // Build a map of error message to ParserErrorCode
+    final messageToName = <String, String>{};
+    for (ErrorCode errorCode in errorCodeValues) {
+      if (errorCode is ParserErrorCode) {
+        String message =
+            errorCode.message.replaceAll(new RegExp(r'\{\d+\}'), '');
+        messageToName[message] = errorCode.name;
+      }
+    }
+
+    String messageFromEntryTemplate(Map entry) {
+      String template = entry['template'];
+      String message = template.replaceAll(new RegExp(r'#\w+'), '');
+      return message;
+    }
+
+    // Remove entries that have already been translated
+    for (Map entry in translatedEntries) {
+      messageToName.remove(messageFromEntryTemplate(entry));
+    }
+
+    // Print the # of autogenerated ParserErrorCodes.
+    print('${translatedEntries.length} of ${messageToName.length}'
+        ' ParserErrorCodes generated.');
+
+    // List the ParserErrorCodes that could easily be auto generated
+    // but have not been already.
+    final analyzerToFasta = new Map<String, List<String>>();
+    messagesYaml.forEach((fastaName, entry) {
+      if (entry is Map) {
+        final analyzerName = messageToName[messageFromEntryTemplate(entry)];
+        if (analyzerName != null) {
+          analyzerToFasta
+              .putIfAbsent(analyzerName, () => <String>[])
+              .add(fastaName);
+        }
+      }
+    });
+    if (analyzerToFasta.isNotEmpty) {
+      print('');
+      print('The following ParserErrorCodes could be auto generated:');
+      for (String analyzerName in analyzerToFasta.keys.toList()..sort()) {
+        List<String> fastaNames = analyzerToFasta[analyzerName];
+        if (fastaNames.length == 1) {
+          print('  $analyzerName = ${fastaNames.first}');
+        } else {
+          print('  $analyzerName = $fastaNames');
+        }
+      }
+      if (analyzerToFasta.length > 3) {
+        print('  ${analyzerToFasta.length} total');
+      }
+    }
+  }
+}
+
+/// Return an entry containing 2 strings,
+/// the name of the class containing the error and the name of the error,
+/// or throw an exception if 'analyzerCode:' field is invalid.
+List<String> nameForEntry(Map entry) {
+  final analyzerCode = entry['analyzerCode'];
+  if (analyzerCode is String) {
+    // TODO(danrubel): Revise to handle others such as ScannerErrorCode.
+    if (!analyzerCode.startsWith('ParserErrorCode.')) {
+      throw invalidAnalyzerCode;
+    }
+    List<String> name = analyzerCode.split('.');
+    if (name.length != 2 || name[1].isEmpty) {
+      throw invalidAnalyzerCode;
+    }
+    return name;
+  }
+  throw invalidAnalyzerCode;
+}
+
+const invalidAnalyzerCode = """
+Error: Expected the text in the 'analyzerCode:' field to contain
+       the name of the class containing the error
+       and the name of the error separated by a `.`
+       (e.g. ParserErrorCode.EQUALITY_CANNOT_BE_EQUALITY_OPERAND).
+""";
+
+const shouldRunFastaGenerateMessagesFirst = """
+Error: After modifying message.yaml, run this first:
+       pkg/front_end/tool/fasta generate-messages
+""";
diff --git a/pkg/analyzer/tool/summary/dump_inferred_types.dart b/pkg/analyzer/tool/summary/dump_inferred_types.dart
index e0eec04..a5167b0 100644
--- a/pkg/analyzer/tool/summary/dump_inferred_types.dart
+++ b/pkg/analyzer/tool/summary/dump_inferred_types.dart
@@ -40,7 +40,7 @@
 
   InferredTypeCollector(
       GetDependencyCallback getDependency, GetUnitCallback getUnit)
-      : _linker = new Linker({}, getDependency, getUnit);
+      : _linker = new Linker({}, getDependency, getUnit, null);
 
   /**
    * If an inferred type exists matching the given [slot], record that it is the
diff --git a/pkg/analyzer/tool/summary/mini_ast.dart b/pkg/analyzer/tool/summary/mini_ast.dart
index 518a6c4..4d18427 100644
--- a/pkg/analyzer/tool/summary/mini_ast.dart
+++ b/pkg/analyzer/tool/summary/mini_ast.dart
@@ -181,6 +181,21 @@
   }
 
   @override
+  void handleClassWithClause(Token withKeyword) {
+    debugEvent("ClassWithClause");
+  }
+
+  @override
+  void handleClassNoWithClause() {
+    debugEvent("NoClassWithClause");
+  }
+
+  @override
+  void handleNamedMixinApplicationWithClause(Token withKeyword) {
+    debugEvent("NamedMixinApplicationWithClause");
+  }
+
+  @override
   void handleRecoverClassHeader() {
     pop(); // superclass
   }
diff --git a/pkg/analyzer_cli/lib/src/build_mode.dart b/pkg/analyzer_cli/lib/src/build_mode.dart
index 729ce0d..051a098 100644
--- a/pkg/analyzer_cli/lib/src/build_mode.dart
+++ b/pkg/analyzer_cli/lib/src/build_mode.dart
@@ -425,7 +425,7 @@
         new FileContentOverlay(),
         null,
         sourceFactory,
-        analysisOptions,
+        analysisOptions as AnalysisOptionsImpl,
         externalSummaries: summaryDataStore);
     analysisDriver.declaredVariables =
         new DeclaredVariables.fromMap(options.definedVariables);
diff --git a/pkg/analyzer_fe_comparison/bin/compare_programs.dart b/pkg/analyzer_fe_comparison/bin/compare_programs.dart
new file mode 100644
index 0000000..0118aee
--- /dev/null
+++ b/pkg/analyzer_fe_comparison/bin/compare_programs.dart
@@ -0,0 +1,48 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for 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:analyzer/src/command_line/arguments.dart';
+import 'package:analyzer_fe_comparison/comparison.dart';
+import 'package:args/args.dart';
+import 'package:path/path.dart' as path;
+
+/// Compares the analyzer and front_end behavior when compiling a program.
+main(List<String> args) async {
+  ArgResults options = _parseArgs(args);
+  var sourcePaths = options.rest;
+  if (sourcePaths.length != 1) {
+    throw new StateError('Exactly one source file must be specified.');
+  }
+  var sourcePath = sourcePaths[0];
+  var scriptPath = Platform.script.toFilePath();
+  var sdkRepoPath =
+      path.normalize(path.join(path.dirname(scriptPath), '..', '..', '..'));
+  var buildPath = await _findBuildDir(sdkRepoPath, 'ReleaseX64');
+  var dillPath = path.join(buildPath, 'vm_platform_strong.dill');
+  var packagesFilePath = path.join(sdkRepoPath, '.packages');
+
+  await compareTestPrograms(sourcePath, dillPath, packagesFilePath);
+}
+
+Future<String> _findBuildDir(String sdkRepoPath, String targetName) async {
+  for (var subdirName in ['out', 'xcodebuild']) {
+    var candidatePath = path.join(sdkRepoPath, subdirName, targetName);
+    if (await new Directory(candidatePath).exists()) {
+      return candidatePath;
+    }
+  }
+  throw new StateError('Cannot find build directory');
+}
+
+ArgResults _parseArgs(List<String> args) {
+  var parser = new ArgParser(allowTrailingOptions: true);
+  parser.addOption('dart-sdk', help: 'The path to the Dart SDK.');
+  if (args.contains('--ignore-unrecognized-flags')) {
+    args = filterUnknownArguments(args, parser);
+  }
+  return parser.parse(args);
+}
diff --git a/pkg/analyzer_fe_comparison/bin/compare_sdk_tests b/pkg/analyzer_fe_comparison/bin/compare_sdk_tests
new file mode 100755
index 0000000..b84851f
--- /dev/null
+++ b/pkg/analyzer_fe_comparison/bin/compare_sdk_tests
@@ -0,0 +1,42 @@
+#!/usr/bin/env bash
+# Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE file.
+
+# Run analyzer_fe_comparison on the Dart VM.  This script assumes the Dart
+# repo's directory structure.
+
+function follow_links() {
+  file="$1"
+  while [ -h "$file" ]; do
+    # On Mac OS, readlink -f doesn't work.
+    file="$(readlink "$file")"
+  done
+  echo "$file"
+}
+
+# Unlike $0, $BASH_SOURCE points to the absolute path of this file.
+PROG_NAME="$(follow_links "$BASH_SOURCE")"
+
+# Find directories.
+PKG_BIN_DIR="$(cd "${PROG_NAME%/*}" ; pwd -P)"
+DART_ROOT="$(cd "${PKG_BIN_DIR}/../../.." ; pwd -P)"
+SDK_DIR="${DART_ROOT}/sdk"
+BIN_DIR="${SDK_DIR}/bin"
+
+SDK_ARG="--dart-sdk=$SDK_DIR"
+
+DART="$BIN_DIR/dart"
+
+unset EXTRA_VM_OPTIONS
+declare -a EXTRA_VM_OPTIONS
+
+# We allow extra vm options to be passed in through an environment variable.
+if [[ $DART_VM_OPTIONS ]]; then
+  read -a OPTIONS <<< "$DART_VM_OPTIONS"
+  EXTRA_VM_OPTIONS+=("${OPTIONS[@]}")
+fi
+
+COMPARE_PROGRAMS="$PKG_BIN_DIR/compare_programs.dart"
+
+exec "$DART" "--packages=$DART_ROOT/.packages" "${EXTRA_VM_OPTIONS[@]}" "$COMPARE_PROGRAMS" "$SDK_ARG" "$@"
diff --git a/pkg/analyzer_fe_comparison/lib/comparison.dart b/pkg/analyzer_fe_comparison/lib/comparison.dart
index 03138b7..461c11b 100644
--- a/pkg/analyzer_fe_comparison/lib/comparison.dart
+++ b/pkg/analyzer_fe_comparison/lib/comparison.dart
@@ -2,15 +2,16 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-import 'package:analyzer_fe_comparison/src/analyzer.dart';
+import 'package:analyzer_fe_comparison/src/analyzer.dart' as analyzer;
 import 'package:analyzer_fe_comparison/src/comparison_node.dart';
-import 'package:analyzer_fe_comparison/src/kernel.dart';
+import 'package:analyzer_fe_comparison/src/kernel.dart' as kernel;
+import 'package:path/path.dart' as path;
 
-/// Compares the analyzer and kernel representations of a project, and prints
+/// Compares the analyzer and kernel representations of a package, and prints
 /// the resulting diff.
-void compare(
+void comparePackages(
     String platformPath, String projectLibPath, String packagesFilePath) async {
-  ComparisonNode analyzerNode = await driveAnalyzer(projectLibPath);
+  ComparisonNode analyzerNode = await analyzer.analyzePackage(projectLibPath);
   var packagesFileUri = Uri.file(packagesFilePath);
   var inputs = <Uri>[];
   for (var library in analyzerNode.children) {
@@ -18,6 +19,52 @@
   }
   var platformUri = Uri.file(platformPath);
   ComparisonNode kernelNode =
-      await driveKernel(inputs, packagesFileUri, platformUri);
+      await kernel.analyzePackage(inputs, packagesFileUri, platformUri);
   print(ComparisonNode.diff(kernelNode, analyzerNode));
 }
+
+/// Compares the analyzer and kernel representations of a test file, and prints
+/// the resulting diff.
+///
+/// Only libraries reached by a "file:" URI are compared.
+void compareTestPrograms(
+    String sourcePath, String platformPath, String packagesFilePath) async {
+  var packagesFileUri = Uri.file(packagesFilePath);
+  var platformUri = Uri.file(platformPath);
+  ComparisonNode kernelNode = await kernel.analyzeProgram(
+      path.toUri(sourcePath),
+      packagesFileUri,
+      platformUri,
+      (uri) => uri.scheme == 'file');
+  if (kernelNode.text == 'Error occurred') {
+    // TODO(paulberry): really we should verify that the analyzer detects an
+    // error as well.  But that's not easy to do right now because we use the
+    // front end to chase imports so that we know which files to pass to the
+    // analyzer, and we can't rely on the front end import chasing when an error
+    // occurred.
+    print('No differences found (skipped due to front end compilation error)');
+    return;
+  }
+  String startingPath;
+  var inputs = <String>[];
+  for (var library in kernelNode.children) {
+    var filePath = path.fromUri(Uri.parse(library.text));
+    if (startingPath == null) {
+      startingPath = path.dirname(filePath);
+    } else {
+      while (!path.isWithin(startingPath, filePath)) {
+        startingPath = path.dirname(startingPath);
+      }
+    }
+    inputs.add(filePath);
+  }
+  ComparisonNode analyzerNode =
+      await analyzer.analyzeFiles(startingPath, inputs);
+  var diff = ComparisonNode.diff(kernelNode, analyzerNode);
+  if (diff.children.isEmpty && diff.text.startsWith('=')) {
+    print('No differences found!');
+  } else {
+    print('Differences found:');
+    print(diff);
+  }
+}
diff --git a/pkg/analyzer_fe_comparison/lib/src/analyzer.dart b/pkg/analyzer_fe_comparison/lib/src/analyzer.dart
index 207ede3..e8a8730 100644
--- a/pkg/analyzer_fe_comparison/lib/src/analyzer.dart
+++ b/pkg/analyzer_fe_comparison/lib/src/analyzer.dart
@@ -5,6 +5,9 @@
 import 'dart:async';
 
 import 'package:analyzer/dart/analysis/analysis_context_collection.dart';
+import 'package:analyzer/dart/analysis/context_root.dart';
+import 'package:analyzer/dart/analysis/session.dart';
+import 'package:analyzer/dart/analysis/uri_converter.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/ast/visitor.dart';
 import 'package:analyzer/dart/element/element.dart';
@@ -13,39 +16,76 @@
 import 'package:analyzer/src/generated/source.dart' show SourceKind;
 import 'package:analyzer_fe_comparison/src/comparison_node.dart';
 
-/// Analyzes the project located at [libPath] using the analyzer, and returns a
+/// Analyzes the files in [filePaths] using the analyzer, and returns a
+/// [ComparisonNode] representing them.
+Future<ComparisonNode> analyzeFiles(
+    String startingPath, List<String> filePaths) async {
+  var driver = await _AnalyzerDriver.create(startingPath);
+  return driver.analyzeFiles(filePaths);
+}
+
+/// Analyzes the package located at [libPath] using the analyzer, and returns a
 /// [ComparisonNode] representing it.
-Future<ComparisonNode> driveAnalyzer(String libPath) async {
-  var contextCollection = AnalysisContextCollection(includedPaths: [libPath]);
-  var contexts = contextCollection.contexts;
-  if (contexts.length != 1) {
-    throw new StateError('Expected exactly one context');
-  }
-  var context = contexts[0];
-  var session = context.currentSession;
-  var typeProvider = await session.typeProvider;
-  var uriConverter = session.uriConverter;
-  var contextRoot = context.contextRoot;
-  var libraryNodes = <ComparisonNode>[];
-  for (var filePath in contextRoot.analyzedFiles()) {
-    var kind = await session.getSourceKind(filePath);
-    if (kind == SourceKind.LIBRARY) {
-      var importUri = uriConverter.pathToUri(filePath);
-      var libraryElement = await session.getLibraryByUri(importUri.toString());
-      var childNodes = <ComparisonNode>[];
-      if (libraryElement.name.isNotEmpty) {
-        childNodes.add(ComparisonNode('name=${libraryElement.name}'));
+Future<ComparisonNode> analyzePackage(String libPath) async {
+  var driver = await _AnalyzerDriver.create(libPath);
+  return driver.analyzePackage();
+}
+
+class _AnalyzerDriver {
+  final AnalysisSession _session;
+
+  final TypeProvider _typeProvider;
+
+  final UriConverter _uriConverter;
+
+  final ContextRoot _contextRoot;
+
+  _AnalyzerDriver._(
+      this._session, this._typeProvider, this._uriConverter, this._contextRoot);
+
+  Future<ComparisonNode> analyzeFiles(Iterable<String> filePaths) async {
+    var libraryNodes = <ComparisonNode>[];
+    for (var filePath in filePaths) {
+      var kind = await _session.getSourceKind(filePath);
+      if (kind == SourceKind.LIBRARY) {
+        var importUri = _uriConverter.pathToUri(filePath);
+        var libraryElement =
+            await _session.getLibraryByUri(importUri.toString());
+        var childNodes = <ComparisonNode>[];
+        if (libraryElement.name.isNotEmpty) {
+          childNodes.add(ComparisonNode('name=${libraryElement.name}'));
+        }
+        for (var compilationUnit in libraryElement.units) {
+          var unitResult =
+              await _session.getResolvedAst(compilationUnit.source.fullName);
+          _AnalyzerVisitor(_typeProvider, childNodes)
+              ._visitList(unitResult.unit.declarations);
+        }
+        libraryNodes
+            .add(ComparisonNode.sorted(importUri.toString(), childNodes));
       }
-      for (var compilationUnit in libraryElement.units) {
-        var unitResult =
-            await session.getResolvedAst(compilationUnit.source.fullName);
-        _AnalyzerVisitor(typeProvider, childNodes)
-            ._visitList(unitResult.unit.declarations);
-      }
-      libraryNodes.add(ComparisonNode.sorted(importUri.toString(), childNodes));
     }
+    return ComparisonNode.sorted('Component', libraryNodes);
   }
-  return ComparisonNode.sorted('Component', libraryNodes);
+
+  Future<ComparisonNode> analyzePackage() async {
+    return analyzeFiles(_contextRoot.analyzedFiles());
+  }
+
+  static Future<_AnalyzerDriver> create(String startingPath) async {
+    var contextCollection =
+        AnalysisContextCollection(includedPaths: [startingPath]);
+    var contexts = contextCollection.contexts;
+    if (contexts.length != 1) {
+      throw new StateError('Expected exactly one context');
+    }
+    var context = contexts[0];
+    var session = context.currentSession;
+    var typeProvider = await session.typeProvider;
+    var uriConverter = session.uriConverter;
+    var contextRoot = context.contextRoot;
+    return _AnalyzerDriver._(session, typeProvider, uriConverter, contextRoot);
+  }
 }
 
 /// Visitor for serializing the contents of an analyzer AST into
@@ -63,24 +103,22 @@
   void visitClassDeclaration(ClassDeclaration node) {
     var children = <ComparisonNode>[];
     var visitor = _AnalyzerVisitor(_typeProvider, children);
-    visitor._visitTypeParameters(node.declaredElement.typeParameters);
-    if (node.declaredElement.supertype != null) {
-      children.add(_translateType('Extends: ', node.declaredElement.supertype));
-    }
-    for (int i = 0; i < node.declaredElement.mixins.length; i++) {
-      children
-          .add(_translateType('Mixin $i: ', node.declaredElement.mixins[i]));
-    }
-    for (int i = 0; i < node.declaredElement.interfaces.length; i++) {
-      children.add(_translateType(
-          'Implements $i: ', node.declaredElement.interfaces[i]));
-    }
+    visitor._handleClassOrClassTypeAlias(node.declaredElement);
     visitor._visitList(node.members);
     _resultNodes
         .add(ComparisonNode.sorted('Class ${node.name.name}', children));
   }
 
   @override
+  void visitClassTypeAlias(ClassTypeAlias node) {
+    var children = <ComparisonNode>[];
+    var visitor = _AnalyzerVisitor(_typeProvider, children);
+    visitor._handleClassOrClassTypeAlias(node.declaredElement);
+    _resultNodes.add(
+        ComparisonNode.sorted('MixinApplication ${node.name.name}', children));
+  }
+
+  @override
   void visitConstructorDeclaration(ConstructorDeclaration node) {
     var children = <ComparisonNode>[];
     var visitor = _AnalyzerVisitor(_typeProvider, children);
@@ -136,6 +174,7 @@
 
   @override
   void visitMethodDeclaration(MethodDeclaration node) {
+    var name = node.name.name;
     String kind;
     if (node.isGetter) {
       kind = 'Getter';
@@ -143,6 +182,9 @@
       kind = 'Setter';
     } else if (node.isOperator) {
       kind = 'Operator';
+      if (name == '-' && node.declaredElement.parameters.isEmpty) {
+        name = 'unary-';
+      }
     } else {
       kind = 'Method';
     }
@@ -152,8 +194,19 @@
     visitor._visitParameters(node.parameters);
     children
         .add(_translateType('Return type: ', node.declaredElement.returnType));
+    _resultNodes.add(ComparisonNode.sorted('$kind $name', children));
+  }
+
+  @override
+  void visitMixinDeclaration(MixinDeclaration node) {
+    // At present, kernel doesn't distinguish between mixin and class
+    // declarations.  So treat the mixin as a class.
+    var children = <ComparisonNode>[];
+    var visitor = _AnalyzerVisitor(_typeProvider, children);
+    visitor._handleClassOrClassTypeAlias(node.declaredElement);
+    visitor._visitList(node.members);
     _resultNodes
-        .add(ComparisonNode.sorted('$kind ${node.name.name}', children));
+        .add(ComparisonNode.sorted('Class ${node.name.name}', children));
   }
 
   @override
@@ -178,6 +231,40 @@
     }
   }
 
+  void _handleClassOrClassTypeAlias(ClassElement element) {
+    _visitTypeParameters(element.typeParameters);
+    InterfaceType supertype;
+    List<InterfaceType> mixins;
+    if (element.isMixin) {
+      // Kernel represents:
+      // - `mixin M` as `class M extends Object`
+      // - `mixin M on A` as `class M extends A`
+      // - `mixin M on A, B` as `class M extends A with B`
+      // - `mixin M on A, B, C` as `class M extends A with B, C`.
+      var superclassConstraints = element.superclassConstraints;
+      if (superclassConstraints.isEmpty) {
+        supertype = _typeProvider.objectType;
+        mixins = [];
+      } else {
+        supertype = superclassConstraints[0];
+        mixins = superclassConstraints.skip(1).toList();
+      }
+    } else {
+      supertype = element.supertype;
+      mixins = element.mixins;
+    }
+    if (supertype != null) {
+      _resultNodes.add(_translateType('Extends: ', supertype));
+    }
+    for (int i = 0; i < mixins.length; i++) {
+      _resultNodes.add(_translateType('Mixin $i: ', mixins[i]));
+    }
+    for (int i = 0; i < element.interfaces.length; i++) {
+      _resultNodes
+          .add(_translateType('Implements $i: ', element.interfaces[i]));
+    }
+  }
+
   /// Converts the analyzer representation of a type into a ComparisonNode.
   ComparisonNode _translateType(String prefix, DartType type) {
     if (type is InterfaceType) {
diff --git a/pkg/analyzer_fe_comparison/lib/src/kernel.dart b/pkg/analyzer_fe_comparison/lib/src/kernel.dart
index 935dd2c..561f5e6 100644
--- a/pkg/analyzer_fe_comparison/lib/src/kernel.dart
+++ b/pkg/analyzer_fe_comparison/lib/src/kernel.dart
@@ -13,22 +13,17 @@
 
 /// Compiles the given [inputs] to kernel using the front_end, and returns a
 /// [ComparisonNode] representing them.
-Future<ComparisonNode> driveKernel(
+Future<ComparisonNode> analyzePackage(
     List<Uri> inputs, Uri packagesFileUri, Uri platformUri) async {
-  var targetFlags = TargetFlags(strongMode: true, syncAsync: true);
-  var target = NoneTarget(targetFlags);
-  var fileSystem = StandardFileSystem.instance;
-
-  var compilerOptions = CompilerOptions()
-    ..fileSystem = fileSystem
-    ..packagesFileUri = packagesFileUri
-    ..sdkSummary = platformUri
-    ..strongMode = true
-    ..target = target
-    ..throwOnErrorsForDebugging = true
-    ..embedSourceText = false;
-
-  var component = await kernelForComponent(inputs, compilerOptions);
+  bool errorOccurred = false;
+  var component = await kernelForComponent(
+      inputs,
+      _makeCompilerOptions(packagesFileUri, platformUri, (_) {
+        errorOccurred = true;
+      }));
+  if (errorOccurred) {
+    return ComparisonNode('Error occurred');
+  }
   var libraryNodes = <ComparisonNode>[];
   var visitor = _KernelVisitor(libraryNodes);
   for (var library in component.libraries) {
@@ -39,6 +34,48 @@
   return ComparisonNode.sorted('Component', libraryNodes);
 }
 
+/// Compiles the given [input] to kernel using the front_end, and returns a
+/// [ComparisonNode] representing it.
+///
+/// Only libraries whose URI passes the [uriFilter] are included in the results.
+Future<ComparisonNode> analyzeProgram(Uri input, Uri packagesFileUri,
+    Uri platformUri, bool uriFilter(Uri uri)) async {
+  var errorOccurred = false;
+  var component = await kernelForProgram(
+      input,
+      _makeCompilerOptions(packagesFileUri, platformUri, (_) {
+        errorOccurred = true;
+      }));
+  if (errorOccurred) {
+    return ComparisonNode('Error occurred');
+  }
+  var libraryNodes = <ComparisonNode>[];
+  var visitor = _KernelVisitor(libraryNodes);
+  for (var library in component.libraries) {
+    if (uriFilter(library.importUri)) {
+      library.accept(visitor);
+    }
+  }
+  return ComparisonNode.sorted('Component', libraryNodes);
+}
+
+CompilerOptions _makeCompilerOptions(
+    Uri packagesFileUri, Uri platformUri, ErrorHandler onError) {
+  var targetFlags = TargetFlags(strongMode: true, syncAsync: true);
+  var target = NoneTarget(targetFlags);
+  var fileSystem = StandardFileSystem.instance;
+
+  return CompilerOptions()
+    ..fileSystem = fileSystem
+    ..packagesFileUri = packagesFileUri
+    ..sdkSummary = platformUri
+    ..strongMode = true
+    ..target = target
+    ..throwOnErrorsForDebugging = false
+    ..embedSourceText = false
+    ..onError = onError;
+}
+
 /// Visitor for serializing a kernel representation of a program into
 /// ComparisonNodes.
 ///
@@ -56,7 +93,9 @@
   @override
   void visitClass(Class class_) {
     if (class_.isAnonymousMixin) return null;
-    var kind = class_.isEnum ? 'Enum' : 'Class';
+    var kind = class_.isEnum
+        ? 'Enum'
+        : class_.isMixinApplication ? 'MixinApplication' : 'Class';
     var children = <ComparisonNode>[];
     var visitor = _KernelVisitor(children);
     if (class_.isEnum) {
@@ -71,6 +110,9 @@
       if (class_.supertype != null) {
         var declaredSupertype = class_.supertype.asInterfaceType;
         var mixedInTypes = <DartType>[];
+        if (class_.isMixinApplication) {
+          mixedInTypes.add(class_.mixedInType.asInterfaceType);
+        }
         while (declaredSupertype.classNode.isAnonymousMixin) {
           // Since we're walking from the class to its declared supertype, we
           // encounter the mixins in the reverse order that they were declared,
@@ -114,6 +156,7 @@
   @override
   void visitField(Field field) {
     if (field.name.name == '_redirecting#') return null;
+    if (field.name.name == '_exports#') return null;
     var children = <ComparisonNode>[];
     children.add(_TypeVisitor.translate('Type: ', field.type));
     // TODO(paulberry): handle more fields from Field
@@ -160,7 +203,14 @@
 
   @override
   void visitProcedure(Procedure procedure) {
-    if (procedure.isForwardingStub) return null;
+    if (procedure.isSyntheticForwarder) {
+      return null;
+    }
+    if (procedure.name.name.startsWith('__loadLibrary_')) {
+      // Sometimes the front end generates procedures with this name that don't
+      // correspond to anything in the source file.  Ignore them.
+      return null;
+    }
     // TODO(paulberry): add an annotation to the ComparisonNode when the
     // procedure is a factory.
     var kind = procedure.isFactory
@@ -241,8 +291,8 @@
           .add(translate('$kind parameter $i: ', node.positionalParameters[i]));
     }
     for (var namedType in node.namedParameters) {
-      children
-          .add(translate('Named parameter ${namedType.name}', namedType.type));
+      children.add(
+          translate('Named parameter ${namedType.name}: ', namedType.type));
     }
     return ComparisonNode.sorted('${_prefix}FunctionType', children);
   }
diff --git a/pkg/analyzer_fe_comparison/tool/compare_packages.dart b/pkg/analyzer_fe_comparison/tool/compare_packages.dart
index efb0efe..e1a7b71 100644
--- a/pkg/analyzer_fe_comparison/tool/compare_packages.dart
+++ b/pkg/analyzer_fe_comparison/tool/compare_packages.dart
@@ -19,7 +19,7 @@
   var dillPath = path.join(buildPath, 'vm_platform_strong.dill');
   var analyzerLibPath = path.join(sdkRepoPath, 'pkg', 'analyzer', 'lib');
   var packagesFilePath = path.join(sdkRepoPath, '.packages');
-  compare(dillPath, analyzerLibPath, packagesFilePath);
+  comparePackages(dillPath, analyzerLibPath, packagesFilePath);
 }
 
 Future<String> _findBuildDir(String sdkRepoPath, String targetName) async {
diff --git a/pkg/analyzer_plugin/lib/src/utilities/change_builder/change_builder_dart.dart b/pkg/analyzer_plugin/lib/src/utilities/change_builder/change_builder_dart.dart
index 991fe82..682aac9 100644
--- a/pkg/analyzer_plugin/lib/src/utilities/change_builder/change_builder_dart.dart
+++ b/pkg/analyzer_plugin/lib/src/utilities/change_builder/change_builder_dart.dart
@@ -150,6 +150,8 @@
       write(' extends ');
       writeType(superclass, groupName: superclassGroupName);
     } else if (mixins != null && mixins.isNotEmpty) {
+      // TODO(brianwilkerson) Remove this branch when 2.1 semantics are
+      // supported everywhere.
       write(' extends Object ');
     }
     writeTypes(mixins, prefix: ' with ');
@@ -363,6 +365,29 @@
   }
 
   @override
+  void writeMixinDeclaration(String name,
+      {Iterable<DartType> interfaces,
+      void membersWriter(),
+      String nameGroupName,
+      Iterable<DartType> superclassConstraints}) {
+    // TODO(brianwilkerson) Add support for type parameters, probably as a
+    // parameterWriter parameter.
+    write('mixin ');
+    if (nameGroupName == null) {
+      write(name);
+    } else {
+      addSimpleLinkedEdit(nameGroupName, name);
+    }
+    writeTypes(superclassConstraints, prefix: ' on ');
+    writeTypes(interfaces, prefix: ' implements ');
+    writeln(' {');
+    if (membersWriter != null) {
+      membersWriter();
+    }
+    write('}');
+  }
+
+  @override
   void writeOverrideOfInheritedMember(ExecutableElement member,
       {StringBuffer displayTextBuffer, String returnTypeGroupName}) {
     void withCarbonCopyBuffer(f()) {
@@ -673,11 +698,7 @@
     }
   }
 
-  /**
-   * Write the code for a comma-separated list of [types], optionally prefixed
-   * by a [prefix]. If the list of [types] is `null` or does not contain any
-   * types, then nothing will be written.
-   */
+  @override
   void writeTypes(Iterable<DartType> types, {String prefix}) {
     if (types == null || types.isEmpty) {
       return;
diff --git a/pkg/analyzer_plugin/lib/src/utilities/completion/optype.dart b/pkg/analyzer_plugin/lib/src/utilities/completion/optype.dart
index 4989a68..f59b1d8 100644
--- a/pkg/analyzer_plugin/lib/src/utilities/completion/optype.dart
+++ b/pkg/analyzer_plugin/lib/src/utilities/completion/optype.dart
@@ -540,6 +540,7 @@
   void visitExtendsClause(ExtendsClause node) {
     if (identical(entity, node.superclass)) {
       optype.includeTypeNameSuggestions = true;
+      optype.typeNameSuggestionsFilter = _nonMixinClasses;
     }
   }
 
@@ -810,6 +811,11 @@
   }
 
   @override
+  void visitOnClause(OnClause node) {
+    optype.includeTypeNameSuggestions = true;
+  }
+
+  @override
   void visitParenthesizedExpression(ParenthesizedExpression node) {
     if (identical(entity, node.expression)) {
       optype.includeReturnValueSuggestions = true;
@@ -1031,4 +1037,18 @@
     }
     return false;
   }
+
+  /**
+   * A filter used to disable everything except classes (such as functions and
+   * mixins).
+   */
+  int _nonMixinClasses(DartType type, int relevance) {
+    if (type is InterfaceType) {
+      if (type.element.isMixin) {
+        return null;
+      }
+      return relevance;
+    }
+    return null;
+  }
 }
diff --git a/pkg/analyzer_plugin/lib/utilities/change_builder/change_builder_dart.dart b/pkg/analyzer_plugin/lib/utilities/change_builder/change_builder_dart.dart
index d6e0b8e..25b5c44 100644
--- a/pkg/analyzer_plugin/lib/utilities/change_builder/change_builder_dart.dart
+++ b/pkg/analyzer_plugin/lib/utilities/change_builder/change_builder_dart.dart
@@ -190,6 +190,19 @@
       String typeGroupName});
 
   /**
+   * Write the code for a declaration of a mixin with the given [name]. If a
+   * list of [interfaces] is provided, then the mixin will implement those
+   * interfaces. If a [membersWriter] is provided, then it will be invoked to
+   * allow members to be generated. If a [nameGroupName] is provided, then the
+   * name of the class will be included in the linked edit group with that name.
+   */
+  void writeMixinDeclaration(String name,
+      {Iterable<DartType> interfaces,
+      void membersWriter(),
+      String nameGroupName,
+      Iterable<DartType> superclassConstraints});
+
+  /**
    * Append a placeholder for an override of the specified inherited [member].
    * If provided, write a string value suitable for display (e.g., in a
    * completion popup) in the given [displayTextBuffer].
@@ -288,6 +301,13 @@
    */
   void writeTypeParameters(List<TypeParameterElement> typeParameters,
       {ExecutableElement methodBeingCopied});
+
+  /**
+   * Write the code for a comma-separated list of [types], optionally prefixed
+   * by a [prefix]. If the list of [types] is `null` or does not contain any
+   * types, then nothing will be written.
+   */
+  void writeTypes(Iterable<DartType> types, {String prefix});
 }
 
 /**
diff --git a/pkg/analyzer_plugin/test/src/utilities/change_builder/change_builder_dart_test.dart b/pkg/analyzer_plugin/test/src/utilities/change_builder/change_builder_dart_test.dart
index 15f5b60..7f0f6e9 100644
--- a/pkg/analyzer_plugin/test/src/utilities/change_builder/change_builder_dart_test.dart
+++ b/pkg/analyzer_plugin/test/src/utilities/change_builder/change_builder_dart_test.dart
@@ -1088,6 +1088,96 @@
     expect(group.positions, hasLength(1));
   }
 
+  test_writeMixinDeclaration_interfaces() async {
+    String path = provider.convertPath('/test.dart');
+    addSource(path, 'class A {}');
+    DartType typeA = await _getType(path, 'A');
+
+    DartChangeBuilderImpl builder = new DartChangeBuilder(session);
+    await builder.addFileEdit(path, (FileEditBuilder builder) {
+      builder.addInsertion(0, (EditBuilder builder) {
+        (builder as DartEditBuilder)
+            .writeMixinDeclaration('M', interfaces: [typeA]);
+      });
+    });
+    SourceEdit edit = getEdit(builder);
+    expect(
+        edit.replacement, equalsIgnoringWhitespace('mixin M implements A { }'));
+  }
+
+  test_writeMixinDeclaration_interfacesAndSuperclassConstraints() async {
+    String path = provider.convertPath('/test.dart');
+    addSource(path, 'class A {} class B {}');
+    DartType typeA = await _getType(path, 'A');
+    DartType typeB = await _getType(path, 'B');
+
+    DartChangeBuilderImpl builder = new DartChangeBuilder(session);
+    await builder.addFileEdit(path, (FileEditBuilder builder) {
+      builder.addInsertion(0, (EditBuilder builder) {
+        (builder as DartEditBuilder).writeMixinDeclaration('M',
+            interfaces: [typeA], superclassConstraints: [typeB]);
+      });
+    });
+    SourceEdit edit = getEdit(builder);
+    expect(edit.replacement,
+        equalsIgnoringWhitespace('mixin M on B implements A { }'));
+  }
+
+  test_writeMixinDeclaration_memberWriter() async {
+    String path = provider.convertPath('/test.dart');
+    addSource(path, '');
+
+    DartChangeBuilderImpl builder = new DartChangeBuilder(session);
+    await builder.addFileEdit(path, (FileEditBuilder builder) {
+      builder.addInsertion(0, (EditBuilder builder) {
+        (builder as DartEditBuilder).writeMixinDeclaration('M',
+            membersWriter: () {
+          builder.write('/**/');
+        });
+      });
+    });
+    SourceEdit edit = getEdit(builder);
+    expect(edit.replacement, equalsIgnoringWhitespace('mixin M { /**/}'));
+  }
+
+  test_writeMixinDeclaration_nameGroupName() async {
+    String path = provider.convertPath('/test.dart');
+    addSource(path, '');
+
+    DartChangeBuilderImpl builder = new DartChangeBuilder(session);
+    await builder.addFileEdit(path, (FileEditBuilder builder) {
+      builder.addInsertion(0, (EditBuilder builder) {
+        (builder as DartEditBuilder)
+            .writeMixinDeclaration('M', nameGroupName: 'name');
+      });
+    });
+    SourceEdit edit = getEdit(builder);
+    expect(edit.replacement, equalsIgnoringWhitespace('mixin M { }'));
+
+    List<LinkedEditGroup> linkedEditGroups =
+        builder.sourceChange.linkedEditGroups;
+    expect(linkedEditGroups, hasLength(1));
+    LinkedEditGroup group = linkedEditGroups[0];
+    expect(group.length, 1);
+    expect(group.positions, hasLength(1));
+  }
+
+  test_writeMixinDeclaration_superclassConstraints() async {
+    String path = provider.convertPath('/test.dart');
+    addSource(path, 'class A {}');
+    DartType typeA = await _getType(path, 'A');
+
+    DartChangeBuilderImpl builder = new DartChangeBuilder(session);
+    await builder.addFileEdit(path, (FileEditBuilder builder) {
+      builder.addInsertion(0, (EditBuilder builder) {
+        (builder as DartEditBuilder)
+            .writeMixinDeclaration('M', superclassConstraints: [typeA]);
+      });
+    });
+    SourceEdit edit = getEdit(builder);
+    expect(edit.replacement, equalsIgnoringWhitespace('mixin M on A { }'));
+  }
+
   test_writeOverrideOfInheritedMember_getter_abstract() async {
     await _assertWriteOverrideOfInheritedAccessor('''
 abstract class A {
diff --git a/pkg/analyzer_plugin/test/src/utilities/completion/optype_test.dart b/pkg/analyzer_plugin/test/src/utilities/completion/optype_test.dart
index ab9bcce..1b49426 100644
--- a/pkg/analyzer_plugin/test/src/utilities/completion/optype_test.dart
+++ b/pkg/analyzer_plugin/test/src/utilities/completion/optype_test.dart
@@ -1706,6 +1706,12 @@
     await assertOpType(typeNames: true);
   }
 
+  test_OnClause() async {
+    // OnClause  MixinDeclaration
+    addTestSource('mixin M on ^\n{}');
+    await assertOpType(typeNames: true);
+  }
+
   test_PropertyAccess_noTarget() async {
     // SimpleIdentifier  PropertyAccess  ExpressionStatement
     addTestSource('main() {.^}');
diff --git a/pkg/compiler/lib/src/common.dart b/pkg/compiler/lib/src/common.dart
index af13e36..0a4b1d5 100644
--- a/pkg/compiler/lib/src/common.dart
+++ b/pkg/compiler/lib/src/common.dart
@@ -18,3 +18,5 @@
         Spannable,
         SpannableAssertionFailure;
 export 'helpers/helpers.dart';
+
+bool retainDataForTesting = false;
diff --git a/pkg/compiler/lib/src/common/tasks.dart b/pkg/compiler/lib/src/common/tasks.dart
index 1da17a1..9f3ce1e5 100644
--- a/pkg/compiler/lib/src/common/tasks.dart
+++ b/pkg/compiler/lib/src/common/tasks.dart
@@ -156,7 +156,7 @@
   /// Note: we assume that this method is used only by the compiler input
   /// provider, but it could be used by other tasks as long as the input
   /// provider will not be called by those tasks.
-  measureIo(Future action()) {
+  Future<T> measureIo<T>(Future<T> action()) {
     if (_isDisabled) return action();
 
     if (measurer.currentAsyncTask == null) {
@@ -174,7 +174,7 @@
 
   /// Measure the time spent in [action] (if in verbose mode) and accumulate it
   /// under a subtask with the given name.
-  measureSubtask(String name, action()) {
+  T measureSubtask<T>(String name, T action()) {
     if (_isDisabled) return action();
 
     // Use a nested CompilerTask for the measurement to ensure nested [measure]
diff --git a/pkg/compiler/lib/src/common_elements.dart b/pkg/compiler/lib/src/common_elements.dart
index 663d010..a16065a 100644
--- a/pkg/compiler/lib/src/common_elements.dart
+++ b/pkg/compiler/lib/src/common_elements.dart
@@ -1098,9 +1098,10 @@
   FunctionEntity get convertRtiToRuntimeType =>
       _findHelperFunction('convertRtiToRuntimeType');
 
-  FunctionEntity _extractTypeArguments;
-  FunctionEntity get extractTypeArguments => _extractTypeArguments ??=
-      _findLibraryMember(internalLibrary, 'extractTypeArguments');
+  bool isExtractTypeArguments(FunctionEntity member) {
+    return member.name == 'extractTypeArguments' &&
+        member.library == internalLibrary;
+  }
 
   FunctionEntity get toStringForNativeObject =>
       _findHelperFunction('toStringForNativeObject');
@@ -1480,6 +1481,10 @@
   /// Returns `true` if [cls] is an unnamed mixin application.
   bool isUnnamedMixinApplication(ClassEntity cls);
 
+  /// Returns `true` if [cls] is a mixin application that mixes in methods with
+  /// super calls.
+  bool isSuperMixinApplication(ClassEntity cls);
+
   /// Returns the 'effective' mixin class if [cls] is a mixin application, and
   /// `null` otherwise.
   ///
diff --git a/pkg/compiler/lib/src/compiler.dart b/pkg/compiler/lib/src/compiler.dart
index 3d5e817..0ad98b3 100644
--- a/pkg/compiler/lib/src/compiler.dart
+++ b/pkg/compiler/lib/src/compiler.dart
@@ -10,8 +10,7 @@
 
 import '../compiler_new.dart' as api;
 import 'backend_strategy.dart';
-import 'common/names.dart' show Selectors;
-import 'common/names.dart' show Uris;
+import 'common/names.dart' show Selectors, Uris;
 import 'common/tasks.dart' show CompilerTask, GenericTask, Measurer;
 import 'common/work.dart' show WorkItem;
 import 'common.dart';
@@ -30,7 +29,7 @@
 import 'io/source_information.dart' show SourceInformation;
 import 'js_backend/backend.dart' show JavaScriptBackend;
 import 'js_backend/inferred_data.dart';
-import 'kernel/kernel_backend_strategy.dart';
+import 'js_model/js_strategy.dart';
 import 'kernel/kernel_strategy.dart';
 import 'library_loader.dart' show LibraryLoaderTask, LoadedLibraries;
 import 'null_compiler_output.dart' show NullCompilerOutput, NullSink;
@@ -153,7 +152,7 @@
     kernelFrontEndTask = new GenericTask('Front end', measurer);
     frontendStrategy = new KernelFrontEndStrategy(
         kernelFrontEndTask, options, reporter, environment);
-    backendStrategy = new KernelBackendStrategy(this);
+    backendStrategy = new JsBackendStrategy(this);
     _impactCache = <Entity, WorldImpact>{};
     _impactCacheDeleter = new _MapImpactCacheDeleter(_impactCache);
 
@@ -227,10 +226,7 @@
   /// have been computed.
   ///
   /// [loadedLibraries] contains the newly loaded libraries.
-  ///
-  /// The method returns a [Future] allowing for the loading of additional
-  /// libraries.
-  LoadedLibraries processLoadedLibraries(LoadedLibraries loadedLibraries) {
+  void processLoadedLibraries(LoadedLibraries loadedLibraries) {
     frontendStrategy.registerLoadedLibraries(loadedLibraries);
     loadedLibraries.forEachLibrary((Uri uri) {
       LibraryEntity library =
@@ -247,7 +243,6 @@
           MessageKind.MIRRORS_LIBRARY_NOT_SUPPORT_WITH_CFE);
     }
     backend.onLibrariesLoaded(frontendStrategy.commonElements, loadedLibraries);
-    return loadedLibraries;
   }
 
   Future runInternal(Uri uri) async {
@@ -272,6 +267,9 @@
     // Note: libraries may be null because of errors trying to find files or
     // parse-time errors (when using `package:front_end` as a loader).
     if (loadedLibraries == null) return;
+    if (compilationFailed && !options.generateCodeWithCompileTimeErrors) {
+      return;
+    }
     _mainLibraryUri = loadedLibraries.rootLibraryUri;
     processLoadedLibraries(loadedLibraries);
     compileLoadedLibraries(loadedLibraries);
@@ -295,6 +293,15 @@
 
   JClosedWorld computeClosedWorld(LoadedLibraries loadedLibraries) {
     ResolutionEnqueuer resolutionEnqueuer = startResolution();
+    for (LibraryEntity library
+        in frontendStrategy.elementEnvironment.libraries) {
+      frontendStrategy.elementEnvironment.forEachClass(library,
+          (ClassEntity cls) {
+        // Register all classes eagerly to optimize closed world computation in
+        // `ClassWorldBuilder.isInheritedInSubtypeOf`.
+        resolutionEnqueuer.worldBuilder.registerClass(cls);
+      });
+    }
     WorldImpactBuilderImpl mainImpact = new WorldImpactBuilderImpl();
     FunctionEntity mainFunction = frontendStrategy.computeMain(mainImpact);
 
@@ -311,8 +318,8 @@
     resolutionEnqueuer.applyImpact(mainImpact);
     reporter.log('Resolving...');
 
-    processQueue(frontendStrategy.elementEnvironment, resolutionEnqueuer,
-        mainFunction, loadedLibraries.libraries,
+    processQueue(
+        frontendStrategy.elementEnvironment, resolutionEnqueuer, mainFunction,
         onProgress: showResolutionProgress);
     backend.onResolutionEnd();
     resolutionEnqueuer.logSummary(reporter.log);
@@ -330,9 +337,12 @@
     }
 
     assert(mainFunction != null);
+    checkQueue(resolutionEnqueuer);
 
     JClosedWorld closedWorld = closeResolution(mainFunction);
-    backendClosedWorldForTesting = closedWorld;
+    if (retainDataForTesting) {
+      backendClosedWorldForTesting = closedWorld;
+    }
     return closedWorld;
   }
 
@@ -340,16 +350,15 @@
       JClosedWorld closedWorld) {
     FunctionEntity mainFunction = closedWorld.elementEnvironment.mainFunction;
     reporter.log('Inferring types...');
-    InferredDataBuilder inferredDataBuilder = new InferredDataBuilderImpl();
-    backend.processAnnotations(closedWorld, inferredDataBuilder);
+    InferredDataBuilder inferredDataBuilder =
+        new InferredDataBuilderImpl(closedWorld.annotationsData);
     return globalInference.runGlobalTypeInference(
         mainFunction, closedWorld, inferredDataBuilder);
   }
 
-  Enqueuer generateJavaScriptCode(
-      LoadedLibraries loadedLibraries,
-      JClosedWorld closedWorld,
+  void generateJavaScriptCode(
       GlobalTypeInferenceResults globalInferenceResults) {
+    JClosedWorld closedWorld = globalInferenceResults.closedWorld;
     FunctionEntity mainFunction = closedWorld.elementEnvironment.mainFunction;
     reporter.log('Compiling...');
     phase = PHASE_COMPILING;
@@ -357,7 +366,6 @@
     Enqueuer codegenEnqueuer =
         startCodegen(closedWorld, globalInferenceResults);
     processQueue(closedWorld.elementEnvironment, codegenEnqueuer, mainFunction,
-        loadedLibraries.libraries,
         onProgress: showCodegenProgress);
     codegenEnqueuer.logSummary(reporter.log);
 
@@ -371,22 +379,21 @@
 
     backend.onCodegenEnd();
 
-    return codegenEnqueuer;
+    checkQueue(codegenEnqueuer);
   }
 
   /// Performs the compilation when all libraries have been loaded.
-  void compileLoadedLibraries(LoadedLibraries loadedLibraries) =>
-      selfTask.measureSubtask("Compiler.compileLoadedLibraries", () {
-        JClosedWorld closedWorld = computeClosedWorld(loadedLibraries);
-        if (closedWorld != null) {
-          GlobalTypeInferenceResults globalInferenceResults =
-              performGlobalTypeInference(closedWorld);
-          if (stopAfterTypeInference) return;
-          Enqueuer codegenEnqueuer = generateJavaScriptCode(
-              loadedLibraries, closedWorld, globalInferenceResults);
-          checkQueues(enqueuer.resolution, codegenEnqueuer);
-        }
-      });
+  void compileLoadedLibraries(LoadedLibraries loadedLibraries) {
+    selfTask.measureSubtask("Compiler.compileLoadedLibraries", () {
+      JClosedWorld closedWorld = computeClosedWorld(loadedLibraries);
+      if (closedWorld != null) {
+        GlobalTypeInferenceResults globalInferenceResults =
+            performGlobalTypeInference(closedWorld);
+        if (stopAfterTypeInference) return;
+        generateJavaScriptCode(globalInferenceResults);
+      }
+    });
+  }
 
   Enqueuer startCodegen(JClosedWorld closedWorld,
       GlobalTypeInferenceResults globalInferenceResults) {
@@ -402,7 +409,7 @@
   JClosedWorld closeResolution(FunctionEntity mainFunction) {
     phase = PHASE_DONE_RESOLVING;
 
-    KClosedWorld closedWorld = resolutionWorldBuilder.closeWorld();
+    KClosedWorld closedWorld = resolutionWorldBuilder.closeWorld(reporter);
     OutputUnitData result = deferredLoadTask.run(mainFunction, closedWorld);
     JClosedWorld closedWorldRefiner =
         backendStrategy.createJClosedWorld(closedWorld);
@@ -433,10 +440,14 @@
   }
 
   void processQueue(ElementEnvironment elementEnvironment, Enqueuer enqueuer,
-      FunctionEntity mainMethod, Iterable<Uri> libraries,
+      FunctionEntity mainMethod,
       {void onProgress(Enqueuer enqueuer)}) {
     selfTask.measureSubtask("Compiler.processQueue", () {
-      enqueuer.open(impactStrategy, mainMethod, libraries);
+      enqueuer.open(
+          impactStrategy,
+          mainMethod,
+          elementEnvironment.libraries
+              .map((LibraryEntity library) => library.canonicalUri));
       progress.startPhase();
       emptyQueue(enqueuer, onProgress: onProgress);
       enqueuer.queueIsClosed = true;
@@ -449,16 +460,11 @@
     });
   }
 
-  /**
-   * Perform various checks of the queues. This includes checking that
-   * the queues are empty (nothing was added after we stopped
-   * processing the queues). Also compute the number of methods that
-   * were resolved, but not compiled (aka excess resolution).
-   */
-  checkQueues(Enqueuer resolutionEnqueuer, Enqueuer codegenEnqueuer) {
-    for (Enqueuer enqueuer in [resolutionEnqueuer, codegenEnqueuer]) {
-      enqueuer.checkQueueIsEmpty();
-    }
+  /// Perform various checks of the queue. This includes checking that the
+  /// queues are empty (nothing was added after we stopped processing the
+  /// queues).
+  checkQueue(Enqueuer enqueuer) {
+    enqueuer.checkQueueIsEmpty();
   }
 
   void showResolutionProgress(Enqueuer enqueuer) {
@@ -917,15 +923,13 @@
   final Map<Entity, WorldImpact> _impactCache;
   _MapImpactCacheDeleter(this._impactCache);
 
-  bool retainCachesForTesting = false;
-
   void uncacheWorldImpact(Entity element) {
-    if (retainCachesForTesting) return;
+    if (retainDataForTesting) return;
     _impactCache.remove(element);
   }
 
   void emptyCache() {
-    if (retainCachesForTesting) return;
+    if (retainDataForTesting) return;
     _impactCache.clear();
   }
 }
diff --git a/pkg/compiler/lib/src/dump_info.dart b/pkg/compiler/lib/src/dump_info.dart
index 64423bf..e6f6948 100644
--- a/pkg/compiler/lib/src/dump_info.dart
+++ b/pkg/compiler/lib/src/dump_info.dart
@@ -290,7 +290,7 @@
 
     String inferredReturnType = '${_resultOfMember(function).returnType}';
     String sideEffects =
-        '${compiler.globalInference.resultsForTesting.inferredData.getSideEffectsOfElement(function)}';
+        '${_globalInferenceResults.inferredData.getSideEffectsOfElement(function)}';
 
     int inlinedCount = compiler.dumpInfoTask.inlineCount[function];
     if (inlinedCount == null) inlinedCount = 0;
diff --git a/pkg/compiler/lib/src/kernel/indexed.dart b/pkg/compiler/lib/src/elements/indexed.dart
similarity index 100%
rename from pkg/compiler/lib/src/kernel/indexed.dart
rename to pkg/compiler/lib/src/elements/indexed.dart
diff --git a/pkg/compiler/lib/src/enqueue.dart b/pkg/compiler/lib/src/enqueue.dart
index 47f8804..fa58347 100644
--- a/pkg/compiler/lib/src/enqueue.dart
+++ b/pkg/compiler/lib/src/enqueue.dart
@@ -63,9 +63,13 @@
 
   Enqueuer createCodegenEnqueuer(JClosedWorld closedWorld,
       GlobalTypeInferenceResults globalInferenceResults) {
-    return codegenEnqueuerForTesting = compiler.backend.createCodegenEnqueuer(
+    Enqueuer enqueuer = compiler.backend.createCodegenEnqueuer(
         this, compiler, closedWorld, globalInferenceResults)
       ..onEmptyForTesting = compiler.onCodegenQueueEmptyForTesting;
+    if (retainDataForTesting) {
+      codegenEnqueuerForTesting = enqueuer;
+    }
+    return enqueuer;
   }
 }
 
diff --git a/pkg/compiler/lib/src/frontend_strategy.dart b/pkg/compiler/lib/src/frontend_strategy.dart
index f136390..dcd11fc 100644
--- a/pkg/compiler/lib/src/frontend_strategy.dart
+++ b/pkg/compiler/lib/src/frontend_strategy.dart
@@ -127,8 +127,6 @@
 /// Class that deletes the contents of an [WorldImpact] cache.
 // TODO(redemption): this can be deleted when we sunset the old front end.
 abstract class ImpactCacheDeleter {
-  static bool retainCachesForTesting = false;
-
   /// Removes the [WorldImpact] for [element] from the resolution cache. Later
   /// calls to [getWorldImpact] or [computeWorldImpact] returns an empty impact.
   void uncacheWorldImpact(Entity element);
diff --git a/pkg/compiler/lib/src/inferrer/builder_kernel.dart b/pkg/compiler/lib/src/inferrer/builder_kernel.dart
index df34fdb..23785e3 100644
--- a/pkg/compiler/lib/src/inferrer/builder_kernel.dart
+++ b/pkg/compiler/lib/src/inferrer/builder_kernel.dart
@@ -13,6 +13,7 @@
 import '../elements/jumps.dart';
 import '../elements/types.dart';
 import '../js_backend/backend.dart';
+import '../js_model/element_map.dart';
 import '../js_model/locals.dart' show JumpVisitor;
 import '../kernel/element_map.dart';
 import '../native/behavior.dart';
@@ -45,7 +46,7 @@
   final TypeSystem _types;
   final MemberEntity _analyzedMember;
   final ir.Node _analyzedNode;
-  final KernelToElementMapForBuilding _elementMap;
+  final JsToElementMap _elementMap;
   final KernelToLocalsMap _localsMap;
   final GlobalTypeInferenceElementData _memberData;
   final bool _inGenerativeConstructor;
diff --git a/pkg/compiler/lib/src/inferrer/inferrer_engine.dart b/pkg/compiler/lib/src/inferrer/inferrer_engine.dart
index a25c9fc..08f5f29 100644
--- a/pkg/compiler/lib/src/inferrer/inferrer_engine.dart
+++ b/pkg/compiler/lib/src/inferrer/inferrer_engine.dart
@@ -14,10 +14,10 @@
 import '../elements/entities.dart';
 import '../elements/names.dart';
 import '../elements/types.dart';
-import '../js_backend/annotations.dart' as optimizerHints;
 import '../js_backend/inferred_data.dart';
 import '../js_backend/no_such_method_registry.dart';
 import '../js_emitter/sorter.dart';
+import '../js_model/element_map.dart';
 import '../js_model/locals.dart';
 import '../kernel/element_map.dart';
 import '../native/behavior.dart' as native;
@@ -251,8 +251,6 @@
 }
 
 class InferrerEngineImpl extends InferrerEngine {
-  static bool retainDataForTesting = false;
-
   final Map<Local, TypeInformation> defaultTypeOfParameter =
       new Map<Local, TypeInformation>();
   final WorkQueue workQueue = new WorkQueue();
@@ -291,7 +289,7 @@
   final NoSuchMethodRegistry noSuchMethodRegistry;
 
   final Sorter sorter;
-  final KernelToElementMapForBuilding _elementMap;
+  final JsToElementMap _elementMap;
   final GlobalLocalsMap _globalLocalsMap;
   final ClosureDataLookup _closureDataLookup;
 
@@ -1262,19 +1260,18 @@
 
   @override
   bool trustTypeAnnotations(MemberEntity member) {
-    return optimizerHints.trustTypeAnnotations(
-        closedWorld.elementEnvironment, commonElements, member);
+    return closedWorld.annotationsData.trustTypeAnnotationsMembers
+        .contains(member);
   }
 
   @override
   bool assumeDynamic(MemberEntity member) {
-    return optimizerHints.assumeDynamic(
-        closedWorld.elementEnvironment, commonElements, member);
+    return closedWorld.annotationsData.assumeDynamicMembers.contains(member);
   }
 }
 
 class KernelTypeSystemStrategy implements TypeSystemStrategy {
-  KernelToElementMapForBuilding _elementMap;
+  JsToElementMap _elementMap;
   GlobalLocalsMap _globalLocalsMap;
   ClosureDataLookup _closureDataLookup;
 
diff --git a/pkg/compiler/lib/src/inferrer/type_graph_inferrer.dart b/pkg/compiler/lib/src/inferrer/type_graph_inferrer.dart
index 4319b27..c8a0219 100644
--- a/pkg/compiler/lib/src/inferrer/type_graph_inferrer.dart
+++ b/pkg/compiler/lib/src/inferrer/type_graph_inferrer.dart
@@ -12,8 +12,8 @@
 import '../elements/entities.dart';
 import '../js_backend/inferred_data.dart';
 import '../js_model/elements.dart' show JClosureCallMethod;
+import '../js_model/element_map.dart';
 import '../js_model/locals.dart';
-import '../kernel/element_map.dart';
 import '../types/abstract_value_domain.dart';
 import '../types/types.dart';
 import '../world.dart';
@@ -56,7 +56,7 @@
   final JClosedWorld closedWorld;
 
   final Compiler _compiler;
-  final KernelToElementMapForBuilding _elementMap;
+  final JsToElementMap _elementMap;
   final GlobalLocalsMap _globalLocalsMap;
   final ClosureDataLookup _closureDataLookup;
   final InferredDataBuilder _inferredDataBuilder;
diff --git a/pkg/compiler/lib/src/io/kernel_source_information.dart b/pkg/compiler/lib/src/io/kernel_source_information.dart
index b70af803..1d7ad8f 100644
--- a/pkg/compiler/lib/src/io/kernel_source_information.dart
+++ b/pkg/compiler/lib/src/io/kernel_source_information.dart
@@ -9,6 +9,7 @@
 
 import 'package:kernel/ast.dart' as ir;
 import '../elements/entities.dart';
+import '../js_model/element_map.dart';
 import '../kernel/element_map.dart';
 import '../js_model/js_strategy.dart';
 import '../universe/call_structure.dart';
@@ -35,7 +36,7 @@
 // TODO(johnniwinther): Make the closure call names available to
 // `sourcemap_helper.dart`.
 String computeKernelElementNameForSourceMaps(
-    KernelToElementMapForBuilding elementMap, MemberEntity member,
+    JsToElementMap elementMap, MemberEntity member,
     [CallStructure callStructure]) {
   MemberDefinition definition = elementMap.getMemberDefinition(member);
   switch (definition.kind) {
@@ -70,7 +71,7 @@
 /// [SourceInformationBuilder] that generates [PositionSourceInformation] from
 /// Kernel nodes.
 class KernelSourceInformationBuilder implements SourceInformationBuilder {
-  final KernelToElementMapForBuilding _elementMap;
+  final JsToElementMap _elementMap;
   final MemberEntity _member;
   final String _name;
 
diff --git a/pkg/compiler/lib/src/kernel/kernel_debug.dart b/pkg/compiler/lib/src/ir/debug.dart
similarity index 100%
rename from pkg/compiler/lib/src/kernel/kernel_debug.dart
rename to pkg/compiler/lib/src/ir/debug.dart
diff --git a/pkg/compiler/lib/src/ir/element_map.dart b/pkg/compiler/lib/src/ir/element_map.dart
new file mode 100644
index 0000000..250c391
--- /dev/null
+++ b/pkg/compiler/lib/src/ir/element_map.dart
@@ -0,0 +1,71 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for 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' as ir;
+import 'package:kernel/class_hierarchy.dart' as ir;
+import 'package:kernel/core_types.dart' as ir;
+import 'package:kernel/type_environment.dart' as ir;
+
+import '../common.dart';
+import '../common_elements.dart';
+import '../elements/entities.dart';
+import '../elements/indexed.dart';
+import '../elements/types.dart';
+import '../ordered_typeset.dart';
+import '../universe/call_structure.dart';
+
+/// Interface that translates between Kernel IR nodes and entities.
+///
+/// This interface is used internally to implement [KernelToElementMap] in the
+/// frontend and [JsToElementMap] in the backend.
+abstract class IrToElementMap {
+  /// Returns the [DartType] corresponding to [type].
+  DartType getDartType(ir.DartType type);
+
+  /// Returns the [MemberEntity] corresponding to the member [node].
+  MemberEntity getMember(ir.Member node);
+
+  /// Returns the [FunctionEntity] corresponding to the procedure [node].
+  FunctionEntity getMethod(ir.Procedure node);
+
+  /// Returns the [ConstructorEntity] corresponding to the generative or factory
+  /// constructor [node].
+  ConstructorEntity getConstructor(ir.Member node);
+
+  /// Returns the [FieldEntity] corresponding to the field [node].
+  FieldEntity getField(ir.Field node);
+
+  /// Returns the [ClassEntity] corresponding to the class [node].
+  ClassEntity getClass(ir.Class node);
+
+  /// Returns the [FunctionType] of the [node].
+  FunctionType getFunctionType(ir.FunctionNode node);
+
+  /// Returns the [TypedefType] corresponding to raw type of the typedef [node].
+  TypedefType getTypedefType(ir.Typedef node);
+
+  /// Return the [InterfaceType] corresponding to the [cls] with the given
+  /// [typeArguments].
+  InterfaceType createInterfaceType(
+      ir.Class cls, List<ir.DartType> typeArguments);
+
+  /// Returns the [CallStructure] corresponding to the [arguments].
+  CallStructure getCallStructure(ir.Arguments arguments);
+
+  /// Returns the [TypeVariableEntity] corresponding to the type parameter
+  /// [node].
+  TypeVariableEntity getTypeVariable(ir.TypeParameter node);
+
+  CommonElements get commonElements;
+  DiagnosticReporter get reporter;
+  InterfaceType getThisType(IndexedClass cls);
+  InterfaceType getSuperType(IndexedClass cls);
+  OrderedTypeSet getOrderedTypeSet(IndexedClass cls);
+  Iterable<InterfaceType> getInterfaces(IndexedClass cls);
+  InterfaceType asInstanceOf(InterfaceType type, ClassEntity cls);
+  DartType substByContext(DartType type, InterfaceType context);
+  DartType getCallType(InterfaceType type);
+  int getHierarchyDepth(IndexedClass cls);
+  DartType getTypeVariableBound(IndexedTypeVariable typeVariable);
+}
diff --git a/pkg/compiler/lib/src/kernel/types.dart b/pkg/compiler/lib/src/ir/types.dart
similarity index 67%
rename from pkg/compiler/lib/src/kernel/types.dart
rename to pkg/compiler/lib/src/ir/types.dart
index 62f38ba..590a295 100644
--- a/pkg/compiler/lib/src/kernel/types.dart
+++ b/pkg/compiler/lib/src/ir/types.dart
@@ -2,16 +2,20 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-part of dart2js.kernel.element_map;
+import '../common_elements.dart';
+import '../elements/entities.dart';
+import '../elements/types.dart';
+import '../ordered_typeset.dart';
+import 'element_map.dart';
 
 /// Support for subtype checks of kernel based [DartType]s.
-class _KernelDartTypes extends DartTypes {
-  final KernelToElementMapBase elementMap;
+class KernelDartTypes extends DartTypes {
+  final IrToElementMap elementMap;
   final SubtypeVisitor<DartType> subtypeVisitor;
   final PotentialSubtypeVisitor<DartType> potentialSubtypeVisitor;
 
-  _KernelDartTypes(this.elementMap)
-      : this.subtypeVisitor = new _KernelSubtypeVisitor(elementMap),
+  KernelDartTypes(this.elementMap)
+      : this.subtypeVisitor = new KernelSubtypeVisitor(elementMap),
         this.potentialSubtypeVisitor =
             new _KernelPotentialSubtypeVisitor(elementMap);
 
@@ -34,37 +38,37 @@
 
   @override
   InterfaceType getThisType(ClassEntity cls) {
-    return elementMap._getThisType(cls);
+    return elementMap.getThisType(cls);
   }
 
   @override
   InterfaceType getSupertype(ClassEntity cls) {
-    return elementMap._getSuperType(cls);
+    return elementMap.getSuperType(cls);
   }
 
   @override
   Iterable<InterfaceType> getSupertypes(ClassEntity cls) {
-    return elementMap._getOrderedTypeSet(cls).supertypes;
+    return elementMap.getOrderedTypeSet(cls).supertypes;
   }
 
   @override
   Iterable<InterfaceType> getInterfaces(ClassEntity cls) {
-    return elementMap._getInterfaces(cls);
+    return elementMap.getInterfaces(cls);
   }
 
   @override
   InterfaceType asInstanceOf(InterfaceType type, ClassEntity cls) {
-    return elementMap._asInstanceOf(type, cls);
+    return elementMap.asInstanceOf(type, cls);
   }
 
   @override
   DartType substByContext(DartType base, InterfaceType context) {
-    return elementMap._substByContext(base, context);
+    return elementMap.substByContext(base, context);
   }
 
   @override
   FunctionType getCallType(InterfaceType type) {
-    DartType callType = elementMap._getCallType(type);
+    DartType callType = elementMap.getCallType(type);
     return callType is FunctionType ? callType : null;
   }
 
@@ -79,7 +83,7 @@
     for (int index = 0; index < typeArguments.length; index++) {
       DartType typeArgument = typeArguments[index];
       TypeVariableType typeVariable = typeVariables[index];
-      DartType bound = elementMap.elementEnvironment
+      DartType bound = elementMap
           .getTypeVariableBound(typeVariable.element)
           .subst(typeArguments, typeVariables);
       checkTypeVariableBound(context, typeArgument, typeVariable, bound);
@@ -90,10 +94,10 @@
   CommonElements get commonElements => elementMap.commonElements;
 }
 
-class _KernelOrderedTypeSetBuilder extends OrderedTypeSetBuilderBase {
-  final KernelToElementMapBase elementMap;
+class KernelOrderedTypeSetBuilder extends OrderedTypeSetBuilderBase {
+  final IrToElementMap elementMap;
 
-  _KernelOrderedTypeSetBuilder(this.elementMap, ClassEntity cls)
+  KernelOrderedTypeSetBuilder(this.elementMap, ClassEntity cls)
       : super(cls, elementMap.commonElements.objectType,
             reporter: elementMap.reporter);
 
@@ -102,55 +106,55 @@
   bool get reportMultiInheritanceIssue => false;
 
   InterfaceType getThisType(ClassEntity cls) {
-    return elementMap._getThisType(cls);
+    return elementMap.getThisType(cls);
   }
 
   InterfaceType substByContext(InterfaceType type, InterfaceType context) {
-    return elementMap._substByContext(type, context);
+    return elementMap.substByContext(type, context);
   }
 
   int getHierarchyDepth(ClassEntity cls) {
-    return elementMap._getHierarchyDepth(cls);
+    return elementMap.getHierarchyDepth(cls);
   }
 
   OrderedTypeSet getOrderedTypeSet(ClassEntity cls) {
-    return elementMap._getOrderedTypeSet(cls);
+    return elementMap.getOrderedTypeSet(cls);
   }
 }
 
-abstract class _AbstractTypeRelationMixin
+abstract class AbstractTypeRelationMixin
     implements AbstractTypeRelation<DartType> {
-  KernelToElementMapBase get elementMap;
+  IrToElementMap get elementMap;
 
   @override
   CommonElements get commonElements => elementMap.commonElements;
 
   @override
   DartType getTypeVariableBound(TypeVariableEntity element) {
-    return elementMap.elementEnvironment.getTypeVariableBound(element);
+    return elementMap.getTypeVariableBound(element);
   }
 
   @override
   FunctionType getCallType(InterfaceType type) {
-    return elementMap._getCallType(type);
+    return elementMap.getCallType(type);
   }
 
   @override
   InterfaceType asInstanceOf(InterfaceType type, ClassEntity cls) {
-    return elementMap._asInstanceOf(type, cls);
+    return elementMap.asInstanceOf(type, cls);
   }
 }
 
-class _KernelSubtypeVisitor extends SubtypeVisitor<DartType>
-    with _AbstractTypeRelationMixin {
-  final KernelToElementMapBase elementMap;
+class KernelSubtypeVisitor extends SubtypeVisitor<DartType>
+    with AbstractTypeRelationMixin {
+  final IrToElementMap elementMap;
 
-  _KernelSubtypeVisitor(this.elementMap);
+  KernelSubtypeVisitor(this.elementMap);
 }
 
 class _KernelPotentialSubtypeVisitor extends PotentialSubtypeVisitor<DartType>
-    with _AbstractTypeRelationMixin {
-  final KernelToElementMapBase elementMap;
+    with AbstractTypeRelationMixin {
+  final IrToElementMap elementMap;
 
   _KernelPotentialSubtypeVisitor(this.elementMap);
 }
diff --git a/pkg/compiler/lib/src/ir/util.dart b/pkg/compiler/lib/src/ir/util.dart
new file mode 100644
index 0000000..8a4a0c4
--- /dev/null
+++ b/pkg/compiler/lib/src/ir/util.dart
@@ -0,0 +1,103 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for 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' as ir;
+import 'package:kernel/class_hierarchy.dart' as ir;
+import 'package:kernel/core_types.dart' as ir;
+import 'package:kernel/type_environment.dart' as ir;
+
+import '../common.dart';
+import '../elements/entities.dart';
+
+/// Comparator for the canonical order or named arguments.
+// TODO(johnniwinther): Remove this when named parameters are sorted in dill.
+int namedOrdering(ir.VariableDeclaration a, ir.VariableDeclaration b) {
+  return a.name.compareTo(b.name);
+}
+
+SourceSpan computeSourceSpanFromTreeNode(ir.TreeNode node) {
+  // TODO(johnniwinther): Use [ir.Location] directly as a [SourceSpan].
+  Uri uri;
+  int offset;
+  while (node != null) {
+    if (node.fileOffset != ir.TreeNode.noOffset) {
+      offset = node.fileOffset;
+      // @patch annotations have no location.
+      uri = node.location?.file;
+      break;
+    }
+    node = node.parent;
+  }
+  if (uri != null) {
+    return new SourceSpan(uri, offset, offset + 1);
+  }
+  return null;
+}
+
+/// Returns the `AsyncMarker` corresponding to `node.asyncMarker`.
+AsyncMarker getAsyncMarker(ir.FunctionNode node) {
+  switch (node.asyncMarker) {
+    case ir.AsyncMarker.Async:
+      return AsyncMarker.ASYNC;
+    case ir.AsyncMarker.AsyncStar:
+      return AsyncMarker.ASYNC_STAR;
+    case ir.AsyncMarker.Sync:
+      return AsyncMarker.SYNC;
+    case ir.AsyncMarker.SyncStar:
+      return AsyncMarker.SYNC_STAR;
+    case ir.AsyncMarker.SyncYielding:
+    default:
+      throw new UnsupportedError(
+          "Async marker ${node.asyncMarker} is not supported.");
+  }
+}
+
+/// Kernel encodes a null-aware expression `a?.b` as
+///
+///     let final #1 = a in #1 == null ? null : #1.b
+///
+/// [getNullAwareExpression] recognizes such expressions storing the result in
+/// a [NullAwareExpression] object.
+///
+/// [syntheticVariable] holds the synthesized `#1` variable. [expression] holds
+/// the `#1.b` expression. [receiver] returns `a` expression. [parent] returns
+/// the parent of the let node, i.e. the parent node of the original null-aware
+/// expression. [let] returns the let node created for the encoding.
+class NullAwareExpression {
+  final ir.VariableDeclaration syntheticVariable;
+  final ir.Expression expression;
+
+  NullAwareExpression(this.syntheticVariable, this.expression);
+
+  ir.Expression get receiver => syntheticVariable.initializer;
+
+  ir.TreeNode get parent => syntheticVariable.parent.parent;
+
+  ir.Let get let => syntheticVariable.parent;
+
+  String toString() => let.toString();
+}
+
+NullAwareExpression getNullAwareExpression(ir.TreeNode node) {
+  if (node is ir.Let) {
+    ir.Expression body = node.body;
+    if (node.variable.name == null &&
+        node.variable.isFinal &&
+        body is ir.ConditionalExpression &&
+        body.condition is ir.MethodInvocation &&
+        body.then is ir.NullLiteral) {
+      ir.MethodInvocation invocation = body.condition;
+      ir.Expression receiver = invocation.receiver;
+      if (invocation.name.name == '==' &&
+          receiver is ir.VariableGet &&
+          receiver.variable == node.variable &&
+          invocation.arguments.positional.single is ir.NullLiteral) {
+        // We have
+        //   let #t1 = e0 in #t1 == null ? null : e1
+        return new NullAwareExpression(node.variable, body.otherwise);
+      }
+    }
+  }
+  return null;
+}
diff --git a/pkg/compiler/lib/src/ir/visitors.dart b/pkg/compiler/lib/src/ir/visitors.dart
new file mode 100644
index 0000000..3e97494
--- /dev/null
+++ b/pkg/compiler/lib/src/ir/visitors.dart
@@ -0,0 +1,622 @@
+// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
+// for 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' as ir;
+
+import '../common.dart';
+import '../constants/constructors.dart';
+import '../constants/expressions.dart';
+import '../common_elements.dart';
+import '../elements/entities.dart';
+import '../elements/operators.dart';
+import '../elements/types.dart';
+import '../ir/element_map.dart';
+import '../ir/util.dart';
+
+/// Visitor that converts string literals and concatenations of string literals
+/// into the string value.
+class Stringifier extends ir.ExpressionVisitor<String> {
+  @override
+  String visitStringLiteral(ir.StringLiteral node) => node.value;
+
+  @override
+  String visitStringConcatenation(ir.StringConcatenation node) {
+    StringBuffer sb = new StringBuffer();
+    for (ir.Expression expression in node.expressions) {
+      String value = expression.accept(this);
+      if (value == null) return null;
+      sb.write(value);
+    }
+    return sb.toString();
+  }
+}
+
+/// Visitor that converts a kernel constant expression into a
+/// [ConstantExpression].
+class Constantifier extends ir.ExpressionVisitor<ConstantExpression> {
+  final bool requireConstant;
+  final IrToElementMap elementMap;
+  ir.TreeNode failNode;
+  final Map<ir.VariableDeclaration, ConstantExpression> _initializerLocals =
+      <ir.VariableDeclaration, ConstantExpression>{};
+
+  Constantifier(this.elementMap, {this.requireConstant: true});
+
+  CommonElements get _commonElements => elementMap.commonElements;
+
+  ConstantExpression visit(ir.Expression node) {
+    ConstantExpression constant = node.accept(this);
+    if (constant == null && requireConstant) {
+      // TODO(johnniwinther): Support contextual error messages.
+      elementMap.reporter.reportErrorMessage(
+          computeSourceSpanFromTreeNode(failNode ?? node),
+          MessageKind.NOT_A_COMPILE_TIME_CONSTANT);
+      return new ErroneousConstantExpression();
+    }
+    return constant;
+  }
+
+  ConstantExpression defaultExpression(ir.Expression node) {
+    if (requireConstant) {
+      failNode ??= node;
+    }
+    return null;
+  }
+
+  List<ConstantExpression> _computeList(List<ir.Expression> expressions) {
+    List<ConstantExpression> list = <ConstantExpression>[];
+    for (ir.Expression expression in expressions) {
+      ConstantExpression constant = visit(expression);
+      if (constant == null) return null;
+      list.add(constant);
+    }
+    return list;
+  }
+
+  List<ConstantExpression> _computeArguments(ir.Arguments node) {
+    List<ConstantExpression> arguments = <ConstantExpression>[];
+    for (ir.Expression argument in node.positional) {
+      ConstantExpression constant = visit(argument);
+      if (constant == null) return null;
+      arguments.add(constant);
+    }
+    for (ir.NamedExpression argument in node.named) {
+      ConstantExpression constant = visit(argument.value);
+      if (constant == null) return null;
+      arguments.add(constant);
+    }
+    return arguments;
+  }
+
+  ConstructedConstantExpression _computeConstructorInvocation(
+      ir.Constructor target, ir.Arguments arguments) {
+    List<ConstantExpression> expressions = _computeArguments(arguments);
+    if (expressions == null) return null;
+    return new ConstructedConstantExpression(
+        elementMap.createInterfaceType(target.enclosingClass, arguments.types),
+        elementMap.getConstructor(target),
+        elementMap.getCallStructure(arguments),
+        expressions);
+  }
+
+  @override
+  ConstantExpression visitConstructorInvocation(ir.ConstructorInvocation node) {
+    if (!node.isConst) return null;
+    return _computeConstructorInvocation(node.target, node.arguments);
+  }
+
+  @override
+  ConstantExpression visitVariableGet(ir.VariableGet node) {
+    ConstantExpression constant = _initializerLocals[node.variable];
+    if (constant != null) {
+      return constant;
+    }
+    if (node.variable.parent is ir.FunctionNode) {
+      ir.FunctionNode function = node.variable.parent;
+      int index = function.positionalParameters.indexOf(node.variable);
+      if (index != -1) {
+        return new PositionalArgumentReference(index);
+      } else {
+        assert(function.namedParameters.contains(node.variable));
+        return new NamedArgumentReference(node.variable.name);
+      }
+    } else if (node.variable.isConst) {
+      return visit(node.variable.initializer);
+    }
+    return defaultExpression(node);
+  }
+
+  @override
+  ConstantExpression visitStaticGet(ir.StaticGet node) {
+    ir.Member target = node.target;
+    if (target is ir.Field && target.isConst) {
+      return new FieldConstantExpression(elementMap.getField(node.target));
+    } else if (target is ir.Procedure &&
+        target.kind == ir.ProcedureKind.Method) {
+      FunctionEntity function = elementMap.getMethod(node.target);
+      DartType type = elementMap.getFunctionType(node.target.function);
+      return new FunctionConstantExpression(function, type);
+    }
+    return defaultExpression(node);
+  }
+
+  @override
+  ConstantExpression visitNullLiteral(ir.NullLiteral node) {
+    return new NullConstantExpression();
+  }
+
+  @override
+  ConstantExpression visitBoolLiteral(ir.BoolLiteral node) {
+    return new BoolConstantExpression(node.value);
+  }
+
+  @override
+  ConstantExpression visitIntLiteral(ir.IntLiteral node) {
+    return new IntConstantExpression(
+        new BigInt.from(node.value).toUnsigned(64));
+  }
+
+  @override
+  ConstantExpression visitDoubleLiteral(ir.DoubleLiteral node) {
+    return new DoubleConstantExpression(node.value);
+  }
+
+  @override
+  ConstantExpression visitStringLiteral(ir.StringLiteral node) {
+    return new StringConstantExpression(node.value);
+  }
+
+  @override
+  ConstantExpression visitSymbolLiteral(ir.SymbolLiteral node) {
+    return new SymbolConstantExpression(node.value);
+  }
+
+  @override
+  ConstantExpression visitStringConcatenation(ir.StringConcatenation node) {
+    List<ConstantExpression> expressions = _computeList(node.expressions);
+    if (expressions == null) return null;
+    return new ConcatenateConstantExpression(expressions);
+  }
+
+  @override
+  ConstantExpression visitMapLiteral(ir.MapLiteral node) {
+    if (!node.isConst) {
+      return defaultExpression(node);
+    }
+    DartType keyType = elementMap.getDartType(node.keyType);
+    DartType valueType = elementMap.getDartType(node.valueType);
+    List<ConstantExpression> keys = <ConstantExpression>[];
+    List<ConstantExpression> values = <ConstantExpression>[];
+    for (ir.MapEntry entry in node.entries) {
+      ConstantExpression key = visit(entry.key);
+      if (key == null) return null;
+      keys.add(key);
+      ConstantExpression value = visit(entry.value);
+      if (value == null) return null;
+      values.add(value);
+    }
+    return new MapConstantExpression(
+        _commonElements.mapType(keyType, valueType), keys, values);
+  }
+
+  @override
+  ConstantExpression visitListLiteral(ir.ListLiteral node) {
+    if (!node.isConst) {
+      return defaultExpression(node);
+    }
+    DartType elementType = elementMap.getDartType(node.typeArgument);
+    List<ConstantExpression> values = <ConstantExpression>[];
+    for (ir.Expression expression in node.expressions) {
+      ConstantExpression value = visit(expression);
+      if (value == null) return null;
+      values.add(value);
+    }
+    return new ListConstantExpression(
+        _commonElements.listType(elementType), values);
+  }
+
+  @override
+  ConstantExpression visitTypeLiteral(ir.TypeLiteral node) {
+    String name;
+    DartType type = elementMap.getDartType(node.type);
+    if (type.isDynamic) {
+      name = 'dynamic';
+    } else if (type is InterfaceType) {
+      name = type.element.name;
+    } else if (type.isTypedef) {
+      // TODO(johnniwinther): Compute a name for the type literal? It is only
+      // used in error messages in the old SSA builder.
+      name = '?';
+    } else if (node.type is ir.FunctionType) {
+      ir.FunctionType functionType = node.type;
+      assert(functionType.typedef != null);
+      type = elementMap.getTypedefType(functionType.typedef);
+      name = functionType.typedef.name;
+    } else {
+      return defaultExpression(node);
+    }
+    return new TypeConstantExpression(type, name);
+  }
+
+  @override
+  ConstantExpression visitAsExpression(ir.AsExpression node) {
+    ConstantExpression expression = visit(node.operand);
+    if (expression == null) return null;
+    DartType type = elementMap.getDartType(node.type);
+    return new AsConstantExpression(expression, type);
+  }
+
+  @override
+  ConstantExpression visitInstantiation(ir.Instantiation node) {
+    List<DartType> typeArguments =
+        node.typeArguments.map(elementMap.getDartType).toList();
+    for (DartType typeArgument in typeArguments) {
+      if (typeArgument.containsTypeVariables) {
+        return null;
+      }
+    }
+    ConstantExpression expression = visit(node.expression);
+    if (expression == null) return null;
+    return new InstantiationConstantExpression(typeArguments, expression);
+  }
+
+  @override
+  ConstantExpression visitNot(ir.Not node) {
+    ConstantExpression expression = visit(node.operand);
+    if (expression == null) return null;
+    return new UnaryConstantExpression(UnaryOperator.NOT, expression);
+  }
+
+  @override
+  ConstantExpression visitConditionalExpression(ir.ConditionalExpression node) {
+    ConstantExpression condition = visit(node.condition);
+    if (condition == null) return null;
+    ConstantExpression trueExp = visit(node.then);
+    if (trueExp == null) return null;
+    ConstantExpression falseExp = visit(node.otherwise);
+    if (falseExp == null) return null;
+    return new ConditionalConstantExpression(condition, trueExp, falseExp);
+  }
+
+  @override
+  ConstantExpression visitPropertyGet(ir.PropertyGet node) {
+    if (node.name.name != 'length') {
+      failNode ??= node;
+      return null;
+    }
+    ConstantExpression receiver = visit(node.receiver);
+    if (receiver == null) return null;
+    return new StringLengthConstantExpression(receiver);
+  }
+
+  @override
+  ConstantExpression visitMethodInvocation(ir.MethodInvocation node) {
+    // Method invocations are generally not constant expressions but unary
+    // and binary expressions are encoded as method invocations in kernel.
+    if (node.arguments.named.isNotEmpty) {
+      return defaultExpression(node);
+    }
+    if (node.arguments.positional.length == 0) {
+      UnaryOperator operator;
+      if (node.name.name == UnaryOperator.NEGATE.selectorName) {
+        operator = UnaryOperator.NEGATE;
+      } else {
+        operator = UnaryOperator.parse(node.name.name);
+      }
+      if (operator != null) {
+        ConstantExpression expression = visit(node.receiver);
+        if (expression == null) return null;
+        return new UnaryConstantExpression(operator, expression);
+      }
+    }
+    if (node.arguments.positional.length == 1) {
+      BinaryOperator operator = BinaryOperator.parse(node.name.name);
+      if (operator != null) {
+        ConstantExpression left = visit(node.receiver);
+        if (left == null) return null;
+        ConstantExpression right = visit(node.arguments.positional.single);
+        if (right == null) return null;
+        return new BinaryConstantExpression(left, operator, right);
+      }
+    }
+    return defaultExpression(node);
+  }
+
+  @override
+  ConstantExpression visitStaticInvocation(ir.StaticInvocation node) {
+    MemberEntity member = elementMap.getMember(node.target);
+    if (member == _commonElements.identicalFunction) {
+      if (node.arguments.positional.length == 2 &&
+          node.arguments.named.isEmpty) {
+        ConstantExpression left = visit(node.arguments.positional[0]);
+        if (left == null) return null;
+        ConstantExpression right = visit(node.arguments.positional[1]);
+        if (right == null) return null;
+        return new IdenticalConstantExpression(left, right);
+      }
+    } else if (member.name == 'fromEnvironment' &&
+        node.arguments.positional.length == 1) {
+      ConstantExpression name = visit(node.arguments.positional.single);
+      if (name == null) return null;
+      ConstantExpression defaultValue;
+      if (node.arguments.named.length == 1) {
+        if (node.arguments.named.single.name != 'defaultValue') {
+          return defaultExpression(node);
+        }
+        defaultValue = visit(node.arguments.named.single.value);
+        if (defaultValue == null) return null;
+      }
+      if (member.enclosingClass == _commonElements.boolClass) {
+        return new BoolFromEnvironmentConstantExpression(name, defaultValue);
+      } else if (member.enclosingClass == _commonElements.intClass) {
+        return new IntFromEnvironmentConstantExpression(name, defaultValue);
+      } else if (member.enclosingClass == _commonElements.stringClass) {
+        return new StringFromEnvironmentConstantExpression(name, defaultValue);
+      }
+    }
+    return defaultExpression(node);
+  }
+
+  @override
+  ConstantExpression visitLogicalExpression(ir.LogicalExpression node) {
+    BinaryOperator operator = BinaryOperator.parse(node.operator);
+    if (operator != null &&
+        BinaryConstantExpression.potentialOperator(operator)) {
+      ConstantExpression left = visit(node.left);
+      if (left == null) return null;
+      ConstantExpression right = visit(node.right);
+      if (right == null) return null;
+      return new BinaryConstantExpression(left, operator, right);
+    }
+    return defaultExpression(node);
+  }
+
+  @override
+  ConstantExpression visitLet(ir.Let node) {
+    ir.Expression body = node.body;
+    if (body is ir.ConditionalExpression) {
+      ir.Expression condition = body.condition;
+      if (condition is ir.MethodInvocation) {
+        ir.Expression receiver = condition.receiver;
+        ir.Expression otherwise = body.otherwise;
+        if (condition.name.name == BinaryOperator.EQ.name &&
+            receiver is ir.VariableGet &&
+            condition.arguments.positional.single is ir.NullLiteral &&
+            otherwise is ir.VariableGet) {
+          if (receiver.variable == node.variable &&
+              otherwise.variable == node.variable) {
+            // We have <left> ?? <right> encoded as:
+            //    let #1 = <left> in #1 == null ? <right> : #1
+            ConstantExpression left = visit(node.variable.initializer);
+            if (left == null) return null;
+            ConstantExpression right = visit(body.then);
+            if (right == null) return null;
+            // TODO(johnniwinther): Remove [IF_NULL] binary constant expression
+            // when the resolver is removed; then we no longer need the
+            // expressions to be structurally equivalence for equivalence
+            // testing.
+            return new BinaryConstantExpression(
+                left, BinaryOperator.IF_NULL, right);
+          }
+        }
+      }
+    }
+    return defaultExpression(node);
+  }
+
+  /// Compute the [ConstantConstructor] corresponding to the const constructor
+  /// [node].
+  ConstantConstructor computeConstantConstructor(ir.Constructor node) {
+    assert(node.isConst);
+    ir.Class cls = node.enclosingClass;
+    InterfaceType type = elementMap.getThisType(elementMap.getClass(cls));
+
+    Map<dynamic, ConstantExpression> defaultValues =
+        <dynamic, ConstantExpression>{};
+    int parameterIndex = 0;
+    for (ir.VariableDeclaration parameter
+        in node.function.positionalParameters) {
+      if (parameterIndex >= node.function.requiredParameterCount) {
+        ConstantExpression defaultValue;
+        if (parameter.initializer != null) {
+          defaultValue = visit(parameter.initializer);
+        } else {
+          defaultValue = new NullConstantExpression();
+        }
+        if (defaultValue == null) return null;
+        defaultValues[parameterIndex] = defaultValue;
+      }
+      parameterIndex++;
+    }
+    for (ir.VariableDeclaration parameter in node.function.namedParameters) {
+      ConstantExpression defaultValue = visit(parameter.initializer);
+      if (defaultValue == null) return null;
+      defaultValues[parameter.name] = defaultValue;
+    }
+
+    bool isRedirecting = node.initializers.length == 1 &&
+        node.initializers.single is ir.RedirectingInitializer;
+
+    Map<FieldEntity, ConstantExpression> fieldMap =
+        <FieldEntity, ConstantExpression>{};
+
+    void registerField(ir.Field field, ConstantExpression constant) {
+      fieldMap[elementMap.getField(field)] = constant;
+    }
+
+    if (!isRedirecting) {
+      for (ir.Field field in cls.fields) {
+        if (field.isStatic) continue;
+        if (field.initializer != null) {
+          registerField(field, visit(field.initializer));
+        }
+      }
+    }
+
+    ConstructedConstantExpression superConstructorInvocation;
+    List<AssertConstantExpression> assertions = <AssertConstantExpression>[];
+    for (ir.Initializer initializer in node.initializers) {
+      if (initializer is ir.FieldInitializer) {
+        registerField(initializer.field, visit(initializer.value));
+      } else if (initializer is ir.SuperInitializer) {
+        superConstructorInvocation = _computeConstructorInvocation(
+            initializer.target, initializer.arguments);
+      } else if (initializer is ir.RedirectingInitializer) {
+        superConstructorInvocation = _computeConstructorInvocation(
+            initializer.target, initializer.arguments);
+      } else if (initializer is ir.AssertInitializer) {
+        ConstantExpression condition = visit(initializer.statement.condition);
+        ConstantExpression message = initializer.statement.message != null
+            ? visit(initializer.statement.message)
+            : null;
+        assertions.add(new AssertConstantExpression(condition, message));
+      } else if (initializer is ir.InvalidInitializer) {
+        String constructorName = '${cls.name}.${node.name}';
+        elementMap.reporter.reportErrorMessage(
+            computeSourceSpanFromTreeNode(initializer),
+            MessageKind.INVALID_CONSTANT_CONSTRUCTOR,
+            {'constructorName': constructorName});
+        return new ErroneousConstantConstructor();
+      } else if (initializer is ir.LocalInitializer) {
+        ir.VariableDeclaration variable = initializer.variable;
+        ConstantExpression constant = visit(variable.initializer);
+        if (constant != null) {
+          _initializerLocals[variable] = constant;
+        } else {
+          // TODO(johnniwinther): Use [_ErroneousInitializerVisitor] in
+          // `ssa/builder_kernel.dart` to identify erroneous initializer.
+          String constructorName = '${cls.name}.${node.name}';
+          elementMap.reporter.reportErrorMessage(
+              computeSourceSpanFromTreeNode(initializer),
+              MessageKind.INVALID_CONSTANT_CONSTRUCTOR,
+              {'constructorName': constructorName});
+          return new ErroneousConstantConstructor();
+        }
+      } else {
+        throw new UnsupportedError(
+            'Unexpected initializer $initializer (${initializer.runtimeType})');
+      }
+    }
+    if (isRedirecting) {
+      return new RedirectingGenerativeConstantConstructor(
+          defaultValues, superConstructorInvocation);
+    } else {
+      return new GenerativeConstantConstructor(type, defaultValues, fieldMap,
+          assertions, superConstructorInvocation);
+    }
+  }
+}
+
+/// Visitor that converts kernel dart types into [DartType].
+class DartTypeConverter extends ir.DartTypeVisitor<DartType> {
+  final IrToElementMap elementMap;
+  final Map<ir.TypeParameter, DartType> currentFunctionTypeParameters =
+      <ir.TypeParameter, DartType>{};
+  bool topLevel = true;
+
+  DartTypeConverter(this.elementMap);
+
+  DartType convert(ir.DartType type) {
+    topLevel = true;
+    return type.accept(this);
+  }
+
+  /// Visit a inner type.
+  DartType visitType(ir.DartType type) {
+    topLevel = false;
+    return type.accept(this);
+  }
+
+  InterfaceType visitSupertype(ir.Supertype node) {
+    ClassEntity cls = elementMap.getClass(node.classNode);
+    return new InterfaceType(cls, visitTypes(node.typeArguments));
+  }
+
+  List<DartType> visitTypes(List<ir.DartType> types) {
+    topLevel = false;
+    return new List.generate(
+        types.length, (int index) => types[index].accept(this));
+  }
+
+  @override
+  DartType visitTypeParameterType(ir.TypeParameterType node) {
+    DartType typeParameter = currentFunctionTypeParameters[node.parameter];
+    if (typeParameter != null) {
+      return typeParameter;
+    }
+    if (node.parameter.parent is ir.Typedef) {
+      // Typedefs are only used in type literals so we never need their type
+      // variables.
+      return const DynamicType();
+    }
+    return new TypeVariableType(elementMap.getTypeVariable(node.parameter));
+  }
+
+  @override
+  DartType visitFunctionType(ir.FunctionType node) {
+    int index = 0;
+    List<FunctionTypeVariable> typeVariables;
+    for (ir.TypeParameter typeParameter in node.typeParameters) {
+      FunctionTypeVariable typeVariable = new FunctionTypeVariable(index);
+      currentFunctionTypeParameters[typeParameter] = typeVariable;
+      typeVariables ??= <FunctionTypeVariable>[];
+      typeVariables.add(typeVariable);
+      index++;
+    }
+    if (typeVariables != null) {
+      for (int index = 0; index < typeVariables.length; index++) {
+        typeVariables[index].bound =
+            node.typeParameters[index].bound.accept(this);
+      }
+    }
+
+    FunctionType type = new FunctionType(
+        visitType(node.returnType),
+        visitTypes(node.positionalParameters
+            .take(node.requiredParameterCount)
+            .toList()),
+        visitTypes(node.positionalParameters
+            .skip(node.requiredParameterCount)
+            .toList()),
+        node.namedParameters.map((n) => n.name).toList(),
+        node.namedParameters.map((n) => visitType(n.type)).toList(),
+        typeVariables ?? const <FunctionTypeVariable>[]);
+    for (ir.TypeParameter typeParameter in node.typeParameters) {
+      currentFunctionTypeParameters.remove(typeParameter);
+    }
+    return type;
+  }
+
+  @override
+  DartType visitInterfaceType(ir.InterfaceType node) {
+    ClassEntity cls = elementMap.getClass(node.classNode);
+    if (cls.name == 'FutureOr' &&
+        cls.library == elementMap.commonElements.asyncLibrary) {
+      return new FutureOrType(visitTypes(node.typeArguments).single);
+    }
+    return new InterfaceType(cls, visitTypes(node.typeArguments));
+  }
+
+  @override
+  DartType visitVoidType(ir.VoidType node) {
+    return const VoidType();
+  }
+
+  @override
+  DartType visitDynamicType(ir.DynamicType node) {
+    return const DynamicType();
+  }
+
+  @override
+  DartType visitInvalidType(ir.InvalidType node) {
+    // Root uses such a `o is Unresolved` and `o as Unresolved` must be special
+    // cased in the builder, nested invalid types are treated as `dynamic`.
+    return const DynamicType();
+  }
+
+  @override
+  DartType visitBottomType(ir.BottomType node) {
+    return elementMap.commonElements.nullType;
+  }
+}
diff --git a/pkg/compiler/lib/src/js_backend/allocator_analysis.dart b/pkg/compiler/lib/src/js_backend/allocator_analysis.dart
index 9147fae..bebbf7f 100644
--- a/pkg/compiler/lib/src/js_backend/allocator_analysis.dart
+++ b/pkg/compiler/lib/src/js_backend/allocator_analysis.dart
@@ -7,7 +7,7 @@
 import '../constants/values.dart';
 import '../js_model/elements.dart' show JsToFrontendMap, JField;
 import '../kernel/element_map.dart';
-import '../kernel/element_map_impl.dart' show KernelElementEnvironment;
+import '../kernel/kernel_strategy.dart';
 import '../kernel/kelements.dart' show KClass, KField;
 import '../options.dart';
 
@@ -30,15 +30,13 @@
 //     this.x = this.z = null;
 //
 class KAllocatorAnalysis implements AllocatorAnalysis {
-  final KernelElementEnvironment _elementEnvironment;
-  KernelToElementMap _elementMap;
+  final KernelToElementMap _elementMap;
 
   final Map<KField, ConstantValue> _fixedInitializers =
       <KField, ConstantValue>{};
 
-  KAllocatorAnalysis(this._elementEnvironment) {
-    _elementMap = _elementEnvironment.elementMap;
-  }
+  KAllocatorAnalysis(KernelFrontEndStrategy kernelStrategy)
+      : _elementMap = kernelStrategy.elementMap;
 
   // Register class during resolution. Use simple syntactic analysis to find
   // null-initialized fields.
diff --git a/pkg/compiler/lib/src/js_backend/annotations.dart b/pkg/compiler/lib/src/js_backend/annotations.dart
index 906f401..a36eea2 100644
--- a/pkg/compiler/lib/src/js_backend/annotations.dart
+++ b/pkg/compiler/lib/src/js_backend/annotations.dart
@@ -4,12 +4,17 @@
 
 library js_backend.backend.annotations;
 
-import '../common_elements.dart' show CommonElements, ElementEnvironment;
+import '../common_elements.dart';
 import '../constants/values.dart';
+import '../diagnostics/diagnostic_listener.dart';
+import '../diagnostics/messages.dart';
 import '../elements/entities.dart';
+import '../native/native.dart' as native;
+
+const VERBOSE_OPTIMIZER_HINTS = false;
 
 /// Returns `true` if inlining is disabled for [element].
-bool noInline(ElementEnvironment elementEnvironment,
+bool _noInline(ElementEnvironment elementEnvironment,
     CommonElements commonElements, MemberEntity element) {
   if (_hasAnnotation(
       elementEnvironment, element, commonElements.metaNoInlineClass)) {
@@ -25,7 +30,7 @@
 }
 
 /// Returns `true` if inlining is requested for [element].
-bool tryInline(ElementEnvironment elementEnvironment,
+bool _tryInline(ElementEnvironment elementEnvironment,
     CommonElements commonElements, MemberEntity element) {
   if (_hasAnnotation(
       elementEnvironment, element, commonElements.metaTryInlineClass)) {
@@ -36,14 +41,14 @@
 
 /// Returns `true` if parameter and returns types should be trusted for
 /// [element].
-bool trustTypeAnnotations(ElementEnvironment elementEnvironment,
+bool _trustTypeAnnotations(ElementEnvironment elementEnvironment,
     CommonElements commonElements, MemberEntity element) {
   return _hasAnnotation(elementEnvironment, element,
       commonElements.expectTrustTypeAnnotationsClass);
 }
 
 /// Returns `true` if inference of parameter types is disabled for [element].
-bool assumeDynamic(ElementEnvironment elementEnvironment,
+bool _assumeDynamic(ElementEnvironment elementEnvironment,
     CommonElements commonElements, MemberEntity element) {
   return _hasAnnotation(
       elementEnvironment, element, commonElements.expectAssumeDynamicClass);
@@ -63,3 +68,200 @@
   }
   return false;
 }
+
+/// Process backend specific annotations.
+// TODO(johnniwinther): Merge this with [AnnotationProcessor].
+AnnotationsData processAnnotations(
+    DiagnosticReporter reporter,
+    CommonElements commonElements,
+    ElementEnvironment elementEnvironment,
+    Iterable<MemberEntity> processedMembers) {
+  AnnotationsDataBuilder annotationsDataBuilder = new AnnotationsDataBuilder();
+
+  void processMemberAnnotations(MemberEntity element) {
+    bool hasNoInline = false;
+    bool hasForceInline = false;
+
+    if (_trustTypeAnnotations(elementEnvironment, commonElements, element)) {
+      annotationsDataBuilder.registerTrustTypeAnnotations(element);
+    }
+
+    if (_assumeDynamic(elementEnvironment, commonElements, element)) {
+      annotationsDataBuilder.registerAssumeDynamic(element);
+    }
+
+    if (element.isFunction || element.isConstructor) {
+      if (_noInline(elementEnvironment, commonElements, element)) {
+        hasNoInline = true;
+        annotationsDataBuilder.markAsNonInlinable(element);
+      }
+      if (_tryInline(elementEnvironment, commonElements, element)) {
+        hasForceInline = true;
+        if (hasNoInline) {
+          reporter.reportErrorMessage(element, MessageKind.GENERIC,
+              {'text': '@tryInline must not be used with @noInline.'});
+        } else {
+          annotationsDataBuilder.markAsTryInline(element);
+        }
+      }
+    }
+
+    if (element.isField) return;
+    FunctionEntity method = element;
+
+    LibraryEntity library = method.library;
+    if (library.canonicalUri.scheme != 'dart' &&
+        !native.maybeEnableNative(library.canonicalUri)) {
+      return;
+    }
+
+    bool hasNoThrows = false;
+    bool hasNoSideEffects = false;
+    for (ConstantValue constantValue
+        in elementEnvironment.getMemberMetadata(method)) {
+      if (!constantValue.isConstructedObject) continue;
+      ObjectConstantValue value = constantValue;
+      ClassEntity cls = value.type.element;
+      if (cls == commonElements.forceInlineClass) {
+        hasForceInline = true;
+        if (VERBOSE_OPTIMIZER_HINTS) {
+          reporter.reportHintMessage(
+              method, MessageKind.GENERIC, {'text': "Must inline"});
+        }
+        annotationsDataBuilder.markAsTryInline(method);
+      } else if (cls == commonElements.noInlineClass) {
+        hasNoInline = true;
+        if (VERBOSE_OPTIMIZER_HINTS) {
+          reporter.reportHintMessage(
+              method, MessageKind.GENERIC, {'text': "Cannot inline"});
+        }
+        annotationsDataBuilder.markAsNonInlinable(method);
+      } else if (cls == commonElements.noThrowsClass) {
+        hasNoThrows = true;
+        bool isValid = true;
+        if (method.isTopLevel) {
+          isValid = true;
+        } else if (method.isStatic) {
+          isValid = true;
+        } else if (method is ConstructorEntity && method.isFactoryConstructor) {
+          isValid = true;
+        }
+        if (!isValid) {
+          reporter.internalError(
+              method,
+              "@NoThrows() is currently limited to top-level"
+              " or static functions and factory constructors.");
+        }
+        if (VERBOSE_OPTIMIZER_HINTS) {
+          reporter.reportHintMessage(
+              method, MessageKind.GENERIC, {'text': "Cannot throw"});
+        }
+        annotationsDataBuilder.registerCannotThrow(method);
+      } else if (cls == commonElements.noSideEffectsClass) {
+        hasNoSideEffects = true;
+        if (VERBOSE_OPTIMIZER_HINTS) {
+          reporter.reportHintMessage(
+              method, MessageKind.GENERIC, {'text': "Has no side effects"});
+        }
+        annotationsDataBuilder.registerSideEffectsFree(method);
+      }
+    }
+    if (hasForceInline && hasNoInline) {
+      reporter.internalError(
+          method, "@ForceInline() must not be used with @NoInline.");
+    }
+    if (hasNoThrows && !hasNoInline) {
+      reporter.internalError(
+          method, "@NoThrows() should always be combined with @NoInline.");
+    }
+    if (hasNoSideEffects && !hasNoInline) {
+      reporter.internalError(
+          method, "@NoSideEffects() should always be combined with @NoInline.");
+    }
+  }
+
+  for (MemberEntity entity in processedMembers) {
+    processMemberAnnotations(entity);
+  }
+
+  return annotationsDataBuilder;
+}
+
+abstract class AnnotationsData {
+  /// Functions with a `@NoInline()` or `@noInline` annotation.
+  Iterable<FunctionEntity> get nonInlinableFunctions;
+
+  /// Functions with a `@ForceInline()` or `@tryInline` annotation.
+  Iterable<FunctionEntity> get tryInlineFunctions;
+
+  /// Functions with a `@NoThrows()` annotation.
+  Iterable<FunctionEntity> get cannotThrowFunctions;
+
+  /// Functions with a `@NoSideEffects()` annotation.
+  Iterable<FunctionEntity> get sideEffectFreeFunctions;
+
+  /// Members with a `@TrustTypeAnnotations()` annotation.
+  Iterable<MemberEntity> get trustTypeAnnotationsMembers;
+
+  /// Members with a `@AssumeDynamic()` annotation.
+  Iterable<MemberEntity> get assumeDynamicMembers;
+}
+
+class AnnotationsDataImpl implements AnnotationsData {
+  final Iterable<FunctionEntity> nonInlinableFunctions;
+  final Iterable<FunctionEntity> tryInlineFunctions;
+  final Iterable<FunctionEntity> cannotThrowFunctions;
+  final Iterable<FunctionEntity> sideEffectFreeFunctions;
+  final Iterable<MemberEntity> trustTypeAnnotationsMembers;
+  final Iterable<MemberEntity> assumeDynamicMembers;
+
+  AnnotationsDataImpl(
+      this.nonInlinableFunctions,
+      this.tryInlineFunctions,
+      this.cannotThrowFunctions,
+      this.sideEffectFreeFunctions,
+      this.trustTypeAnnotationsMembers,
+      this.assumeDynamicMembers);
+}
+
+class AnnotationsDataBuilder implements AnnotationsData {
+  List<FunctionEntity> _nonInlinableFunctions = <FunctionEntity>[];
+  List<FunctionEntity> _tryInlinableFunctions = <FunctionEntity>[];
+  List<FunctionEntity> _cannotThrowFunctions = <FunctionEntity>[];
+  List<FunctionEntity> _sideEffectFreeFunctions = <FunctionEntity>[];
+  List<MemberEntity> _trustTypeAnnotationsMembers = <MemberEntity>[];
+  List<MemberEntity> _assumeDynamicMembers = <MemberEntity>[];
+
+  void markAsNonInlinable(FunctionEntity function) {
+    _nonInlinableFunctions.add(function);
+  }
+
+  void markAsTryInline(FunctionEntity function) {
+    _tryInlinableFunctions.add(function);
+  }
+
+  void registerCannotThrow(FunctionEntity function) {
+    _cannotThrowFunctions.add(function);
+  }
+
+  void registerSideEffectsFree(FunctionEntity function) {
+    _sideEffectFreeFunctions.add(function);
+  }
+
+  void registerTrustTypeAnnotations(MemberEntity member) {
+    _trustTypeAnnotationsMembers.add(member);
+  }
+
+  void registerAssumeDynamic(MemberEntity member) {
+    _assumeDynamicMembers.add(member);
+  }
+
+  Iterable<FunctionEntity> get nonInlinableFunctions => _nonInlinableFunctions;
+  Iterable<FunctionEntity> get tryInlineFunctions => _tryInlinableFunctions;
+  Iterable<FunctionEntity> get cannotThrowFunctions => _cannotThrowFunctions;
+  Iterable<FunctionEntity> get sideEffectFreeFunctions =>
+      _sideEffectFreeFunctions;
+  Iterable<MemberEntity> get trustTypeAnnotationsMembers =>
+      _trustTypeAnnotationsMembers;
+  Iterable<MemberEntity> get assumeDynamicMembers => _assumeDynamicMembers;
+}
diff --git a/pkg/compiler/lib/src/js_backend/backend.dart b/pkg/compiler/lib/src/js_backend/backend.dart
index 3ed2a84..8da1293 100644
--- a/pkg/compiler/lib/src/js_backend/backend.dart
+++ b/pkg/compiler/lib/src/js_backend/backend.dart
@@ -12,7 +12,6 @@
 import '../common_elements.dart' show CommonElements, ElementEnvironment;
 import '../compiler.dart' show Compiler;
 import '../constants/constant_system.dart';
-import '../constants/values.dart';
 import '../deferred_load.dart' show DeferredLoadTask, OutputUnitData;
 import '../dump_info.dart' show DumpInfoTask;
 import '../elements/entities.dart';
@@ -43,7 +42,7 @@
 import '../util/util.dart';
 import '../world.dart' show JClosedWorld;
 import 'allocator_analysis.dart';
-import 'annotations.dart' as optimizerHints;
+import 'annotations.dart';
 import 'backend_impact.dart';
 import 'backend_usage.dart';
 import 'checked_mode_helpers.dart';
@@ -61,8 +60,6 @@
 import 'resolution_listener.dart';
 import 'runtime_types.dart';
 
-const VERBOSE_OPTIMIZER_HINTS = false;
-
 abstract class FunctionCompiler {
   void onCodegenStart();
 
@@ -96,6 +93,15 @@
 
   final Set<FunctionEntity> _tryInlineFunctions = new Set<FunctionEntity>();
 
+  FunctionInlineCache(AnnotationsData annotationsData) {
+    annotationsData.nonInlinableFunctions.forEach((FunctionEntity function) {
+      markAsNonInlinable(function);
+    });
+    annotationsData.tryInlineFunctions.forEach((FunctionEntity function) {
+      markAsTryInline(function);
+    });
+  }
+
   /// Checks that [method] is the canonical representative for this method.
   ///
   /// For a [MethodElement] this means it must be the declaration element.
@@ -312,8 +318,6 @@
   final Map<MemberEntity, jsAst.Expression> generatedCode =
       <MemberEntity, jsAst.Expression>{};
 
-  FunctionInlineCache inlineCache = new FunctionInlineCache();
-
   /// If [true], the compiler will emit code that logs whenever a method is
   /// called. When TRACE_METHOD is 'console' this will be logged
   /// directly in the JavaScript console. When TRACE_METHOD is 'post' the
@@ -570,7 +574,8 @@
         commonElements,
         nativeBasicData,
         _backendUsageBuilder);
-    _allocatorResolutionAnalysis = new KAllocatorAnalysis(elementEnvironment);
+    _allocatorResolutionAnalysis =
+        new KAllocatorAnalysis(compiler.frontendStrategy);
     ClassQueries classQueries = compiler.frontendStrategy.createClassQueries();
     ClassHierarchyBuilder classHierarchyBuilder =
         new ClassHierarchyBuilder(commonElements, classQueries);
@@ -614,9 +619,7 @@
             _allocatorResolutionAnalysis,
             _nativeResolutionEnqueuer,
             noSuchMethodRegistry,
-            useStrongModeWorldStrategy
-                ? const StrongModeWorldStrategy()
-                : const OpenWorldStrategy(),
+            const StrongModeWorldStrategy(),
             classHierarchyBuilder,
             classQueries),
         compiler.frontendStrategy.createResolutionWorkItemBuilder(
@@ -668,7 +671,6 @@
             nativeCodegenEnqueuer));
   }
 
-  static bool cacheCodegenImpactForTesting = false;
   Map<MemberEntity, WorldImpact> codegenImpactsForTesting;
 
   WorldImpact codegen(CodegenWorkItem work, JClosedWorld closedWorld,
@@ -702,7 +704,7 @@
       }
       generatedCode[element] = function;
     }
-    if (cacheCodegenImpactForTesting) {
+    if (retainDataForTesting) {
       codegenImpactsForTesting ??= <MemberEntity, WorldImpact>{};
       codegenImpactsForTesting[element] = work.registry.worldImpact;
     }
@@ -759,7 +761,7 @@
   void setAnnotations(LibraryEntity library) {
     AnnotationProcessor processor =
         compiler.frontendStrategy.annotationProcesser;
-    if (canLibraryUseNative(library)) {
+    if (native.maybeEnableNative(library.canonicalUri)) {
       processor.extractNativeAnnotations(library);
     }
     processor.extractJsInteropAnnotations(library);
@@ -832,119 +834,6 @@
     tracer.close();
   }
 
-  /// Returns `true` if the `native` pseudo keyword is supported for [library].
-  bool canLibraryUseNative(LibraryEntity library) =>
-      native.maybeEnableNative(library.canonicalUri);
-
-  /// Process backend specific annotations.
-  // TODO(johnniwinther): Merge this with [AnnotationProcessor] and use
-  // [ElementEnvironment.getMemberMetadata] in [AnnotationProcessor].
-  void processAnnotations(
-      JClosedWorld closedWorld, InferredDataBuilder inferredDataBuilder) {
-    for (MemberEntity entity in closedWorld.processedMembers) {
-      _processMemberAnnotations(closedWorld, inferredDataBuilder, entity);
-    }
-  }
-
-  void _processMemberAnnotations(JClosedWorld closedWorld,
-      InferredDataBuilder inferredDataBuilder, MemberEntity element) {
-    ElementEnvironment elementEnvironment = closedWorld.elementEnvironment;
-    CommonElements commonElements = closedWorld.commonElements;
-    bool hasNoInline = false;
-    bool hasForceInline = false;
-
-    if (element.isFunction || element.isConstructor) {
-      if (optimizerHints.noInline(
-          elementEnvironment, commonElements, element)) {
-        hasNoInline = true;
-        inlineCache.markAsNonInlinable(element);
-      }
-      if (optimizerHints.tryInline(
-          elementEnvironment, commonElements, element)) {
-        hasForceInline = true;
-        if (hasNoInline) {
-          reporter.reportErrorMessage(element, MessageKind.GENERIC,
-              {'text': '@tryInline must not be used with @noInline.'});
-        } else {
-          inlineCache.markAsTryInline(element);
-        }
-      }
-    }
-
-    if (element.isField) return;
-    FunctionEntity method = element;
-
-    LibraryEntity library = method.library;
-    if (library.canonicalUri.scheme != 'dart' &&
-        !canLibraryUseNative(library)) {
-      return;
-    }
-
-    bool hasNoThrows = false;
-    bool hasNoSideEffects = false;
-    for (ConstantValue constantValue
-        in elementEnvironment.getMemberMetadata(method)) {
-      if (!constantValue.isConstructedObject) continue;
-      ObjectConstantValue value = constantValue;
-      ClassEntity cls = value.type.element;
-      if (cls == commonElements.forceInlineClass) {
-        hasForceInline = true;
-        if (VERBOSE_OPTIMIZER_HINTS) {
-          reporter.reportHintMessage(
-              method, MessageKind.GENERIC, {'text': "Must inline"});
-        }
-        inlineCache.markAsTryInline(method);
-      } else if (cls == commonElements.noInlineClass) {
-        hasNoInline = true;
-        if (VERBOSE_OPTIMIZER_HINTS) {
-          reporter.reportHintMessage(
-              method, MessageKind.GENERIC, {'text': "Cannot inline"});
-        }
-        inlineCache.markAsNonInlinable(method);
-      } else if (cls == commonElements.noThrowsClass) {
-        hasNoThrows = true;
-        bool isValid = true;
-        if (method.isTopLevel) {
-          isValid = true;
-        } else if (method.isStatic) {
-          isValid = true;
-        } else if (method is ConstructorEntity && method.isFactoryConstructor) {
-          isValid = true;
-        }
-        if (!isValid) {
-          reporter.internalError(
-              method,
-              "@NoThrows() is currently limited to top-level"
-              " or static functions and factory constructors.");
-        }
-        if (VERBOSE_OPTIMIZER_HINTS) {
-          reporter.reportHintMessage(
-              method, MessageKind.GENERIC, {'text': "Cannot throw"});
-        }
-        inferredDataBuilder.registerCannotThrow(method);
-      } else if (cls == commonElements.noSideEffectsClass) {
-        hasNoSideEffects = true;
-        if (VERBOSE_OPTIMIZER_HINTS) {
-          reporter.reportHintMessage(
-              method, MessageKind.GENERIC, {'text': "Has no side effects"});
-        }
-        inferredDataBuilder.registerSideEffectsFree(method);
-      }
-    }
-    if (hasForceInline && hasNoInline) {
-      reporter.internalError(
-          method, "@ForceInline() must not be used with @NoInline.");
-    }
-    if (hasNoThrows && !hasNoInline) {
-      reporter.internalError(
-          method, "@NoThrows() should always be combined with @NoInline.");
-    }
-    if (hasNoSideEffects && !hasNoInline) {
-      reporter.internalError(
-          method, "@NoSideEffects() should always be combined with @NoInline.");
-    }
-  }
-
   /// Enable compilation of code with compile time errors. Returns `true` if
   /// supported by the backend.
   bool enableCodegenWithErrorsIfSupported(Spannable node) => true;
diff --git a/pkg/compiler/lib/src/js_backend/inferred_data.dart b/pkg/compiler/lib/src/js_backend/inferred_data.dart
index 9ae9b5f..0d62ef1 100644
--- a/pkg/compiler/lib/src/js_backend/inferred_data.dart
+++ b/pkg/compiler/lib/src/js_backend/inferred_data.dart
@@ -10,6 +10,7 @@
 import '../universe/selector.dart';
 import '../universe/side_effects.dart';
 import '../world.dart';
+import 'annotations.dart';
 
 abstract class InferredData {
   /// Returns the side effects of executing [element].
@@ -163,7 +164,10 @@
   final Set<FunctionEntity> _functionsThatMightBePassedToApply =
       new Set<FunctionEntity>();
 
-  InferredDataBuilderImpl();
+  InferredDataBuilderImpl(AnnotationsData annotationsData) {
+    annotationsData.cannotThrowFunctions.forEach(registerCannotThrow);
+    annotationsData.sideEffectFreeFunctions.forEach(registerSideEffectsFree);
+  }
 
   @override
   SideEffectsBuilder getSideEffectsBuilder(MemberEntity member) {
diff --git a/pkg/compiler/lib/src/js_backend/namer.dart b/pkg/compiler/lib/src/js_backend/namer.dart
index 062d02f..b0ac3c1 100644
--- a/pkg/compiler/lib/src/js_backend/namer.dart
+++ b/pkg/compiler/lib/src/js_backend/namer.dart
@@ -1481,6 +1481,27 @@
     return names.join();
   }
 
+  String _getSuffixForInterceptedClasses(Iterable<ClassEntity> classes) {
+    if (classes.isEmpty) {
+      // TODO(johnniwinther,sra): If [classes] is empty it should either have
+      // its own suffix (like here), or always be equated with the set of
+      // classes that contain `Interceptor`. For the latter to work we need to
+      // update `OneShotInterceptorData.registerSpecializedGetInterceptor`,
+      // since it currently would otherwise potentially overwrite the all
+      // intercepted classes case with the empty case.
+      return 'z';
+    } else if (classes.contains(_commonElements.jsInterceptorClass)) {
+      // If the base Interceptor class is in the set of intercepted classes,
+      // this is the most general specialization which uses the generic
+      // getInterceptor method.
+      // TODO(sra): Find a way to get the simple name when Object is not in the
+      // set of classes for most general variant, e.g. "$lt$n" could be "$lt".
+      return '';
+    } else {
+      return suffixForGetInterceptor(classes);
+    }
+  }
+
   /// Property name used for a specialization of `getInterceptor`.
   ///
   /// js_runtime contains a top-level `getInterceptor` method. The
@@ -1490,9 +1511,7 @@
     // If the base Interceptor class is in the set of intercepted classes, we
     // need to go through the generic getInterceptor method (any subclass of the
     // base Interceptor could match), which is encoded as an empty suffix.
-    String suffix = classes.contains(_commonElements.jsInterceptorClass)
-        ? ''
-        : suffixForGetInterceptor(classes);
+    String suffix = _getSuffixForInterceptedClasses(classes);
     return _disambiguateInternalGlobal('getInterceptor\$$suffix');
   }
 
@@ -1505,18 +1524,9 @@
     // other global names.
     jsAst.Name root = invocationName(selector);
 
-    if (classes.contains(_commonElements.jsInterceptorClass)) {
-      // If the base Interceptor class is in the set of intercepted classes,
-      // this is the most general specialization which uses the generic
-      // getInterceptor method.
-      // TODO(sra): Find a way to get the simple name when Object is not in the
-      // set of classes for most general variant, e.g. "$lt$n" could be "$lt".
-      return new CompoundName([root, _literalDollar]);
-    } else {
-      String suffix = suffixForGetInterceptor(classes);
-      return new CompoundName(
-          [root, _literalDollar, new StringBackedName(suffix)]);
-    }
+    String suffix = _getSuffixForInterceptedClasses(classes);
+    return new CompoundName(
+        [root, _literalDollar, new StringBackedName(suffix)]);
   }
 
   /// Returns the runtime name for [element].
diff --git a/pkg/compiler/lib/src/js_backend/runtime_types.dart b/pkg/compiler/lib/src/js_backend/runtime_types.dart
index fccfdae..d2ff93c 100644
--- a/pkg/compiler/lib/src/js_backend/runtime_types.dart
+++ b/pkg/compiler/lib/src/js_backend/runtime_types.dart
@@ -4,6 +4,7 @@
 
 library js_backend.runtime_types;
 
+import '../common.dart';
 import '../common/names.dart' show Identifiers;
 import '../common_elements.dart' show CommonElements, ElementEnvironment;
 import '../elements/entities.dart';
@@ -22,8 +23,6 @@
 import 'namer.dart';
 import 'native_data.dart';
 
-bool cacheRtiDataForTesting = false;
-
 /// For each class, stores the possible class subtype tests that could succeed.
 abstract class TypeChecks {
   /// Get the set of checks required for class [element].
@@ -1737,7 +1736,7 @@
         if (methodsNeedingTypeArguments.contains(target) ||
             localFunctionsNeedingTypeArguments.contains(target)) {
           selectorsNeedingTypeArguments.add(selector);
-          if (cacheRtiDataForTesting) {
+          if (retainDataForTesting) {
             selectorsNeedingTypeArgumentsForTesting ??=
                 <Selector, Set<Entity>>{};
             selectorsNeedingTypeArgumentsForTesting
@@ -1759,7 +1758,7 @@
           // expression.
           instantiationsNeedingTypeArguments
               .add(instantiation.typeArguments.length);
-          if (cacheRtiDataForTesting) {
+          if (retainDataForTesting) {
             instantiationsNeedingTypeArgumentsForTesting ??=
                 <GenericInstantiation, Set<Entity>>{};
             instantiationsNeedingTypeArgumentsForTesting
@@ -1772,7 +1771,7 @@
       }
     });
 
-    if (cacheRtiDataForTesting) {
+    if (retainDataForTesting) {
       typeVariableTestsForTesting = typeVariableTests;
     }
 
@@ -1890,7 +1889,7 @@
     Set<DartType> implicitIsChecks = typeVariableTests.implicitIsChecks;
 
     Map<ClassEntity, ClassUse> classUseMap = <ClassEntity, ClassUse>{};
-    if (cacheRtiDataForTesting) {
+    if (retainDataForTesting) {
       classUseMapForTesting = classUseMap;
     }
 
diff --git a/pkg/compiler/lib/src/js_emitter/full_emitter/class_emitter.dart b/pkg/compiler/lib/src/js_emitter/full_emitter/class_emitter.dart
index 1e24de4..e7c3cfc 100644
--- a/pkg/compiler/lib/src/js_emitter/full_emitter/class_emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/full_emitter/class_emitter.dart
@@ -42,9 +42,8 @@
       superName = namer.className(superclass);
     }
 
-    if (cls.isMixinApplication) {
-      MixinApplication mixinApplication = cls;
-      jsAst.Name mixinName = mixinApplication.mixinClass.name;
+    if (cls.mixinClass != null) {
+      jsAst.Name mixinName = cls.mixinClass.name;
       superName = new CompoundName([superName, Namer.literalPlus, mixinName]);
       emitter.needsMixinSupport = true;
     }
@@ -226,7 +225,7 @@
   void emitInstanceMembers(Class cls, ClassBuilder builder) {
     ClassEntity classElement = cls.element;
 
-    if (cls.onlyForRti || cls.isMixinApplication) return;
+    if (cls.onlyForRti || cls.isSimpleMixinApplication) return;
 
     // TODO(herhut): This is a no-op. Should it be removed?
     for (Field field in cls.fields) {
diff --git a/pkg/compiler/lib/src/js_emitter/full_emitter/emitter.dart b/pkg/compiler/lib/src/js_emitter/full_emitter/emitter.dart
index 02253a2..40169f1 100644
--- a/pkg/compiler/lib/src/js_emitter/full_emitter/emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/full_emitter/emitter.dart
@@ -12,9 +12,9 @@
 
 import '../../../compiler_new.dart';
 import '../../common.dart';
+import '../../common_elements.dart' show CommonElements, ElementEnvironment;
 import '../../compiler.dart' show Compiler;
 import '../../constants/values.dart';
-import '../../common_elements.dart' show CommonElements, ElementEnvironment;
 import '../../deferred_load.dart' show OutputUnit, OutputUnitData;
 import '../../elements/entities.dart';
 import '../../hash/sha1.dart' show Hasher;
@@ -1351,8 +1351,11 @@
   }
 
   int emitProgram(ProgramBuilder programBuilder) {
-    Program program = programForTesting =
+    Program program =
         programBuilder.buildProgram(storeFunctionTypesInMetadata: true);
+    if (retainDataForTesting) {
+      programForTesting = program;
+    }
 
     outputStaticNonFinalFieldLists =
         programBuilder.collector.outputStaticNonFinalFieldLists;
diff --git a/pkg/compiler/lib/src/js_emitter/model.dart b/pkg/compiler/lib/src/js_emitter/model.dart
index 467648f..78d8585 100644
--- a/pkg/compiler/lib/src/js_emitter/model.dart
+++ b/pkg/compiler/lib/src/js_emitter/model.dart
@@ -237,6 +237,7 @@
   final js.Name name;
   final Holder holder;
   Class _superclass;
+  Class _mixinClass;
   final List<Method> methods;
   final List<Field> fields;
   final List<StubMethod> isChecks;
@@ -259,6 +260,8 @@
   /// A soft-deferred class is only fully initialized at first instantiation.
   final bool isSoftDeferred;
 
+  final bool isSuperMixinApplication;
+
   // If the class implements a function type, and the type is encoded in the
   // metatada table, then this field contains the index into that field.
   final js.Expression functionTypeIndex;
@@ -292,20 +295,28 @@
       this.isDirectlyInstantiated,
       this.isNative,
       this.isClosureBaseClass,
-      this.isSoftDeferred = false}) {
+      this.isSoftDeferred = false,
+      this.isSuperMixinApplication}) {
     assert(onlyForRti != null);
     assert(isDirectlyInstantiated != null);
     assert(isNative != null);
     assert(isClosureBaseClass != null);
   }
 
-  bool get isMixinApplication => false;
+  bool get isSimpleMixinApplication => false;
+
   Class get superclass => _superclass;
 
   void setSuperclass(Class superclass) {
     _superclass = superclass;
   }
 
+  Class get mixinClass => _mixinClass;
+
+  void setMixinClass(Class mixinClass) {
+    _mixinClass = mixinClass;
+  }
+
   js.Name get superclassName => superclass == null ? null : superclass.name;
 
   int get superclassHolderIndex =>
@@ -315,8 +326,6 @@
 }
 
 class MixinApplication extends Class {
-  Class _mixinClass;
-
   MixinApplication(
       ClassEntity element,
       js.Name name,
@@ -346,14 +355,10 @@
             onlyForRti: onlyForRti,
             isDirectlyInstantiated: isDirectlyInstantiated,
             isNative: false,
-            isClosureBaseClass: false);
+            isClosureBaseClass: false,
+            isSuperMixinApplication: false);
 
-  bool get isMixinApplication => true;
-  Class get mixinClass => _mixinClass;
-
-  void setMixinClass(Class mixinClass) {
-    _mixinClass = mixinClass;
-  }
+  bool get isSimpleMixinApplication => true;
 
   String toString() => 'Mixin(name=${name.key},element=$element)';
 }
diff --git a/pkg/compiler/lib/src/js_emitter/native_emitter.dart b/pkg/compiler/lib/src/js_emitter/native_emitter.dart
index 42dcf2f..0a7ccef 100644
--- a/pkg/compiler/lib/src/js_emitter/native_emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/native_emitter.dart
@@ -257,15 +257,13 @@
     return cls.methods.isEmpty &&
         cls.isChecks.isEmpty &&
         cls.callStubs.isEmpty &&
-        !cls.superclass.isMixinApplication &&
+        !cls.superclass.isSimpleMixinApplication &&
         !cls.fields.any(needsAccessor);
   }
 
   void potentiallyConvertDartClosuresToJs(List<jsAst.Statement> statements,
       FunctionEntity member, List<jsAst.Parameter> stubParameters) {
-    FunctionEntity converter = _commonElements.closureConverter;
-    jsAst.Expression closureConverter =
-        _emitterTask.staticFunctionAccess(converter);
+    jsAst.Expression closureConverter;
     _worldBuilder.forEachParameter(member, (DartType type, String name, _) {
       // If [name] is not in [stubParameters], then the parameter is an optional
       // parameter that was not provided for this stub.
@@ -273,6 +271,9 @@
         if (stubParameter.name == name) {
           type = type.unaliased;
           if (type.isFunctionType) {
+            closureConverter ??= _emitterTask
+                .staticFunctionAccess(_commonElements.closureConverter);
+
             // The parameter type is a function type either directly or through
             // typedef(s).
             FunctionType functionType = type;
diff --git a/pkg/compiler/lib/src/js_emitter/program_builder/program_builder.dart b/pkg/compiler/lib/src/js_emitter/program_builder/program_builder.dart
index 4138b1f..de9d367 100644
--- a/pkg/compiler/lib/src/js_emitter/program_builder/program_builder.dart
+++ b/pkg/compiler/lib/src/js_emitter/program_builder/program_builder.dart
@@ -211,7 +211,7 @@
                 "No Class for has been created for superclass "
                 "${superclass} of $c."));
       }
-      if (c is MixinApplication) {
+      if (c.isSimpleMixinApplication || c.isSuperMixinApplication) {
         ClassEntity effectiveMixinClass =
             _elementEnvironment.getEffectiveMixinClass(cls);
         c.setMixinClass(_classes[effectiveMixinClass]);
@@ -690,18 +690,32 @@
       callStubs.add(_buildStubMethod(name, function));
     }
 
-    if (_commonElements.isInstantiationClass(cls)) {
+    if (_commonElements.isInstantiationClass(cls) && !onlyForRti) {
       callStubs.addAll(_generateInstantiationStubs(cls));
     }
 
     // MixinApplications run through the members of their mixin. Here, we are
     // only interested in direct members.
-    if (!onlyForRti && !_elementEnvironment.isMixinApplication(cls)) {
-      List<MemberEntity> members = <MemberEntity>[];
-      _elementEnvironment.forEachLocalClassMember(cls, members.add);
-      _elementEnvironment.forEachInjectedClassMember(cls, members.add);
-      _elementEnvironment.forEachConstructorBody(cls, members.add);
-      _sorter.sortMembers(members).forEach(visitMember);
+    bool isSuperMixinApplication = false;
+    if (!onlyForRti) {
+      if (_elementEnvironment.isSuperMixinApplication(cls)) {
+        List<MemberEntity> members = <MemberEntity>[];
+        _elementEnvironment.forEachLocalClassMember(cls, (MemberEntity member) {
+          if (member.enclosingClass == cls) {
+            members.add(member);
+            isSuperMixinApplication = true;
+          }
+        });
+        if (members.isNotEmpty) {
+          _sorter.sortMembers(members).forEach(visitMember);
+        }
+      } else if (!_elementEnvironment.isMixinApplication(cls)) {
+        List<MemberEntity> members = <MemberEntity>[];
+        _elementEnvironment.forEachLocalClassMember(cls, members.add);
+        _elementEnvironment.forEachInjectedClassMember(cls, members.add);
+        _elementEnvironment.forEachConstructorBody(cls, members.add);
+        _sorter.sortMembers(members).forEach(visitMember);
+      }
     }
     bool isInterceptedClass = _interceptorData.isInterceptedClass(cls);
     List<Field> instanceFields = onlyForRti
@@ -759,7 +773,9 @@
         _worldBuilder.directlyInstantiatedClasses.contains(cls);
 
     Class result;
-    if (_elementEnvironment.isMixinApplication(cls) && !onlyForRti) {
+    if (_elementEnvironment.isMixinApplication(cls) &&
+        !onlyForRti &&
+        !isSuperMixinApplication) {
       assert(!_nativeData.isNativeClass(cls));
       assert(methods.isEmpty);
       assert(!isClosureBaseClass);
@@ -795,7 +811,8 @@
           onlyForRti: onlyForRti,
           isNative: _nativeData.isNativeClass(cls),
           isClosureBaseClass: isClosureBaseClass,
-          isSoftDeferred: _isSoftDeferred(cls));
+          isSoftDeferred: _isSoftDeferred(cls),
+          isSuperMixinApplication: isSuperMixinApplication);
     }
     _classes[cls] = result;
     return result;
diff --git a/pkg/compiler/lib/src/js_emitter/startup_emitter/emitter.dart b/pkg/compiler/lib/src/js_emitter/startup_emitter/emitter.dart
index 0e3e5a4..e653943 100644
--- a/pkg/compiler/lib/src/js_emitter/startup_emitter/emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/startup_emitter/emitter.dart
@@ -61,7 +61,10 @@
 
   @override
   int emitProgram(ProgramBuilder programBuilder) {
-    Program program = programForTesting = programBuilder.buildProgram();
+    Program program = programBuilder.buildProgram();
+    if (retainDataForTesting) {
+      programForTesting = program;
+    }
     return _emitter.emitProgram(program);
   }
 
diff --git a/pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_emitter.dart b/pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_emitter.dart
index ad0cb13..46ae073 100644
--- a/pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_emitter.dart
@@ -1018,10 +1018,9 @@
         if (cls.isSoftDeferred != softDeferred) continue;
         collect(cls);
 
-        if (cls.isMixinApplication) {
-          MixinApplication mixin = cls;
+        if (cls.mixinClass != null) {
           mixinCalls.add(js.js.statement('mixin(#, #)',
-              [classReference(cls), classReference(mixin.mixinClass)]));
+              [classReference(cls), classReference(cls.mixinClass)]));
         }
       }
     }
diff --git a/pkg/compiler/lib/src/js_model/closure.dart b/pkg/compiler/lib/src/js_model/closure.dart
index ecb5a5f..78d6a94 100644
--- a/pkg/compiler/lib/src/js_model/closure.dart
+++ b/pkg/compiler/lib/src/js_model/closure.dart
@@ -12,8 +12,12 @@
 import '../elements/entities.dart';
 import '../elements/names.dart' show Name;
 import '../elements/types.dart';
+import '../ir/element_map.dart';
+import '../ir/util.dart';
+import '../js_model/element_map.dart';
 import '../kernel/element_map.dart';
 import '../kernel/env.dart';
+import '../ordered_typeset.dart';
 import '../options.dart';
 import '../ssa/type_builder.dart';
 import '../universe/selector.dart';
@@ -74,7 +78,7 @@
 // ClosureConversionTask doesn't inherit from ClosureTask because it's just a
 // glorified timer.
 class KernelClosureConversionTask extends ClosureConversionTask {
-  final KernelToElementMapForBuilding _elementMap;
+  final JsToElementMap _elementMap;
   final GlobalLocalsMap _globalLocalsMap;
   final CompilerOptions _options;
 
@@ -627,8 +631,8 @@
 
 /// Helper method to get or create a Local variable out of a variable
 /// declaration or type parameter.
-Local _getLocal(ir.Node variable, KernelToLocalsMap localsMap,
-    KernelToElementMap elementMap) {
+Local _getLocal(
+    ir.Node variable, KernelToLocalsMap localsMap, JsToElementMap elementMap) {
   assert(variable is ir.VariableDeclaration ||
       variable is TypeVariableTypeWithContext);
   if (variable is ir.VariableDeclaration) {
@@ -651,7 +655,7 @@
   final Set<Local> freeVariables;
 
   JsScopeInfo.from(this.boxedVariables, KernelScopeInfo info,
-      KernelToLocalsMap localsMap, KernelToElementMap elementMap)
+      KernelToLocalsMap localsMap, JsToElementMap elementMap)
       : this.thisLocal =
             info.hasThisLocal ? new ThisLocal(localsMap.currentMember) : null,
         this.localsUsedInTryOrSync =
@@ -731,7 +735,7 @@
       Map<Local, JRecordField> boxedVariables,
       KernelCapturedScope capturedScope,
       KernelToLocalsMap localsMap,
-      KernelToElementMap elementMap)
+      JsToElementMap elementMap)
       : this.context =
             boxedVariables.isNotEmpty ? boxedVariables.values.first.box : null,
         super.from(boxedVariables, capturedScope, localsMap, elementMap);
@@ -773,7 +777,7 @@
       Map<Local, JRecordField> boxedVariables,
       KernelCapturedLoopScope capturedScope,
       KernelToLocalsMap localsMap,
-      KernelToElementMap elementMap)
+      JsToElementMap elementMap)
       : this.boxedLoopVariables = capturedScope.boxedLoopVariables
             .map(localsMap.getLocalVariable)
             .toList(),
@@ -801,7 +805,7 @@
       KernelToLocalsMap localsMap,
       this.closureEntity,
       this.thisLocal,
-      KernelToElementMap elementMap)
+      JsToElementMap elementMap)
       : super.from(boxedVariables, info, localsMap, elementMap);
 
   List<Local> get createdFieldEntities => localToFieldMap.keys.toList();
@@ -873,6 +877,48 @@
   Entity get rootOfScope => enclosingClass;
 }
 
+class RecordClassData implements ClassData {
+  @override
+  final ClassDefinition definition;
+
+  @override
+  final InterfaceType thisType;
+
+  @override
+  final OrderedTypeSet orderedTypeSet;
+
+  @override
+  final InterfaceType supertype;
+
+  RecordClassData(
+      this.definition, this.thisType, this.supertype, this.orderedTypeSet);
+
+  @override
+  ClassData copy() => this;
+
+  @override
+  Iterable<ConstantValue> getMetadata(IrToElementMap elementMap) =>
+      const <ConstantValue>[];
+
+  @override
+  bool get isMixinApplication => false;
+
+  @override
+  bool get isEnumClass => false;
+
+  @override
+  DartType get callType => null;
+
+  @override
+  List<InterfaceType> get interfaces => const <InterfaceType>[];
+
+  @override
+  InterfaceType get mixedInType => null;
+
+  @override
+  InterfaceType get rawType => thisType;
+}
+
 /// A container for variables declared in a particular scope that are accessed
 /// elsewhere.
 // TODO(efortuna, johnniwinther): Don't implement JClass. This isn't actually a
@@ -902,6 +948,15 @@
   bool get isInstanceMember => false;
 }
 
+class ClosureClassData extends RecordClassData {
+  @override
+  FunctionType callType;
+
+  ClosureClassData(ClassDefinition definition, InterfaceType thisType,
+      InterfaceType supertype, OrderedTypeSet orderedTypeSet)
+      : super(definition, thisType, supertype, orderedTypeSet);
+}
+
 class ClosureClassDefinition implements ClassDefinition {
   final ClassEntity cls;
   final SourceSpan location;
@@ -924,12 +979,12 @@
   ClosureMemberData(this.definition, this.memberThisType);
 
   @override
-  Iterable<ConstantValue> getMetadata(KernelToElementMap elementMap) {
+  Iterable<ConstantValue> getMetadata(IrToElementMap elementMap) {
     return const <ConstantValue>[];
   }
 
   @override
-  InterfaceType getMemberThisType(KernelToElementMapForBuilding elementMap) {
+  InterfaceType getMemberThisType(JsToElementMap elementMap) {
     return memberThisType;
   }
 }
@@ -949,7 +1004,7 @@
       this.classTypeVariableAccess)
       : super(definition, memberThisType);
 
-  void forEachParameter(KernelToElementMapForBuilding elementMap,
+  void forEachParameter(JsToElementMap elementMap,
       void f(DartType type, String name, ConstantValue defaultValue)) {
     void handleParameter(ir.VariableDeclaration node, {bool isOptional: true}) {
       DartType type = elementMap.getDartType(node.type);
@@ -975,7 +1030,7 @@
   }
 
   @override
-  FunctionType getFunctionType(KernelToElementMap elementMap) {
+  FunctionType getFunctionType(IrToElementMap elementMap) {
     return functionType;
   }
 }
@@ -986,7 +1041,7 @@
       : super(definition, memberThisType);
 
   @override
-  DartType getFieldType(KernelToElementMap elementMap) {
+  DartType getFieldType(IrToElementMap elementMap) {
     if (_type != null) return _type;
     ir.TreeNode sourceNode = definition.node;
     ir.DartType type;
@@ -1012,7 +1067,7 @@
   }
 
   @override
-  ConstantExpression getFieldConstantExpression(KernelToElementMap elementMap) {
+  ConstantExpression getFieldConstantExpression(IrToElementMap elementMap) {
     failedAt(
         definition.member,
         "Unexpected field ${definition.member} in "
@@ -1021,7 +1076,7 @@
   }
 
   @override
-  ConstantValue getConstantFieldInitializer(KernelToElementMap elementMap) {
+  ConstantValue getConstantFieldInitializer(IrToElementMap elementMap) {
     failedAt(
         definition.member,
         "Unexpected field ${definition.member} in "
@@ -1030,12 +1085,12 @@
   }
 
   @override
-  bool hasConstantFieldInitializer(KernelToElementMap elementMap) {
+  bool hasConstantFieldInitializer(IrToElementMap elementMap) {
     return false;
   }
 
   @override
-  ConstantValue getFieldConstantValue(KernelToElementMap elementMap) {
+  ConstantValue getFieldConstantValue(IrToElementMap elementMap) {
     return null;
   }
 
diff --git a/pkg/compiler/lib/src/js_model/element_map.dart b/pkg/compiler/lib/src/js_model/element_map.dart
new file mode 100644
index 0000000..32e0c66
--- /dev/null
+++ b/pkg/compiler/lib/src/js_model/element_map.dart
@@ -0,0 +1,330 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for 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' as ir;
+
+import '../common.dart';
+import '../constants/values.dart';
+import '../common_elements.dart';
+import '../elements/entities.dart';
+import '../elements/jumps.dart';
+import '../elements/names.dart';
+import '../elements/types.dart';
+import '../js/js.dart' as js;
+import '../js_backend/namer.dart';
+import '../js_emitter/code_emitter_task.dart';
+import '../js_model/closure.dart' show JRecordField, KernelScopeInfo;
+import '../js_model/elements.dart' show JGeneratorBody;
+import '../kernel/element_map.dart';
+import '../native/native.dart' as native;
+import '../ssa/type_builder.dart';
+import '../types/abstract_value_domain.dart';
+import '../universe/call_structure.dart';
+import '../universe/selector.dart';
+import '../world.dart';
+
+/// Interface that translates between Kernel IR nodes and entities used for
+/// global type inference and building the SSA graph for members.
+abstract class JsToElementMap {
+  /// Access to the commonly used elements and types.
+  CommonElements get commonElements;
+
+  /// Access to the [DartTypes] object.
+  DartTypes get types;
+
+  /// Returns the [DartType] corresponding to [type].
+  DartType getDartType(ir.DartType type);
+
+  /// Returns the [InterfaceType] corresponding to [type].
+  InterfaceType getInterfaceType(ir.InterfaceType type);
+
+  /// Returns the [TypeVariableType] corresponding to [type].
+  TypeVariableType getTypeVariableType(ir.TypeParameterType type);
+
+  /// Returns the [FunctionType] of the [node].
+  FunctionType getFunctionType(ir.FunctionNode node);
+
+  /// Return the [InterfaceType] corresponding to the [cls] with the given
+  /// [typeArguments].
+  InterfaceType createInterfaceType(
+      ir.Class cls, List<ir.DartType> typeArguments);
+
+  /// Returns the [CallStructure] corresponding to the [arguments].
+  CallStructure getCallStructure(ir.Arguments arguments);
+
+  /// Returns the [Selector] corresponding to the invocation or getter/setter
+  /// access of [node].
+  Selector getSelector(ir.Expression node);
+
+  /// Returns the [MemberEntity] corresponding to the member [node].
+  MemberEntity getMember(ir.Member node);
+
+  /// Returns the [FunctionEntity] corresponding to the procedure [node].
+  FunctionEntity getMethod(ir.Procedure node);
+
+  /// Returns the [ConstructorEntity] corresponding to the generative or factory
+  /// constructor [node].
+  ConstructorEntity getConstructor(ir.Member node);
+
+  /// Returns the [FieldEntity] corresponding to the field [node].
+  FieldEntity getField(ir.Field node);
+
+  /// Returns the [ClassEntity] corresponding to the class [node].
+  ClassEntity getClass(ir.Class node);
+
+  /// Returns the [TypedefType] corresponding to raw type of the typedef [node].
+  TypedefType getTypedefType(ir.Typedef node);
+
+  /// Returns the super [MemberEntity] for a super invocation, get or set of
+  /// [name] from the member [context].
+  ///
+  /// The IR doesn't always resolve super accesses to the corresponding
+  /// [target]. If not, the target is computed using [name] and [setter] from
+  /// the enclosing class of [context].
+  MemberEntity getSuperMember(
+      MemberEntity context, ir.Name name, ir.Member target,
+      {bool setter: false});
+
+  /// Returns the `noSuchMethod` [FunctionEntity] call from a
+  /// `super.noSuchMethod` invocation within [cls].
+  FunctionEntity getSuperNoSuchMethod(ClassEntity cls);
+
+  /// Returns the [Name] corresponding to [name].
+  Name getName(ir.Name name);
+
+  /// Computes the [native.NativeBehavior] for a call to the [JS] function.
+  native.NativeBehavior getNativeBehaviorForJsCall(ir.StaticInvocation node);
+
+  /// Computes the [native.NativeBehavior] for a call to the [JS_BUILTIN]
+  /// function.
+  native.NativeBehavior getNativeBehaviorForJsBuiltinCall(
+      ir.StaticInvocation node);
+
+  /// Computes the [native.NativeBehavior] for a call to the
+  /// [JS_EMBEDDED_GLOBAL] function.
+  native.NativeBehavior getNativeBehaviorForJsEmbeddedGlobalCall(
+      ir.StaticInvocation node);
+
+  /// Returns the [js.Name] for the `JsGetName` [constant] value.
+  js.Name getNameForJsGetName(ConstantValue constant, Namer namer);
+
+  /// Computes the [ConstantValue] for the constant [expression].
+  // TODO(johnniwinther): Move to [KernelToElementMapForBuilding]. This is only
+  // used in impact builder for symbol constants.
+  ConstantValue getConstantValue(ir.Expression expression,
+      {bool requireConstant: true, bool implicitNull: false});
+
+  /// Return the [ImportEntity] corresponding to [node].
+  ImportEntity getImport(ir.LibraryDependency node);
+
+  /// Returns the definition information for [cls].
+  ClassDefinition getClassDefinition(covariant ClassEntity cls);
+
+  /// Returns the static type of [node].
+  // TODO(johnniwinther): This should be provided directly from kernel.
+  DartType getStaticType(ir.Expression node);
+
+  /// [ElementEnvironment] for library, class and member lookup.
+  ElementEnvironment get elementEnvironment;
+
+  /// Returns the list of [DartType]s corresponding to [types].
+  List<DartType> getDartTypes(List<ir.DartType> types);
+
+  /// Returns the definition information for [member].
+  MemberDefinition getMemberDefinition(covariant MemberEntity member);
+
+  /// Returns the type of `this` in [member], or `null` if member is defined in
+  /// a static context.
+  InterfaceType getMemberThisType(covariant MemberEntity member);
+
+  /// Returns how [member] has access to type variables of the this type
+  /// returned by [getMemberThisType].
+  ClassTypeVariableAccess getClassTypeVariableAccessForMember(
+      MemberEntity member);
+
+  /// Returns the [LibraryEntity] corresponding to the library [node].
+  LibraryEntity getLibrary(ir.Library node);
+
+  /// Returns the [js.Template] for the `JsBuiltin` [constant] value.
+  js.Template getJsBuiltinTemplate(
+      ConstantValue constant, CodeEmitterTask emitter);
+
+  /// Return the [ConstantValue] the initial value of [field] or `null` if
+  /// the initializer is not a constant expression.
+  ConstantValue getFieldConstantValue(FieldEntity field);
+
+  /// Returns a [Spannable] for a message pointing to the IR [node] in the
+  /// context of [member].
+  Spannable getSpannable(MemberEntity member, ir.Node node);
+
+  /// Returns the constructor body entity corresponding to [constructor].
+  FunctionEntity getConstructorBody(ir.Constructor node);
+
+  /// Returns the constructor body entity corresponding to [function].
+  JGeneratorBody getGeneratorBody(FunctionEntity function);
+
+  /// Make a record to ensure variables that are are declared in one scope and
+  /// modified in another get their values updated correctly.
+  Map<Local, JRecordField> makeRecordContainer(
+      KernelScopeInfo info, MemberEntity member, KernelToLocalsMap localsMap);
+}
+
+/// Interface for type inference results for kernel IR nodes.
+abstract class KernelToTypeInferenceMap {
+  /// Returns the inferred return type of [function].
+  AbstractValue getReturnTypeOf(FunctionEntity function);
+
+  /// Returns the inferred receiver type of the dynamic [invocation].
+  AbstractValue receiverTypeOfInvocation(
+      ir.MethodInvocation invocation, AbstractValueDomain abstractValueDomain);
+
+  /// Returns the inferred receiver type of the dynamic [read].
+  AbstractValue receiverTypeOfGet(ir.PropertyGet read);
+
+  /// Returns the inferred receiver type of the direct [read].
+  AbstractValue receiverTypeOfDirectGet(ir.DirectPropertyGet read);
+
+  /// Returns the inferred receiver type of the dynamic [write].
+  AbstractValue receiverTypeOfSet(
+      ir.PropertySet write, AbstractValueDomain abstractValueDomain);
+
+  /// Returns the inferred type of [listLiteral].
+  AbstractValue typeOfListLiteral(MemberEntity owner,
+      ir.ListLiteral listLiteral, AbstractValueDomain abstractValueDomain);
+
+  /// Returns the inferred type of iterator in [forInStatement].
+  AbstractValue typeOfIterator(ir.ForInStatement forInStatement);
+
+  /// Returns the inferred type of `current` in [forInStatement].
+  AbstractValue typeOfIteratorCurrent(ir.ForInStatement forInStatement);
+
+  /// Returns the inferred type of `moveNext` in [forInStatement].
+  AbstractValue typeOfIteratorMoveNext(ir.ForInStatement forInStatement);
+
+  /// Returns `true` if [forInStatement] is inferred to be a JavaScript
+  /// indexable iterator.
+  bool isJsIndexableIterator(ir.ForInStatement forInStatement,
+      AbstractValueDomain abstractValueDomain);
+
+  /// Returns the inferred index type of [forInStatement].
+  AbstractValue inferredIndexType(ir.ForInStatement forInStatement);
+
+  /// Returns the inferred type of [member].
+  AbstractValue getInferredTypeOf(MemberEntity member);
+
+  /// Returns the inferred type of the [parameter].
+  AbstractValue getInferredTypeOfParameter(Local parameter);
+
+  /// Returns the inferred type of a dynamic [selector] access on the
+  /// [receiver].
+  AbstractValue selectorTypeOf(Selector selector, AbstractValue receiver);
+
+  /// Returns the returned type annotation in the [nativeBehavior].
+  AbstractValue typeFromNativeBehavior(
+      native.NativeBehavior nativeBehavior, JClosedWorld closedWorld);
+}
+
+/// Map from kernel IR nodes to local entities.
+abstract class KernelToLocalsMap {
+  /// The member currently being built.
+  MemberEntity get currentMember;
+
+  /// Returns the [Local] for [node].
+  Local getLocalVariable(ir.VariableDeclaration node);
+
+  Local getLocalTypeVariable(
+      ir.TypeParameterType node, JsToElementMap elementMap);
+
+  /// Returns the [ir.FunctionNode] that declared [parameter].
+  ir.FunctionNode getFunctionNodeForParameter(Local parameter);
+
+  /// Returns the [DartType] of [local].
+  DartType getLocalType(JsToElementMap elementMap, Local local);
+
+  /// Returns the [JumpTarget] for the break statement [node].
+  JumpTarget getJumpTargetForBreak(ir.BreakStatement node);
+
+  /// Returns `true` if [node] should generate a `continue` to its [JumpTarget].
+  bool generateContinueForBreak(ir.BreakStatement node);
+
+  /// Returns the [JumpTarget] defined by the labelled statement [node] or
+  /// `null` if [node] is not a jump target.
+  JumpTarget getJumpTargetForLabel(ir.LabeledStatement node);
+
+  /// Returns the [JumpTarget] defined by the switch statement [node] or `null`
+  /// if [node] is not a jump target.
+  JumpTarget getJumpTargetForSwitch(ir.SwitchStatement node);
+
+  /// Returns the [JumpTarget] for the continue switch statement [node].
+  JumpTarget getJumpTargetForContinueSwitch(ir.ContinueSwitchStatement node);
+
+  /// Returns the [JumpTarget] defined by the switch case [node] or `null`
+  /// if [node] is not a jump target.
+  JumpTarget getJumpTargetForSwitchCase(ir.SwitchCase node);
+
+  /// Returns the [JumpTarget] defined the do statement [node] or `null`
+  /// if [node] is not a jump target.
+  JumpTarget getJumpTargetForDo(ir.DoStatement node);
+
+  /// Returns the [JumpTarget] defined by the for statement [node] or `null`
+  /// if [node] is not a jump target.
+  JumpTarget getJumpTargetForFor(ir.ForStatement node);
+
+  /// Returns the [JumpTarget] defined by the for-in statement [node] or `null`
+  /// if [node] is not a jump target.
+  JumpTarget getJumpTargetForForIn(ir.ForInStatement node);
+
+  /// Returns the [JumpTarget] defined by the while statement [node] or `null`
+  /// if [node] is not a jump target.
+  JumpTarget getJumpTargetForWhile(ir.WhileStatement node);
+}
+
+/// Returns the [ir.FunctionNode] that defines [member] or `null` if [member]
+/// is not a constructor, method or local function.
+ir.FunctionNode getFunctionNode(
+    JsToElementMap elementMap, MemberEntity member) {
+  MemberDefinition definition = elementMap.getMemberDefinition(member);
+  switch (definition.kind) {
+    case MemberKind.regular:
+      ir.Node node = definition.node;
+      if (node is ir.Procedure) {
+        return node.function;
+      }
+      break;
+    case MemberKind.constructor:
+    case MemberKind.constructorBody:
+      ir.Node node = definition.node;
+      if (node is ir.Procedure) {
+        return node.function;
+      } else if (node is ir.Constructor) {
+        return node.function;
+      }
+      break;
+    case MemberKind.closureCall:
+      ir.Node node = definition.node;
+      if (node is ir.FunctionDeclaration) {
+        return node.function;
+      } else if (node is ir.FunctionExpression) {
+        return node.function;
+      }
+      break;
+    default:
+  }
+  return null;
+}
+
+/// Returns the initializer for [field].
+///
+/// If [field] is an instance field with a null literal initializer `null` is
+/// returned, otherwise the initializer of the [ir.Field] is returned.
+ir.Node getFieldInitializer(JsToElementMap elementMap, FieldEntity field) {
+  MemberDefinition definition = elementMap.getMemberDefinition(field);
+  ir.Field node = definition.node;
+  if (node.isInstanceMember &&
+      !node.isFinal &&
+      node.initializer is ir.NullLiteral) {
+    return null;
+  }
+  return node.initializer;
+}
diff --git a/pkg/compiler/lib/src/js_model/element_map_impl.dart b/pkg/compiler/lib/src/js_model/element_map_impl.dart
new file mode 100644
index 0000000..296d67c
--- /dev/null
+++ b/pkg/compiler/lib/src/js_model/element_map_impl.dart
@@ -0,0 +1,807 @@
+// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
+// for 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:js_runtime/shared/embedded_names.dart';
+import 'package:kernel/ast.dart' as ir;
+import 'package:kernel/class_hierarchy.dart' as ir;
+import 'package:kernel/core_types.dart' as ir;
+import 'package:kernel/type_environment.dart' as ir;
+
+import '../closure.dart' show BoxLocal, ThisLocal;
+import '../common.dart';
+import '../constants/values.dart';
+import '../elements/entities.dart';
+import '../elements/entity_utils.dart' as utils;
+import '../elements/indexed.dart';
+import '../elements/types.dart';
+import '../environment.dart';
+import '../ir/util.dart';
+import '../js/js.dart' as js;
+import '../js_backend/native_data.dart';
+import '../js_emitter/code_emitter_task.dart';
+import '../js_model/closure.dart';
+import '../js_model/elements.dart';
+import '../js_model/element_map.dart';
+import '../js_model/locals.dart';
+import '../kernel/element_map.dart';
+import '../kernel/element_map_impl.dart';
+import '../kernel/env.dart';
+import '../ssa/type_builder.dart';
+
+import 'element_map.dart';
+
+/// Interface for kernel queries needed to implement the [CodegenWorldBuilder].
+abstract class KernelToWorldBuilder implements JsToElementMap {
+  /// Returns `true` if [field] has a constant initializer.
+  bool hasConstantFieldInitializer(FieldEntity field);
+
+  /// Returns the constant initializer for [field].
+  ConstantValue getConstantFieldInitializer(FieldEntity field);
+
+  /// Calls [f] for each parameter of [function] providing the type and name of
+  /// the parameter and the [defaultValue] if the parameter is optional.
+  void forEachParameter(FunctionEntity function,
+      void f(DartType type, String name, ConstantValue defaultValue));
+}
+
+class JsKernelToElementMap extends KernelToElementMapBase
+    with JsElementCreatorMixin
+    implements KernelToWorldBuilder, JsToElementMap {
+  final Map<ir.Library, IndexedLibrary> libraryMap = {};
+  final Map<ir.Class, IndexedClass> classMap = {};
+  final Map<ir.Typedef, IndexedTypedef> typedefMap = {};
+
+  /// Map from [ir.TypeParameter] nodes to the corresponding
+  /// [TypeVariableEntity].
+  ///
+  /// Normally the type variables are [IndexedTypeVariable]s, but for type
+  /// parameters on local function (in the frontend) these are _not_ since
+  /// their type declaration is neither a class nor a member. In the backend,
+  /// these type parameters belong to the call-method and are therefore indexed.
+  final Map<ir.TypeParameter, TypeVariableEntity> typeVariableMap = {};
+  final Map<ir.Member, IndexedConstructor> constructorMap = {};
+  final Map<ir.Procedure, IndexedFunction> methodMap = {};
+  final Map<ir.Field, IndexedField> fieldMap = {};
+  final Map<ir.TreeNode, Local> localFunctionMap = {};
+
+  /// Map from members to the call methods created for their nested closures.
+  Map<MemberEntity, List<FunctionEntity>> _nestedClosureMap =
+      <MemberEntity, List<FunctionEntity>>{};
+
+  @override
+  NativeBasicData nativeBasicData;
+
+  Map<FunctionEntity, JGeneratorBody> _generatorBodies = {};
+
+  Map<ClassEntity, List<MemberEntity>> _injectedClassMembers = {};
+
+  JsKernelToElementMap(DiagnosticReporter reporter, Environment environment,
+      KernelToElementMapImpl _elementMap, Iterable<MemberEntity> liveMembers)
+      : super(_elementMap.options, reporter, environment) {
+    env = _elementMap.env;
+    for (int libraryIndex = 0;
+        libraryIndex < _elementMap.libraries.length;
+        libraryIndex++) {
+      IndexedLibrary oldLibrary = _elementMap.libraries.getEntity(libraryIndex);
+      LibraryEnv env = _elementMap.libraries.getEnv(oldLibrary);
+      LibraryData data = _elementMap.libraries.getData(oldLibrary);
+      IndexedLibrary newLibrary = convertLibrary(oldLibrary);
+      libraryMap[env.library] =
+          libraries.register<IndexedLibrary, LibraryData, LibraryEnv>(
+              newLibrary, data.copy(), env.copyLive(_elementMap, liveMembers));
+      assert(newLibrary.libraryIndex == oldLibrary.libraryIndex);
+    }
+    for (int classIndex = 0;
+        classIndex < _elementMap.classes.length;
+        classIndex++) {
+      IndexedClass oldClass = _elementMap.classes.getEntity(classIndex);
+      ClassEnv env = _elementMap.classes.getEnv(oldClass);
+      ClassData data = _elementMap.classes.getData(oldClass);
+      IndexedLibrary oldLibrary = oldClass.library;
+      LibraryEntity newLibrary = libraries.getEntity(oldLibrary.libraryIndex);
+      IndexedClass newClass = convertClass(newLibrary, oldClass);
+      classMap[env.cls] = classes.register(
+          newClass, data.copy(), env.copyLive(_elementMap, liveMembers));
+      assert(newClass.classIndex == oldClass.classIndex);
+    }
+    for (int typedefIndex = 0;
+        typedefIndex < _elementMap.typedefs.length;
+        typedefIndex++) {
+      IndexedTypedef oldTypedef = _elementMap.typedefs.getEntity(typedefIndex);
+      TypedefData data = _elementMap.typedefs.getData(oldTypedef);
+      IndexedLibrary oldLibrary = oldTypedef.library;
+      LibraryEntity newLibrary = libraries.getEntity(oldLibrary.libraryIndex);
+      IndexedTypedef newTypedef = convertTypedef(newLibrary, oldTypedef);
+      typedefMap[data.node] = typedefs.register(
+          newTypedef,
+          new TypedefData(
+              data.node,
+              newTypedef,
+              new TypedefType(
+                  newTypedef,
+                  new List<DartType>.filled(
+                      data.node.typeParameters.length, const DynamicType()),
+                  getDartType(data.node.type))));
+      assert(newTypedef.typedefIndex == oldTypedef.typedefIndex);
+    }
+    for (int memberIndex = 0;
+        memberIndex < _elementMap.members.length;
+        memberIndex++) {
+      IndexedMember oldMember = _elementMap.members.getEntity(memberIndex);
+      if (!liveMembers.contains(oldMember)) {
+        members.skipIndex(oldMember.memberIndex);
+        continue;
+      }
+      MemberDataImpl data = _elementMap.members.getData(oldMember);
+      IndexedLibrary oldLibrary = oldMember.library;
+      IndexedClass oldClass = oldMember.enclosingClass;
+      LibraryEntity newLibrary = libraries.getEntity(oldLibrary.libraryIndex);
+      ClassEntity newClass =
+          oldClass != null ? classes.getEntity(oldClass.classIndex) : null;
+      IndexedMember newMember = convertMember(newLibrary, newClass, oldMember);
+      members.register(newMember, data.copy());
+      assert(newMember.memberIndex == oldMember.memberIndex);
+      if (newMember.isField) {
+        fieldMap[data.node] = newMember;
+      } else if (newMember.isConstructor) {
+        constructorMap[data.node] = newMember;
+      } else {
+        methodMap[data.node] = newMember;
+      }
+    }
+    for (int typeVariableIndex = 0;
+        typeVariableIndex < _elementMap.typeVariables.length;
+        typeVariableIndex++) {
+      IndexedTypeVariable oldTypeVariable =
+          _elementMap.typeVariables.getEntity(typeVariableIndex);
+      TypeVariableData oldTypeVariableData =
+          _elementMap.typeVariables.getData(oldTypeVariable);
+      Entity newTypeDeclaration;
+      if (oldTypeVariable.typeDeclaration is ClassEntity) {
+        IndexedClass cls = oldTypeVariable.typeDeclaration;
+        newTypeDeclaration = classes.getEntity(cls.classIndex);
+      } else if (oldTypeVariable.typeDeclaration is MemberEntity) {
+        IndexedMember member = oldTypeVariable.typeDeclaration;
+        newTypeDeclaration = members.getEntity(member.memberIndex);
+      } else {
+        assert(oldTypeVariable.typeDeclaration is Local);
+      }
+      IndexedTypeVariable newTypeVariable = createTypeVariable(
+          newTypeDeclaration, oldTypeVariable.name, oldTypeVariable.index);
+      typeVariableMap[oldTypeVariableData.node] =
+          typeVariables.register<IndexedTypeVariable, TypeVariableData>(
+              newTypeVariable, oldTypeVariableData.copy());
+      assert(newTypeVariable.typeVariableIndex ==
+          oldTypeVariable.typeVariableIndex);
+    }
+    //typeVariableMap.keys.forEach((n) => print(n.parent));
+    // TODO(johnniwinther): We should close the environment in the beginning of
+    // this constructor but currently we need the [MemberEntity] to query if the
+    // member is live, thus potentially creating the [MemberEntity] in the
+    // process. Avoid this.
+    _elementMap.envIsClosed = true;
+  }
+
+  @override
+  void forEachNestedClosure(
+      MemberEntity member, void f(FunctionEntity closure)) {
+    assert(checkFamily(member));
+    _nestedClosureMap[member]?.forEach(f);
+  }
+
+  @override
+  InterfaceType getMemberThisType(MemberEntity member) {
+    return members.getData(member).getMemberThisType(this);
+  }
+
+  @override
+  ClassTypeVariableAccess getClassTypeVariableAccessForMember(
+      MemberEntity member) {
+    return members.getData(member).classTypeVariableAccess;
+  }
+
+  @override
+  bool checkFamily(Entity entity) {
+    assert(
+        '$entity'.startsWith(jsElementPrefix),
+        failedAt(entity,
+            "Unexpected entity $entity, expected family $jsElementPrefix."));
+    return true;
+  }
+
+  @override
+  Spannable getSpannable(MemberEntity member, ir.Node node) {
+    SourceSpan sourceSpan;
+    if (node is ir.TreeNode) {
+      sourceSpan = computeSourceSpanFromTreeNode(node);
+    }
+    sourceSpan ??= getSourceSpan(member, null);
+    return sourceSpan;
+  }
+
+  @override
+  Iterable<LibraryEntity> get libraryListInternal {
+    return libraryMap.values;
+  }
+
+  @override
+  LibraryEntity getLibraryInternal(ir.Library node, [LibraryEnv env]) {
+    LibraryEntity library = libraryMap[node];
+    assert(library != null, "No library entity for $node");
+    return library;
+  }
+
+  @override
+  ClassEntity getClassInternal(ir.Class node, [ClassEnv env]) {
+    ClassEntity cls = classMap[node];
+    assert(cls != null, "No class entity for $node");
+    return cls;
+  }
+
+  @override
+  FieldEntity getFieldInternal(ir.Field node) {
+    FieldEntity field = fieldMap[node];
+    assert(field != null, "No field entity for $node");
+    return field;
+  }
+
+  @override
+  FunctionEntity getMethodInternal(ir.Procedure node) {
+    FunctionEntity function = methodMap[node];
+    assert(function != null, "No function entity for $node");
+    return function;
+  }
+
+  @override
+  ConstructorEntity getConstructorInternal(ir.Member node) {
+    ConstructorEntity constructor = constructorMap[node];
+    assert(constructor != null, "No constructor entity for $node");
+    return constructor;
+  }
+
+  @override
+  TypeVariableEntity getTypeVariableInternal(ir.TypeParameter node) {
+    TypeVariableEntity typeVariable = typeVariableMap[node];
+    if (typeVariable == null) {
+      if (node.parent is ir.FunctionNode) {
+        ir.FunctionNode func = node.parent;
+        int index = func.typeParameters.indexOf(node);
+        if (func.parent is ir.Constructor) {
+          ir.Constructor constructor = func.parent;
+          ir.Class cls = constructor.enclosingClass;
+          typeVariableMap[node] =
+              typeVariable = getTypeVariableInternal(cls.typeParameters[index]);
+        } else if (func.parent is ir.Procedure) {
+          ir.Procedure procedure = func.parent;
+          if (procedure.kind == ir.ProcedureKind.Factory) {
+            ir.Class cls = procedure.enclosingClass;
+            typeVariableMap[node] = typeVariable =
+                getTypeVariableInternal(cls.typeParameters[index]);
+          }
+        }
+      }
+    }
+    assert(
+        typeVariable != null,
+        "No type variable entity for $node on "
+        "${node.parent is ir.FunctionNode ? node.parent.parent : node.parent}");
+    return typeVariable;
+  }
+
+  @override
+  TypedefEntity getTypedefInternal(ir.Typedef node) {
+    TypedefEntity typedef = typedefMap[node];
+    assert(typedef != null, "No typedef entity for $node");
+    return typedef;
+  }
+
+  @override
+  FunctionEntity getConstructorBody(ir.Constructor node) {
+    ConstructorEntity constructor = getConstructor(node);
+    return _getConstructorBody(node, constructor);
+  }
+
+  FunctionEntity _getConstructorBody(
+      ir.Constructor node, covariant IndexedConstructor constructor) {
+    ConstructorDataImpl data = members.getData(constructor);
+    if (data.constructorBody == null) {
+      JConstructorBody constructorBody = createConstructorBody(constructor);
+      members.register<IndexedFunction, FunctionData>(
+          constructorBody,
+          new ConstructorBodyDataImpl(
+              node,
+              node.function,
+              new SpecialMemberDefinition(
+                  constructorBody, node, MemberKind.constructorBody)));
+      IndexedClass cls = constructor.enclosingClass;
+      ClassEnvImpl classEnv = classes.getEnv(cls);
+      // TODO(johnniwinther): Avoid this by only including live members in the
+      // js-model.
+      classEnv.addConstructorBody(constructorBody);
+      data.constructorBody = constructorBody;
+    }
+    return data.constructorBody;
+  }
+
+  @override
+  JConstructorBody createConstructorBody(ConstructorEntity constructor);
+
+  @override
+  MemberDefinition getMemberDefinition(MemberEntity member) {
+    return getMemberDefinitionInternal(member);
+  }
+
+  @override
+  ClassDefinition getClassDefinition(ClassEntity cls) {
+    return getClassDefinitionInternal(cls);
+  }
+
+  @override
+  ConstantValue getFieldConstantValue(covariant IndexedField field) {
+    assert(checkFamily(field));
+    FieldData data = members.getData(field);
+    return data.getFieldConstantValue(this);
+  }
+
+  @override
+  bool hasConstantFieldInitializer(covariant IndexedField field) {
+    FieldData data = members.getData(field);
+    return data.hasConstantFieldInitializer(this);
+  }
+
+  @override
+  ConstantValue getConstantFieldInitializer(covariant IndexedField field) {
+    FieldData data = members.getData(field);
+    return data.getConstantFieldInitializer(this);
+  }
+
+  @override
+  void forEachParameter(covariant IndexedFunction function,
+      void f(DartType type, String name, ConstantValue defaultValue)) {
+    FunctionData data = members.getData(function);
+    data.forEachParameter(this, f);
+  }
+
+  @override
+  void forEachConstructorBody(
+      IndexedClass cls, void f(ConstructorBodyEntity member)) {
+    ClassEnv env = classes.getEnv(cls);
+    env.forEachConstructorBody(f);
+  }
+
+  @override
+  void forEachInjectedClassMember(
+      IndexedClass cls, void f(MemberEntity member)) {
+    _injectedClassMembers[cls]?.forEach(f);
+  }
+
+  JRecordField _constructRecordFieldEntry(
+      InterfaceType memberThisType,
+      ir.VariableDeclaration variable,
+      BoxLocal boxLocal,
+      JClass container,
+      Map<String, MemberEntity> memberMap,
+      KernelToLocalsMap localsMap) {
+    Local local = localsMap.getLocalVariable(variable);
+    JRecordField boxedField =
+        new JRecordField(local.name, boxLocal, container, variable.isConst);
+    members.register(
+        boxedField,
+        new ClosureFieldData(
+            new ClosureMemberDefinition(
+                boxedField,
+                computeSourceSpanFromTreeNode(variable),
+                MemberKind.closureField,
+                variable),
+            memberThisType));
+    memberMap[boxedField.name] = boxedField;
+
+    return boxedField;
+  }
+
+  /// Make a container controlling access to records, that is, variables that
+  /// are accessed in different scopes. This function creates the container
+  /// and returns a map of locals to the corresponding records created.
+  @override
+  Map<Local, JRecordField> makeRecordContainer(
+      KernelScopeInfo info, MemberEntity member, KernelToLocalsMap localsMap) {
+    Map<Local, JRecordField> boxedFields = {};
+    if (info.boxedVariables.isNotEmpty) {
+      NodeBox box = info.capturedVariablesAccessor;
+
+      Map<String, MemberEntity> memberMap = <String, MemberEntity>{};
+      JRecord container = new JRecord(member.library, box.name);
+      InterfaceType thisType = new InterfaceType(container, const <DartType>[]);
+      InterfaceType supertype = commonElements.objectType;
+      ClassData containerData = new RecordClassData(
+          new ClosureClassDefinition(container,
+              computeSourceSpanFromTreeNode(getMemberDefinition(member).node)),
+          thisType,
+          supertype,
+          getOrderedTypeSet(supertype.element).extendClass(thisType));
+      classes.register(container, containerData, new RecordEnv(memberMap));
+
+      BoxLocal boxLocal = new BoxLocal(box.name);
+      InterfaceType memberThisType = member.enclosingClass != null
+          ? elementEnvironment.getThisType(member.enclosingClass)
+          : null;
+      for (ir.VariableDeclaration variable in info.boxedVariables) {
+        boxedFields[localsMap.getLocalVariable(variable)] =
+            _constructRecordFieldEntry(memberThisType, variable, boxLocal,
+                container, memberMap, localsMap);
+      }
+    }
+    return boxedFields;
+  }
+
+  bool _isInRecord(
+          Local local, Map<Local, JRecordField> recordFieldsVisibleInScope) =>
+      recordFieldsVisibleInScope.containsKey(local);
+
+  KernelClosureClassInfo constructClosureClass(
+      MemberEntity member,
+      ir.FunctionNode node,
+      JLibrary enclosingLibrary,
+      Map<Local, JRecordField> recordFieldsVisibleInScope,
+      KernelScopeInfo info,
+      KernelToLocalsMap localsMap,
+      InterfaceType supertype,
+      {bool createSignatureMethod}) {
+    InterfaceType memberThisType = member.enclosingClass != null
+        ? elementEnvironment.getThisType(member.enclosingClass)
+        : null;
+    ClassTypeVariableAccess typeVariableAccess =
+        members.getData(member).classTypeVariableAccess;
+    if (typeVariableAccess == ClassTypeVariableAccess.instanceField) {
+      // A closure in a field initializer will only be executed in the
+      // constructor and type variables are therefore accessed through
+      // parameters.
+      typeVariableAccess = ClassTypeVariableAccess.parameter;
+    }
+    String name = _computeClosureName(node);
+    SourceSpan location = computeSourceSpanFromTreeNode(node);
+    Map<String, MemberEntity> memberMap = <String, MemberEntity>{};
+
+    JClass classEntity = new JClosureClass(enclosingLibrary, name);
+    // Create a classData and set up the interfaces and subclass
+    // relationships that _ensureSupertypes and _ensureThisAndRawType are doing
+    InterfaceType thisType = new InterfaceType(classEntity, const <DartType>[]);
+    ClosureClassData closureData = new ClosureClassData(
+        new ClosureClassDefinition(classEntity, location),
+        thisType,
+        supertype,
+        getOrderedTypeSet(supertype.element).extendClass(thisType));
+    classes.register(classEntity, closureData, new ClosureClassEnv(memberMap));
+
+    Local closureEntity;
+    if (node.parent is ir.FunctionDeclaration) {
+      ir.FunctionDeclaration parent = node.parent;
+      closureEntity = localsMap.getLocalVariable(parent.variable);
+    } else if (node.parent is ir.FunctionExpression) {
+      closureEntity = new JLocal('', localsMap.currentMember);
+    }
+
+    FunctionEntity callMethod = new JClosureCallMethod(
+        classEntity, getParameterStructure(node), getAsyncMarker(node));
+    _nestedClosureMap
+        .putIfAbsent(member, () => <FunctionEntity>[])
+        .add(callMethod);
+    // We need create the type variable here - before we try to make local
+    // variables from them (in `JsScopeInfo.from` called through
+    // `KernelClosureClassInfo.fromScopeInfo` below).
+    int index = 0;
+    for (ir.TypeParameter typeParameter in node.typeParameters) {
+      typeVariableMap[typeParameter] = typeVariables.register(
+          createTypeVariable(callMethod, typeParameter.name, index),
+          new TypeVariableData(typeParameter));
+      index++;
+    }
+
+    KernelClosureClassInfo closureClassInfo =
+        new KernelClosureClassInfo.fromScopeInfo(
+            classEntity,
+            node,
+            <Local, JRecordField>{},
+            info,
+            localsMap,
+            closureEntity,
+            info.hasThisLocal ? new ThisLocal(localsMap.currentMember) : null,
+            this);
+    _buildClosureClassFields(closureClassInfo, member, memberThisType, info,
+        localsMap, recordFieldsVisibleInScope, memberMap);
+
+    if (createSignatureMethod) {
+      _constructSignatureMethod(closureClassInfo, memberMap, node,
+          memberThisType, location, typeVariableAccess);
+    }
+
+    closureData.callType = getFunctionType(node);
+
+    members.register<IndexedFunction, FunctionData>(
+        callMethod,
+        new ClosureFunctionData(
+            new ClosureMemberDefinition(
+                callMethod, location, MemberKind.closureCall, node.parent),
+            memberThisType,
+            closureData.callType,
+            node,
+            typeVariableAccess));
+    memberMap[callMethod.name] = closureClassInfo.callMethod = callMethod;
+    return closureClassInfo;
+  }
+
+  void _buildClosureClassFields(
+      KernelClosureClassInfo closureClassInfo,
+      MemberEntity member,
+      InterfaceType memberThisType,
+      KernelScopeInfo info,
+      KernelToLocalsMap localsMap,
+      Map<Local, JRecordField> recordFieldsVisibleInScope,
+      Map<String, MemberEntity> memberMap) {
+    // TODO(efortuna): Limit field number usage to when we need to distinguish
+    // between two variables with the same name from different scopes.
+    int fieldNumber = 0;
+
+    // For the captured variables that are boxed, ensure this closure has a
+    // field to reference the box. This puts the boxes first in the closure like
+    // the AST front-end, but otherwise there is no reason to separate this loop
+    // from the one below.
+    // TODO(redemption): Merge this loop and the following.
+
+    for (ir.Node variable in info.freeVariables) {
+      if (variable is ir.VariableDeclaration) {
+        Local capturedLocal = localsMap.getLocalVariable(variable);
+        if (_isInRecord(capturedLocal, recordFieldsVisibleInScope)) {
+          bool constructedField = _constructClosureFieldForRecord(
+              capturedLocal,
+              closureClassInfo,
+              memberThisType,
+              memberMap,
+              variable,
+              recordFieldsVisibleInScope,
+              fieldNumber);
+          if (constructedField) fieldNumber++;
+        }
+      }
+    }
+
+    // Add a field for the captured 'this'.
+    if (info.thisUsedAsFreeVariable) {
+      _constructClosureField(
+          closureClassInfo.thisLocal,
+          closureClassInfo,
+          memberThisType,
+          memberMap,
+          getClassDefinition(member.enclosingClass).node,
+          true,
+          false,
+          fieldNumber);
+      fieldNumber++;
+    }
+
+    for (ir.Node variable in info.freeVariables) {
+      // Make a corresponding field entity in this closure class for the
+      // free variables in the KernelScopeInfo.freeVariable.
+      if (variable is ir.VariableDeclaration) {
+        Local capturedLocal = localsMap.getLocalVariable(variable);
+        if (!_isInRecord(capturedLocal, recordFieldsVisibleInScope)) {
+          _constructClosureField(
+              capturedLocal,
+              closureClassInfo,
+              memberThisType,
+              memberMap,
+              variable,
+              variable.isConst,
+              false, // Closure field is never assigned (only box fields).
+              fieldNumber);
+          fieldNumber++;
+        }
+      } else if (variable is TypeVariableTypeWithContext) {
+        _constructClosureField(
+            localsMap.getLocalTypeVariable(variable.type, this),
+            closureClassInfo,
+            memberThisType,
+            memberMap,
+            variable.type.parameter,
+            true,
+            false,
+            fieldNumber);
+        fieldNumber++;
+      } else {
+        throw new UnsupportedError("Unexpected field node type: $variable");
+      }
+    }
+  }
+
+  /// Records point to one or more local variables declared in another scope
+  /// that are captured in a scope. Access to those variables goes entirely
+  /// through the record container, so we only create a field for the *record*
+  /// holding [capturedLocal] and not the individual local variables accessed
+  /// through the record. Records, by definition, are not mutable (though the
+  /// locals they contain may be). Returns `true` if we constructed a new field
+  /// in the closure class.
+  bool _constructClosureFieldForRecord(
+      Local capturedLocal,
+      KernelClosureClassInfo closureClassInfo,
+      InterfaceType memberThisType,
+      Map<String, MemberEntity> memberMap,
+      ir.TreeNode sourceNode,
+      Map<Local, JRecordField> recordFieldsVisibleInScope,
+      int fieldNumber) {
+    JRecordField recordField = recordFieldsVisibleInScope[capturedLocal];
+
+    // Don't construct a new field if the box that holds this local already has
+    // a field in the closure class.
+    if (closureClassInfo.localToFieldMap.containsKey(recordField.box)) {
+      closureClassInfo.boxedVariables[capturedLocal] = recordField;
+      return false;
+    }
+
+    FieldEntity closureField = new JClosureField(
+        '_box_$fieldNumber', closureClassInfo, true, false, recordField.box);
+
+    members.register<IndexedField, FieldData>(
+        closureField,
+        new ClosureFieldData(
+            new ClosureMemberDefinition(
+                closureClassInfo.localToFieldMap[capturedLocal],
+                computeSourceSpanFromTreeNode(sourceNode),
+                MemberKind.closureField,
+                sourceNode),
+            memberThisType));
+    memberMap[closureField.name] = closureField;
+    closureClassInfo.localToFieldMap[recordField.box] = closureField;
+    closureClassInfo.boxedVariables[capturedLocal] = recordField;
+    return true;
+  }
+
+  void _constructSignatureMethod(
+      KernelClosureClassInfo closureClassInfo,
+      Map<String, MemberEntity> memberMap,
+      ir.FunctionNode closureSourceNode,
+      InterfaceType memberThisType,
+      SourceSpan location,
+      ClassTypeVariableAccess typeVariableAccess) {
+    FunctionEntity signatureMethod = new JSignatureMethod(
+        closureClassInfo.closureClassEntity.library,
+        closureClassInfo.closureClassEntity,
+        // SignatureMethod takes no arguments.
+        const ParameterStructure(0, 0, const [], 0),
+        AsyncMarker.SYNC);
+    members.register<IndexedFunction, FunctionData>(
+        signatureMethod,
+        new SignatureFunctionData(
+            new SpecialMemberDefinition(signatureMethod,
+                closureSourceNode.parent, MemberKind.signature),
+            memberThisType,
+            null,
+            closureSourceNode.typeParameters,
+            typeVariableAccess));
+    memberMap[signatureMethod.name] =
+        closureClassInfo.signatureMethod = signatureMethod;
+  }
+
+  void _constructClosureField(
+      Local capturedLocal,
+      KernelClosureClassInfo closureClassInfo,
+      InterfaceType memberThisType,
+      Map<String, MemberEntity> memberMap,
+      ir.TreeNode sourceNode,
+      bool isConst,
+      bool isAssignable,
+      int fieldNumber) {
+    FieldEntity closureField = new JClosureField(
+        _getClosureVariableName(capturedLocal.name, fieldNumber),
+        closureClassInfo,
+        isConst,
+        isAssignable,
+        capturedLocal);
+
+    members.register<IndexedField, FieldData>(
+        closureField,
+        new ClosureFieldData(
+            new ClosureMemberDefinition(
+                closureClassInfo.localToFieldMap[capturedLocal],
+                computeSourceSpanFromTreeNode(sourceNode),
+                MemberKind.closureField,
+                sourceNode),
+            memberThisType));
+    memberMap[closureField.name] = closureField;
+    closureClassInfo.localToFieldMap[capturedLocal] = closureField;
+  }
+
+  // Returns a non-unique name for the given closure element.
+  String _computeClosureName(ir.TreeNode treeNode) {
+    var parts = <String>[];
+    // First anonymous is called 'closure', outer ones called '' to give a
+    // compound name where increasing nesting level corresponds to extra
+    // underscores.
+    var anonymous = 'closure';
+    ir.TreeNode current = treeNode;
+    // TODO(johnniwinther): Simplify computed names.
+    while (current != null) {
+      var node = current;
+      if (node is ir.FunctionExpression) {
+        parts.add(anonymous);
+        anonymous = '';
+      } else if (node is ir.FunctionDeclaration) {
+        String name = node.variable.name;
+        if (name != null && name != "") {
+          parts.add(utils.operatorNameToIdentifier(name));
+        } else {
+          parts.add(anonymous);
+          anonymous = '';
+        }
+      } else if (node is ir.Class) {
+        // TODO(sra): Do something with abstracted mixin type names like '^#U0'.
+        parts.add(node.name);
+        break;
+      } else if (node is ir.Procedure) {
+        if (node.kind == ir.ProcedureKind.Factory) {
+          parts.add(utils.reconstructConstructorName(getMember(node)));
+        } else {
+          parts.add(utils.operatorNameToIdentifier(node.name.name));
+        }
+      } else if (node is ir.Constructor) {
+        parts.add(utils.reconstructConstructorName(getMember(node)));
+        break;
+      }
+      current = current.parent;
+    }
+    return parts.reversed.join('_');
+  }
+
+  /// Generate a unique name for the [id]th closure field, with proposed name
+  /// [name].
+  ///
+  /// The result is used as the name of [ClosureFieldElement]s, and must
+  /// therefore be unique to avoid breaking an invariant in the element model
+  /// (classes cannot declare multiple fields with the same name).
+  ///
+  /// Also, the names should be distinct from real field names to prevent
+  /// clashes with selectors for those fields.
+  ///
+  /// These names are not used in generated code, just as element name.
+  String _getClosureVariableName(String name, int id) {
+    return "_captured_${name}_$id";
+  }
+
+  @override
+  JGeneratorBody getGeneratorBody(covariant IndexedFunction function) {
+    JGeneratorBody generatorBody = _generatorBodies[function];
+    if (generatorBody == null) {
+      FunctionData functionData = members.getData(function);
+      ir.TreeNode node = functionData.definition.node;
+      DartType elementType =
+          elementEnvironment.getFunctionAsyncOrSyncStarElementType(function);
+      generatorBody = createGeneratorBody(function, elementType);
+      members.register<IndexedFunction, FunctionData>(
+          generatorBody,
+          new GeneratorBodyFunctionData(
+              functionData,
+              new SpecialMemberDefinition(
+                  generatorBody, node, MemberKind.generatorBody)));
+
+      if (function.enclosingClass != null) {
+        // TODO(sra): Integrate this with ClassEnvImpl.addConstructorBody ?
+        (_injectedClassMembers[function.enclosingClass] ??= <MemberEntity>[])
+            .add(generatorBody);
+      }
+    }
+    return generatorBody;
+  }
+
+  @override
+  JGeneratorBody createGeneratorBody(
+      FunctionEntity function, DartType elementType);
+
+  @override
+  js.Template getJsBuiltinTemplate(
+      ConstantValue constant, CodeEmitterTask emitter) {
+    int index = extractEnumIndexFromConstantValue(
+        constant, commonElements.jsBuiltinEnum);
+    if (index == null) return null;
+    return emitter.builtinTemplateFor(JsBuiltin.values[index]);
+  }
+}
diff --git a/pkg/compiler/lib/src/js_model/elements.dart b/pkg/compiler/lib/src/js_model/elements.dart
index 17de922..95193d0 100644
--- a/pkg/compiler/lib/src/js_model/elements.dart
+++ b/pkg/compiler/lib/src/js_model/elements.dart
@@ -6,9 +6,9 @@
 
 import '../common/names.dart' show Names;
 import '../elements/entities.dart';
+import '../elements/indexed.dart';
 import '../elements/names.dart';
 import '../elements/types.dart';
-import '../kernel/indexed.dart';
 import '../universe/class_set.dart' show ClassHierarchyNodesMapKey;
 
 /// Map from 'frontend' to 'backend' elements.
diff --git a/pkg/compiler/lib/src/js_model/js_strategy.dart b/pkg/compiler/lib/src/js_model/js_strategy.dart
index e2889cd..3bcbcd7 100644
--- a/pkg/compiler/lib/src/js_model/js_strategy.dart
+++ b/pkg/compiler/lib/src/js_model/js_strategy.dart
@@ -6,8 +6,10 @@
 
 import 'package:kernel/ast.dart' as ir;
 
+import '../backend_strategy.dart';
 import '../closure.dart' show ClosureConversionTask;
 import '../common.dart';
+import '../common/codegen.dart' show CodegenRegistry, CodegenWorkItem;
 import '../common/tasks.dart';
 import '../common_elements.dart';
 import '../compiler.dart';
@@ -17,6 +19,7 @@
 import '../elements/entities.dart';
 import '../elements/names.dart';
 import '../elements/types.dart';
+import '../elements/entity_utils.dart' as utils;
 import '../enqueue.dart';
 import '../io/kernel_source_information.dart'
     show KernelSourceInformationStrategy;
@@ -24,6 +27,7 @@
 import '../inferrer/type_graph_inferrer.dart';
 import '../js_emitter/sorter.dart';
 import '../js/js_source_mapping.dart';
+import '../js_backend/annotations.dart';
 import '../js_backend/allocator_analysis.dart';
 import '../js_backend/backend.dart';
 import '../js_backend/backend_usage.dart';
@@ -35,24 +39,30 @@
 import '../js_backend/runtime_types.dart';
 import '../kernel/element_map.dart';
 import '../kernel/element_map_impl.dart';
-import '../kernel/kernel_backend_strategy.dart';
 import '../kernel/kernel_strategy.dart';
 import '../kernel/kelements.dart';
 import '../native/behavior.dart';
+import '../ordered_typeset.dart';
 import '../options.dart';
+import '../ssa/builder_kernel.dart';
+import '../ssa/nodes.dart';
 import '../ssa/ssa.dart';
+import '../ssa/types.dart';
 import '../types/abstract_value_domain.dart';
 import '../types/types.dart';
 import '../universe/class_set.dart';
 import '../universe/feature.dart';
 import '../universe/selector.dart';
 import '../universe/world_builder.dart';
+import '../universe/world_impact.dart';
 import '../world.dart';
 import 'closure.dart';
 import 'elements.dart';
+import 'element_map.dart';
+import 'element_map_impl.dart';
 import 'locals.dart';
 
-class JsBackendStrategy implements KernelBackendStrategy {
+class JsBackendStrategy implements BackendStrategy {
   final Compiler _compiler;
   ElementEnvironment _elementEnvironment;
   CommonElements _commonElements;
@@ -63,7 +73,7 @@
 
   JsBackendStrategy(this._compiler);
 
-  KernelToElementMapForBuilding get elementMap {
+  JsToElementMap get elementMap {
     assert(_elementMap != null,
         "JsBackendStrategy.elementMap has not been created yet.");
     return _elementMap;
@@ -379,6 +389,20 @@
     JAllocatorAnalysis allocatorAnalysis =
         JAllocatorAnalysis.from(closedWorld.allocatorAnalysis, map, _options);
 
+    AnnotationsData annotationsData = new AnnotationsDataImpl(
+        map.toBackendFunctionSet(
+            closedWorld.annotationsData.nonInlinableFunctions),
+        map.toBackendFunctionSet(
+            closedWorld.annotationsData.tryInlineFunctions),
+        map.toBackendFunctionSet(
+            closedWorld.annotationsData.cannotThrowFunctions),
+        map.toBackendFunctionSet(
+            closedWorld.annotationsData.sideEffectFreeFunctions),
+        map.toBackendMemberSet(
+            closedWorld.annotationsData.trustTypeAnnotationsMembers),
+        map.toBackendMemberSet(
+            closedWorld.annotationsData.assumeDynamicMembers));
+
     return new JsClosedWorld(_elementMap,
         elementEnvironment: _elementEnvironment,
         dartTypes: _elementMap.types,
@@ -402,7 +426,8 @@
         mixinUses: mixinUses,
         typesImplementedBySubclasses: typesImplementedBySubclasses,
         abstractValueStrategy: _abstractValueStrategy,
-        allocatorAnalysis: allocatorAnalysis);
+        allocatorAnalysis: allocatorAnalysis,
+        annotationsData: annotationsData);
   }
 
   BackendUsage _convertBackendUsage(
@@ -615,11 +640,12 @@
   }
 }
 
-class JsClosedWorld extends ClosedWorldBase with KernelClosedWorldMixin {
+class JsClosedWorld extends ClosedWorldBase {
   final JsKernelToElementMap elementMap;
   final RuntimeTypesNeed rtiNeed;
   AbstractValueDomain _abstractValueDomain;
   final JAllocatorAnalysis allocatorAnalysis;
+  final AnnotationsData annotationsData;
 
   JsClosedWorld(this.elementMap,
       {ElementEnvironment elementEnvironment,
@@ -641,7 +667,8 @@
       Map<ClassEntity, Set<ClassEntity>> typesImplementedBySubclasses,
       Map<ClassEntity, ClassHierarchyNode> classHierarchyNodes,
       Map<ClassEntity, ClassSet> classSets,
-      AbstractValueStrategy abstractValueStrategy})
+      AbstractValueStrategy abstractValueStrategy,
+      this.annotationsData})
       : super(
             elementEnvironment,
             dartTypes,
@@ -668,6 +695,71 @@
   AbstractValueDomain get abstractValueDomain {
     return _abstractValueDomain;
   }
+
+  @override
+  bool hasElementIn(ClassEntity cls, Selector selector, Entity element) {
+    while (cls != null) {
+      MemberEntity member = elementEnvironment.lookupLocalClassMember(
+          cls, selector.name,
+          setter: selector.isSetter);
+      if (member != null &&
+          !member.isAbstract &&
+          (!selector.memberName.isPrivate ||
+              member.library == selector.library)) {
+        return member == element;
+      }
+      cls = elementEnvironment.getSuperClass(cls);
+    }
+    return false;
+  }
+
+  @override
+  bool hasConcreteMatch(ClassEntity cls, Selector selector,
+      {ClassEntity stopAtSuperclass}) {
+    assert(classHierarchy.isInstantiated(cls),
+        failedAt(cls, '$cls has not been instantiated.'));
+    MemberEntity element = elementEnvironment
+        .lookupClassMember(cls, selector.name, setter: selector.isSetter);
+    if (element == null) return false;
+
+    if (element.isAbstract) {
+      ClassEntity enclosingClass = element.enclosingClass;
+      return hasConcreteMatch(
+          elementEnvironment.getSuperClass(enclosingClass), selector);
+    }
+    return selector.appliesUntyped(element);
+  }
+
+  @override
+  bool isNamedMixinApplication(ClassEntity cls) {
+    return elementMap.elementEnvironment.isMixinApplication(cls) &&
+        !elementMap.elementEnvironment.isUnnamedMixinApplication(cls);
+  }
+
+  @override
+  ClassEntity getAppliedMixin(ClassEntity cls) {
+    return elementMap.getAppliedMixin(cls);
+  }
+
+  @override
+  Iterable<ClassEntity> getInterfaces(ClassEntity cls) {
+    return elementMap.getInterfaces(cls).map((t) => t.element);
+  }
+
+  @override
+  ClassEntity getSuperClass(ClassEntity cls) {
+    return elementMap.getSuperType(cls)?.element;
+  }
+
+  @override
+  int getHierarchyDepth(ClassEntity cls) {
+    return elementMap.getHierarchyDepth(cls);
+  }
+
+  @override
+  OrderedTypeSet getOrderedTypeSet(ClassEntity cls) {
+    return elementMap.getOrderedTypeSet(cls);
+  }
 }
 
 class ConstantConverter implements ConstantValueVisitor<ConstantValue, Null> {
@@ -895,3 +987,263 @@
           DartType functionType, int typeArgumentCount) =>
       rtiNeed.instantiationNeedsTypeArguments(functionType, typeArgumentCount);
 }
+
+class KernelCodegenWorkItemBuilder implements WorkItemBuilder {
+  final JavaScriptBackend _backend;
+  final JClosedWorld _closedWorld;
+  final GlobalTypeInferenceResults _globalInferenceResults;
+
+  KernelCodegenWorkItemBuilder(
+      this._backend, this._closedWorld, this._globalInferenceResults);
+
+  CompilerOptions get _options => _backend.compiler.options;
+
+  @override
+  CodegenWorkItem createWorkItem(MemberEntity entity) {
+    if (entity.isAbstract) return null;
+
+    // Codegen inlines field initializers. It only needs to generate
+    // code for checked setters.
+    if (entity.isField && entity.isInstanceMember) {
+      if (!_options.parameterCheckPolicy.isEmitted ||
+          entity.enclosingClass.isClosure) {
+        return null;
+      }
+    }
+
+    return new KernelCodegenWorkItem(
+        _backend, _closedWorld, _globalInferenceResults, entity);
+  }
+}
+
+class KernelCodegenWorkItem extends CodegenWorkItem {
+  final JavaScriptBackend _backend;
+  final JClosedWorld _closedWorld;
+  final MemberEntity element;
+  final CodegenRegistry registry;
+  final GlobalTypeInferenceResults _globalInferenceResults;
+
+  KernelCodegenWorkItem(this._backend, this._closedWorld,
+      this._globalInferenceResults, this.element)
+      : registry =
+            new CodegenRegistry(_closedWorld.elementEnvironment, element);
+
+  @override
+  WorldImpact run() {
+    return _backend.codegen(this, _closedWorld, _globalInferenceResults);
+  }
+}
+
+/// Task for building SSA from kernel IR loaded from .dill.
+class KernelSsaBuilder implements SsaBuilder {
+  final CompilerTask task;
+  final Compiler _compiler;
+  final JsToElementMap _elementMap;
+  final GlobalLocalsMap _globalLocalsMap;
+  FunctionInlineCache _inlineCache;
+
+  KernelSsaBuilder(
+      this.task, this._compiler, this._elementMap, this._globalLocalsMap);
+
+  @override
+  HGraph build(CodegenWorkItem work, JClosedWorld closedWorld,
+      GlobalTypeInferenceResults results) {
+    _inlineCache ??= new FunctionInlineCache(closedWorld.annotationsData);
+    return task.measure(() {
+      KernelSsaGraphBuilder builder = new KernelSsaGraphBuilder(
+          work.element,
+          _elementMap.getMemberThisType(work.element),
+          _compiler,
+          _elementMap,
+          results,
+          _globalLocalsMap,
+          closedWorld,
+          _compiler.codegenWorldBuilder,
+          work.registry,
+          _compiler.backendStrategy.closureDataLookup,
+          _compiler.backend.emitter.nativeEmitter,
+          _compiler.backend.sourceInformationStrategy,
+          _inlineCache);
+      return builder.build();
+    });
+  }
+}
+
+class KernelToTypeInferenceMapImpl implements KernelToTypeInferenceMap {
+  final GlobalTypeInferenceResults _globalInferenceResults;
+  GlobalTypeInferenceMemberResult _targetResults;
+
+  KernelToTypeInferenceMapImpl(
+      MemberEntity target, this._globalInferenceResults) {
+    _targetResults = _resultOf(target);
+  }
+
+  GlobalTypeInferenceMemberResult _resultOf(MemberEntity e) =>
+      _globalInferenceResults
+          .resultOfMember(e is ConstructorBodyEntity ? e.constructor : e);
+
+  AbstractValue getReturnTypeOf(FunctionEntity function) {
+    return AbstractValueFactory.inferredReturnTypeForElement(
+        function, _globalInferenceResults);
+  }
+
+  AbstractValue receiverTypeOfInvocation(
+      ir.MethodInvocation node, AbstractValueDomain abstractValueDomain) {
+    return _targetResults.typeOfSend(node);
+  }
+
+  AbstractValue receiverTypeOfGet(ir.PropertyGet node) {
+    return _targetResults.typeOfSend(node);
+  }
+
+  AbstractValue receiverTypeOfDirectGet(ir.DirectPropertyGet node) {
+    return _targetResults.typeOfSend(node);
+  }
+
+  AbstractValue receiverTypeOfSet(
+      ir.PropertySet node, AbstractValueDomain abstractValueDomain) {
+    return _targetResults.typeOfSend(node);
+  }
+
+  AbstractValue typeOfListLiteral(MemberEntity owner,
+      ir.ListLiteral listLiteral, AbstractValueDomain abstractValueDomain) {
+    return _resultOf(owner).typeOfListLiteral(listLiteral) ??
+        abstractValueDomain.dynamicType;
+  }
+
+  AbstractValue typeOfIterator(ir.ForInStatement node) {
+    return _targetResults.typeOfIterator(node);
+  }
+
+  AbstractValue typeOfIteratorCurrent(ir.ForInStatement node) {
+    return _targetResults.typeOfIteratorCurrent(node);
+  }
+
+  AbstractValue typeOfIteratorMoveNext(ir.ForInStatement node) {
+    return _targetResults.typeOfIteratorMoveNext(node);
+  }
+
+  bool isJsIndexableIterator(
+      ir.ForInStatement node, AbstractValueDomain abstractValueDomain) {
+    AbstractValue mask = typeOfIterator(node);
+    return abstractValueDomain.isJsIndexableAndIterable(mask);
+  }
+
+  AbstractValue inferredIndexType(ir.ForInStatement node) {
+    return AbstractValueFactory.inferredTypeForSelector(
+        new Selector.index(), typeOfIterator(node), _globalInferenceResults);
+  }
+
+  AbstractValue getInferredTypeOf(MemberEntity member) {
+    return AbstractValueFactory.inferredTypeForMember(
+        member, _globalInferenceResults);
+  }
+
+  AbstractValue getInferredTypeOfParameter(Local parameter) {
+    return AbstractValueFactory.inferredTypeForParameter(
+        parameter, _globalInferenceResults);
+  }
+
+  AbstractValue selectorTypeOf(Selector selector, AbstractValue mask) {
+    return AbstractValueFactory.inferredTypeForSelector(
+        selector, mask, _globalInferenceResults);
+  }
+
+  AbstractValue typeFromNativeBehavior(
+      NativeBehavior nativeBehavior, JClosedWorld closedWorld) {
+    return AbstractValueFactory.fromNativeBehavior(nativeBehavior, closedWorld);
+  }
+}
+
+class KernelSorter implements Sorter {
+  final JsToElementMap elementMap;
+
+  KernelSorter(this.elementMap);
+
+  int _compareLibraries(LibraryEntity a, LibraryEntity b) {
+    return utils.compareLibrariesUris(a.canonicalUri, b.canonicalUri);
+  }
+
+  int _compareSourceSpans(Entity entity1, SourceSpan sourceSpan1,
+      Entity entity2, SourceSpan sourceSpan2) {
+    int r = utils.compareSourceUris(sourceSpan1.uri, sourceSpan2.uri);
+    if (r != 0) return r;
+    return utils.compareEntities(
+        entity1, sourceSpan1.begin, null, entity2, sourceSpan2.begin, null);
+  }
+
+  @override
+  Iterable<LibraryEntity> sortLibraries(Iterable<LibraryEntity> libraries) {
+    return libraries.toList()..sort(_compareLibraries);
+  }
+
+  @override
+  Iterable<T> sortMembers<T extends MemberEntity>(Iterable<T> members) {
+    return members.toList()..sort(compareMembersByLocation);
+  }
+
+  @override
+  Iterable<ClassEntity> sortClasses(Iterable<ClassEntity> classes) {
+    List<ClassEntity> regularClasses = <ClassEntity>[];
+    List<ClassEntity> unnamedMixins = <ClassEntity>[];
+    for (ClassEntity cls in classes) {
+      if (elementMap.elementEnvironment.isUnnamedMixinApplication(cls)) {
+        unnamedMixins.add(cls);
+      } else {
+        regularClasses.add(cls);
+      }
+    }
+    List<ClassEntity> sorted = <ClassEntity>[];
+    regularClasses.sort(compareClassesByLocation);
+    sorted.addAll(regularClasses);
+    unnamedMixins.sort((a, b) {
+      int result = _compareLibraries(a.library, b.library);
+      if (result != 0) return result;
+      result = a.name.compareTo(b.name);
+      assert(result != 0,
+          failedAt(a, "Multiple mixins named ${a.name}: $a vs $b."));
+      return result;
+    });
+    sorted.addAll(unnamedMixins);
+    return sorted;
+  }
+
+  @override
+  Iterable<TypedefEntity> sortTypedefs(Iterable<TypedefEntity> typedefs) {
+    // TODO(redemption): Support this.
+    assert(typedefs.isEmpty);
+    return typedefs;
+  }
+
+  @override
+  int compareLibrariesByLocation(LibraryEntity a, LibraryEntity b) {
+    return _compareLibraries(a, b);
+  }
+
+  @override
+  int compareClassesByLocation(ClassEntity a, ClassEntity b) {
+    int r = _compareLibraries(a.library, b.library);
+    if (r != 0) return r;
+    ClassDefinition definition1 = elementMap.getClassDefinition(a);
+    ClassDefinition definition2 = elementMap.getClassDefinition(b);
+    return _compareSourceSpans(
+        a, definition1.location, b, definition2.location);
+  }
+
+  @override
+  int compareTypedefsByLocation(TypedefEntity a, TypedefEntity b) {
+    // TODO(redemption): Support this.
+    failedAt(a, 'KernelSorter.compareTypedefsByLocation unimplemented');
+    return 0;
+  }
+
+  @override
+  int compareMembersByLocation(MemberEntity a, MemberEntity b) {
+    int r = _compareLibraries(a.library, b.library);
+    if (r != 0) return r;
+    MemberDefinition definition1 = elementMap.getMemberDefinition(a);
+    MemberDefinition definition2 = elementMap.getMemberDefinition(b);
+    return _compareSourceSpans(
+        a, definition1.location, b, definition2.location);
+  }
+}
diff --git a/pkg/compiler/lib/src/js_model/locals.dart b/pkg/compiler/lib/src/js_model/locals.dart
index efd2e7f..a949a55 100644
--- a/pkg/compiler/lib/src/js_model/locals.dart
+++ b/pkg/compiler/lib/src/js_model/locals.dart
@@ -9,12 +9,14 @@
 import '../closure.dart';
 import '../common.dart';
 import '../elements/entities.dart';
+import '../elements/indexed.dart';
 import '../elements/jumps.dart';
 import '../elements/types.dart';
 import '../kernel/element_map.dart';
-import '../kernel/indexed.dart';
+import '../ir/util.dart';
 
-import '../js_model/elements.dart' show JGeneratorBody;
+import 'element_map.dart';
+import 'elements.dart' show JGeneratorBody;
 
 class GlobalLocalsMap {
   Map<MemberEntity, KernelToLocalsMap> _localsMaps =
@@ -146,7 +148,7 @@
 
   @override
   Local getLocalTypeVariable(
-      ir.TypeParameterType node, KernelToElementMap elementMap) {
+      ir.TypeParameterType node, JsToElementMap elementMap) {
     // TODO(efortuna, johnniwinther): We're not registering the type variables
     // like we are for the variable declarations. Is that okay or do we need to
     // make TypeVariableLocal a JLocal?
@@ -159,21 +161,9 @@
   }
 
   @override
-  DartType getLocalType(KernelToElementMap elementMap, covariant JLocal local) {
+  DartType getLocalType(JsToElementMap elementMap, covariant JLocal local) {
     return _locals.getData(local).getDartType(elementMap);
   }
-
-  @override
-  CapturedLoopScope getCapturedLoopScope(
-      ClosureDataLookup closureLookup, ir.TreeNode node) {
-    return closureLookup.getCapturedLoopScope(node);
-  }
-
-  @override
-  ClosureRepresentationInfo getClosureRepresentationInfo(
-      ClosureDataLookup closureLookup, ir.TreeNode node) {
-    return closureLookup.getClosureInfo(node);
-  }
 }
 
 class JumpVisitor extends ir.Visitor {
@@ -443,7 +433,7 @@
 
   LocalData(this.node);
 
-  DartType getDartType(KernelToElementMap elementMap) {
+  DartType getDartType(JsToElementMap elementMap) {
     return _type ??= elementMap.getDartType(node.type);
   }
 
@@ -454,7 +444,7 @@
 /// Positional parameters by index, then named parameters lexicographically.
 void forEachOrderedParameter(
     GlobalLocalsMap globalLocalsMap,
-    KernelToElementMapForBuilding elementMap,
+    JsToElementMap elementMap,
     FunctionEntity function,
     void f(Local parameter)) {
   KernelToLocalsMap localsMap = globalLocalsMap.getLocalsMap(function);
diff --git a/pkg/compiler/lib/src/kernel/deferred_load.dart b/pkg/compiler/lib/src/kernel/deferred_load.dart
index 7b0a987..db947c7 100644
--- a/pkg/compiler/lib/src/kernel/deferred_load.dart
+++ b/pkg/compiler/lib/src/kernel/deferred_load.dart
@@ -14,7 +14,7 @@
 import 'element_map.dart';
 
 class KernelDeferredLoadTask extends DeferredLoadTask {
-  KernelToElementMapForImpact _elementMap;
+  KernelToElementMap _elementMap;
   Map<ir.Library, Set<ir.NamedNode>> _additionalExportsSets =
       <ir.Library, Set<ir.NamedNode>>{};
 
@@ -130,7 +130,7 @@
 }
 
 class ConstantCollector extends ir.RecursiveVisitor {
-  final KernelToElementMapForImpact elementMap;
+  final KernelToElementMap elementMap;
   final Dependencies dependencies;
 
   ConstantCollector(this.elementMap, this.dependencies);
diff --git a/pkg/compiler/lib/src/kernel/element_map.dart b/pkg/compiler/lib/src/kernel/element_map.dart
index 998afb5..4bb698f 100644
--- a/pkg/compiler/lib/src/kernel/element_map.dart
+++ b/pkg/compiler/lib/src/kernel/element_map.dart
@@ -4,29 +4,26 @@
 
 import 'package:kernel/ast.dart' as ir;
 
-import '../closure.dart';
 import '../common.dart';
 import '../constants/values.dart';
 import '../common_elements.dart';
 import '../elements/entities.dart';
-import '../elements/jumps.dart';
 import '../elements/names.dart';
 import '../elements/types.dart';
+import '../ir/util.dart';
 import '../js/js.dart' as js;
 import '../js_backend/namer.dart';
 import '../js_backend/native_data.dart';
-import '../js_emitter/code_emitter_task.dart';
-import '../js_model/closure.dart' show JRecordField, KernelScopeInfo;
-import '../js_model/elements.dart' show JGeneratorBody;
 import '../native/native.dart' as native;
-import '../ssa/type_builder.dart';
-import '../types/abstract_value_domain.dart';
 import '../universe/call_structure.dart';
 import '../universe/selector.dart';
-import '../world.dart';
 
-/// Interface that translates between Kernel IR nodes and entities.
+/// Interface that translates between Kernel IR nodes and entities used for
+/// computing the [WorldImpact] for members.
 abstract class KernelToElementMap {
+  ElementEnvironment get elementEnvironment;
+  NativeBasicData get nativeBasicData;
+
   /// Access to the commonly used elements and types.
   CommonElements get commonElements;
 
@@ -124,13 +121,6 @@
   /// Returns the static type of [node].
   // TODO(johnniwinther): This should be provided directly from kernel.
   DartType getStaticType(ir.Expression node);
-}
-
-/// Interface that translates between Kernel IR nodes and entities used for
-/// computing the [WorldImpact] for members.
-abstract class KernelToElementMapForImpact extends KernelToElementMap {
-  ElementEnvironment get elementEnvironment;
-  NativeBasicData get nativeBasicData;
 
   /// Adds libraries in [component] to the set of libraries.
   ///
@@ -196,57 +186,6 @@
   DartType getFunctionAsyncOrSyncStarElementType(ir.FunctionNode functionNode);
 }
 
-/// Interface that translates between Kernel IR nodes and entities used for
-/// global type inference and building the SSA graph for members.
-abstract class KernelToElementMapForBuilding implements KernelToElementMap {
-  /// [ElementEnvironment] for library, class and member lookup.
-  ElementEnvironment get elementEnvironment;
-
-  /// Returns the list of [DartType]s corresponding to [types].
-  List<DartType> getDartTypes(List<ir.DartType> types);
-
-  /// Returns the definition information for [member].
-  MemberDefinition getMemberDefinition(covariant MemberEntity member);
-
-  /// Returns the type of `this` in [member], or `null` if member is defined in
-  /// a static context.
-  InterfaceType getMemberThisType(covariant MemberEntity member);
-
-  /// Returns how [member] has access to type variables of the this type
-  /// returned by [getMemberThisType].
-  ClassTypeVariableAccess getClassTypeVariableAccessForMember(
-      MemberEntity member);
-
-  /// Returns the definition information for [cls].
-  ClassDefinition getClassDefinition(covariant ClassEntity cls);
-
-  /// Returns the [LibraryEntity] corresponding to the library [node].
-  LibraryEntity getLibrary(ir.Library node);
-
-  /// Returns the [js.Template] for the `JsBuiltin` [constant] value.
-  js.Template getJsBuiltinTemplate(
-      ConstantValue constant, CodeEmitterTask emitter);
-
-  /// Return the [ConstantValue] the initial value of [field] or `null` if
-  /// the initializer is not a constant expression.
-  ConstantValue getFieldConstantValue(FieldEntity field);
-
-  /// Returns a [Spannable] for a message pointing to the IR [node] in the
-  /// context of [member].
-  Spannable getSpannable(MemberEntity member, ir.Node node);
-
-  /// Returns the constructor body entity corresponding to [constructor].
-  FunctionEntity getConstructorBody(ir.Constructor node);
-
-  /// Returns the constructor body entity corresponding to [function].
-  JGeneratorBody getGeneratorBody(FunctionEntity function);
-
-  /// Make a record to ensure variables that are are declared in one scope and
-  /// modified in another get their values updated correctly.
-  Map<Local, JRecordField> makeRecordContainer(
-      KernelScopeInfo info, MemberEntity member, KernelToLocalsMap localsMap);
-}
-
 // TODO(johnniwinther,efortuna): Add more when needed.
 // TODO(johnniwinther): Should we split regular into method, field, etc.?
 enum MemberKind {
@@ -365,266 +304,3 @@
   JS_INTERCEPTOR_CONSTANT,
   NONE,
 }
-
-/// Interface for type inference results for kernel IR nodes.
-abstract class KernelToTypeInferenceMap {
-  /// Returns the inferred return type of [function].
-  AbstractValue getReturnTypeOf(FunctionEntity function);
-
-  /// Returns the inferred receiver type of the dynamic [invocation].
-  AbstractValue receiverTypeOfInvocation(
-      ir.MethodInvocation invocation, AbstractValueDomain abstractValueDomain);
-
-  /// Returns the inferred receiver type of the dynamic [read].
-  AbstractValue receiverTypeOfGet(ir.PropertyGet read);
-
-  /// Returns the inferred receiver type of the direct [read].
-  AbstractValue receiverTypeOfDirectGet(ir.DirectPropertyGet read);
-
-  /// Returns the inferred receiver type of the dynamic [write].
-  AbstractValue receiverTypeOfSet(
-      ir.PropertySet write, AbstractValueDomain abstractValueDomain);
-
-  /// Returns the inferred type of [listLiteral].
-  AbstractValue typeOfListLiteral(MemberEntity owner,
-      ir.ListLiteral listLiteral, AbstractValueDomain abstractValueDomain);
-
-  /// Returns the inferred type of iterator in [forInStatement].
-  AbstractValue typeOfIterator(ir.ForInStatement forInStatement);
-
-  /// Returns the inferred type of `current` in [forInStatement].
-  AbstractValue typeOfIteratorCurrent(ir.ForInStatement forInStatement);
-
-  /// Returns the inferred type of `moveNext` in [forInStatement].
-  AbstractValue typeOfIteratorMoveNext(ir.ForInStatement forInStatement);
-
-  /// Returns `true` if [forInStatement] is inferred to be a JavaScript
-  /// indexable iterator.
-  bool isJsIndexableIterator(ir.ForInStatement forInStatement,
-      AbstractValueDomain abstractValueDomain);
-
-  /// Returns the inferred index type of [forInStatement].
-  AbstractValue inferredIndexType(ir.ForInStatement forInStatement);
-
-  /// Returns the inferred type of [member].
-  AbstractValue getInferredTypeOf(MemberEntity member);
-
-  /// Returns the inferred type of the [parameter].
-  AbstractValue getInferredTypeOfParameter(Local parameter);
-
-  /// Returns the inferred type of a dynamic [selector] access on the
-  /// [receiver].
-  AbstractValue selectorTypeOf(Selector selector, AbstractValue receiver);
-
-  /// Returns the returned type annotation in the [nativeBehavior].
-  AbstractValue typeFromNativeBehavior(
-      native.NativeBehavior nativeBehavior, JClosedWorld closedWorld);
-}
-
-/// Map from kernel IR nodes to local entities.
-abstract class KernelToLocalsMap {
-  /// The member currently being built.
-  MemberEntity get currentMember;
-
-  /// Returns the [Local] for [node].
-  Local getLocalVariable(ir.VariableDeclaration node);
-
-  Local getLocalTypeVariable(
-      ir.TypeParameterType node, KernelToElementMap elementMap);
-
-  /// Returns the [ir.FunctionNode] that declared [parameter].
-  ir.FunctionNode getFunctionNodeForParameter(Local parameter);
-
-  /// Returns the [DartType] of [local].
-  DartType getLocalType(KernelToElementMap elementMap, Local local);
-
-  /// Returns the [JumpTarget] for the break statement [node].
-  JumpTarget getJumpTargetForBreak(ir.BreakStatement node);
-
-  /// Returns `true` if [node] should generate a `continue` to its [JumpTarget].
-  bool generateContinueForBreak(ir.BreakStatement node);
-
-  /// Returns the [JumpTarget] defined by the labelled statement [node] or
-  /// `null` if [node] is not a jump target.
-  JumpTarget getJumpTargetForLabel(ir.LabeledStatement node);
-
-  /// Returns the [JumpTarget] defined by the switch statement [node] or `null`
-  /// if [node] is not a jump target.
-  JumpTarget getJumpTargetForSwitch(ir.SwitchStatement node);
-
-  /// Returns the [JumpTarget] for the continue switch statement [node].
-  JumpTarget getJumpTargetForContinueSwitch(ir.ContinueSwitchStatement node);
-
-  /// Returns the [JumpTarget] defined by the switch case [node] or `null`
-  /// if [node] is not a jump target.
-  JumpTarget getJumpTargetForSwitchCase(ir.SwitchCase node);
-
-  /// Returns the [JumpTarget] defined the do statement [node] or `null`
-  /// if [node] is not a jump target.
-  JumpTarget getJumpTargetForDo(ir.DoStatement node);
-
-  /// Returns the [JumpTarget] defined by the for statement [node] or `null`
-  /// if [node] is not a jump target.
-  JumpTarget getJumpTargetForFor(ir.ForStatement node);
-
-  /// Returns the [JumpTarget] defined by the for-in statement [node] or `null`
-  /// if [node] is not a jump target.
-  JumpTarget getJumpTargetForForIn(ir.ForInStatement node);
-
-  /// Returns the [JumpTarget] defined by the while statement [node] or `null`
-  /// if [node] is not a jump target.
-  JumpTarget getJumpTargetForWhile(ir.WhileStatement node);
-
-  /// Returns the [CapturedLoopScope] for the loop [node] in
-  /// [closureLookup].
-  // TODO(johnniwinther): Remove this when [KernelAstAdapter] is deleted.
-  CapturedLoopScope getCapturedLoopScope(
-      ClosureDataLookup closureLookup, ir.TreeNode node);
-
-  /// Returns the [ClosureRepresentationInfo] for the local function [node] in
-  /// [closureLookup].
-  // TODO(johnniwinther): Remove this when [KernelAstAdapter] is deleted.
-  ClosureRepresentationInfo getClosureRepresentationInfo(
-      ClosureDataLookup closureLookup, ir.TreeNode node);
-}
-
-/// Comparator for the canonical order or named arguments.
-// TODO(johnniwinther): Remove this when named parameters are sorted in dill.
-int namedOrdering(ir.VariableDeclaration a, ir.VariableDeclaration b) {
-  return a.name.compareTo(b.name);
-}
-
-SourceSpan computeSourceSpanFromTreeNode(ir.TreeNode node) {
-  // TODO(johnniwinther): Use [ir.Location] directly as a [SourceSpan].
-  Uri uri;
-  int offset;
-  while (node != null) {
-    if (node.fileOffset != ir.TreeNode.noOffset) {
-      offset = node.fileOffset;
-      uri = node.location.file;
-      break;
-    }
-    node = node.parent;
-  }
-  if (uri != null) {
-    return new SourceSpan(uri, offset, offset + 1);
-  }
-  return null;
-}
-
-/// Returns the [ir.FunctionNode] that defines [member] or `null` if [member]
-/// is not a constructor, method or local function.
-ir.FunctionNode getFunctionNode(
-    KernelToElementMapForBuilding elementMap, MemberEntity member) {
-  MemberDefinition definition = elementMap.getMemberDefinition(member);
-  switch (definition.kind) {
-    case MemberKind.regular:
-      ir.Node node = definition.node;
-      if (node is ir.Procedure) {
-        return node.function;
-      }
-      break;
-    case MemberKind.constructor:
-    case MemberKind.constructorBody:
-      ir.Node node = definition.node;
-      if (node is ir.Procedure) {
-        return node.function;
-      } else if (node is ir.Constructor) {
-        return node.function;
-      }
-      break;
-    case MemberKind.closureCall:
-      ir.Node node = definition.node;
-      if (node is ir.FunctionDeclaration) {
-        return node.function;
-      } else if (node is ir.FunctionExpression) {
-        return node.function;
-      }
-      break;
-    default:
-  }
-  return null;
-}
-
-/// Returns the `AsyncMarker` corresponding to `node.asyncMarker`.
-AsyncMarker getAsyncMarker(ir.FunctionNode node) {
-  switch (node.asyncMarker) {
-    case ir.AsyncMarker.Async:
-      return AsyncMarker.ASYNC;
-    case ir.AsyncMarker.AsyncStar:
-      return AsyncMarker.ASYNC_STAR;
-    case ir.AsyncMarker.Sync:
-      return AsyncMarker.SYNC;
-    case ir.AsyncMarker.SyncStar:
-      return AsyncMarker.SYNC_STAR;
-    case ir.AsyncMarker.SyncYielding:
-    default:
-      throw new UnsupportedError(
-          "Async marker ${node.asyncMarker} is not supported.");
-  }
-}
-
-/// Kernel encodes a null-aware expression `a?.b` as
-///
-///     let final #1 = a in #1 == null ? null : #1.b
-///
-/// [getNullAwareExpression] recognizes such expressions storing the result in
-/// a [NullAwareExpression] object.
-///
-/// [syntheticVariable] holds the synthesized `#1` variable. [expression] holds
-/// the `#1.b` expression. [receiver] returns `a` expression. [parent] returns
-/// the parent of the let node, i.e. the parent node of the original null-aware
-/// expression. [let] returns the let node created for the encoding.
-class NullAwareExpression {
-  final ir.VariableDeclaration syntheticVariable;
-  final ir.Expression expression;
-
-  NullAwareExpression(this.syntheticVariable, this.expression);
-
-  ir.Expression get receiver => syntheticVariable.initializer;
-
-  ir.TreeNode get parent => syntheticVariable.parent.parent;
-
-  ir.Let get let => syntheticVariable.parent;
-
-  String toString() => let.toString();
-}
-
-NullAwareExpression getNullAwareExpression(ir.TreeNode node) {
-  if (node is ir.Let) {
-    ir.Expression body = node.body;
-    if (node.variable.name == null &&
-        node.variable.isFinal &&
-        body is ir.ConditionalExpression &&
-        body.condition is ir.MethodInvocation &&
-        body.then is ir.NullLiteral) {
-      ir.MethodInvocation invocation = body.condition;
-      ir.Expression receiver = invocation.receiver;
-      if (invocation.name.name == '==' &&
-          receiver is ir.VariableGet &&
-          receiver.variable == node.variable &&
-          invocation.arguments.positional.single is ir.NullLiteral) {
-        // We have
-        //   let #t1 = e0 in #t1 == null ? null : e1
-        return new NullAwareExpression(node.variable, body.otherwise);
-      }
-    }
-  }
-  return null;
-}
-
-/// Returns the initializer for [field].
-///
-/// If [field] is an instance field with a null literal initializer `null` is
-/// returned, otherwise the initializer of the [ir.Field] is returned.
-ir.Node getFieldInitializer(
-    KernelToElementMapForBuilding elementMap, FieldEntity field) {
-  MemberDefinition definition = elementMap.getMemberDefinition(field);
-  ir.Field node = definition.node;
-  if (node.isInstanceMember &&
-      !node.isFinal &&
-      node.initializer is ir.NullLiteral) {
-    return null;
-  }
-  return node.initializer;
-}
diff --git a/pkg/compiler/lib/src/kernel/element_map_impl.dart b/pkg/compiler/lib/src/kernel/element_map_impl.dart
index aa15678..d09ed9c 100644
--- a/pkg/compiler/lib/src/kernel/element_map_impl.dart
+++ b/pkg/compiler/lib/src/kernel/element_map_impl.dart
@@ -5,14 +5,14 @@
 library dart2js.kernel.element_map;
 
 import 'package:front_end/src/fasta/util/link.dart' show Link, LinkBuilder;
+import 'package:js_runtime/shared/embedded_names.dart';
 import 'package:kernel/ast.dart' as ir;
 import 'package:kernel/class_hierarchy.dart' as ir;
 import 'package:kernel/core_types.dart' as ir;
 import 'package:kernel/type_environment.dart' as ir;
 
-import '../closure.dart' show BoxLocal, ThisLocal;
 import '../common.dart';
-import '../common/names.dart' show Identifiers;
+import '../common/names.dart';
 import '../common/resolution.dart';
 import '../common_elements.dart';
 import '../compile_time_constants.dart';
@@ -22,15 +22,24 @@
 import '../constants/expressions.dart';
 import '../constants/values.dart';
 import '../elements/entities.dart';
-import '../elements/entity_utils.dart' as utils;
+import '../elements/indexed.dart';
 import '../elements/names.dart';
 import '../elements/types.dart';
 import '../environment.dart';
 import '../frontend_strategy.dart';
+import '../ir/debug.dart';
+import '../ir/element_map.dart';
+import '../ir/types.dart';
+import '../ir/visitors.dart';
+import '../ir/util.dart';
+import '../js/js.dart' as js;
+import '../js_backend/annotations.dart';
 import '../js_backend/allocator_analysis.dart' show KAllocatorAnalysis;
+import '../js_backend/backend.dart' show JavaScriptBackend;
 import '../js_backend/backend_usage.dart';
 import '../js_backend/constant_system_javascript.dart';
 import '../js_backend/interceptor_data.dart';
+import '../js_backend/namer.dart';
 import '../js_backend/native_data.dart';
 import '../js_backend/no_such_method_registry.dart';
 import '../js_backend/runtime_types.dart';
@@ -42,59 +51,42 @@
 import '../options.dart';
 import '../ordered_typeset.dart';
 import '../ssa/kernel_impact.dart';
-import '../ssa/type_builder.dart';
+import '../universe/call_structure.dart';
 import '../universe/class_hierarchy.dart';
 import '../universe/class_set.dart';
 import '../universe/selector.dart';
 import '../universe/world_builder.dart';
 import '../world.dart';
+
 import 'element_map.dart';
-import 'element_map_mixins.dart';
 import 'env.dart';
-import 'indexed.dart';
 import 'kelements.dart';
 
 part 'native_basic_data.dart';
 part 'no_such_method_resolver.dart';
-part 'types.dart';
 
-/// Interface for kernel queries needed to implement the [CodegenWorldBuilder].
-abstract class KernelToWorldBuilder implements KernelToElementMapForBuilding {
-  /// Returns `true` if [field] has a constant initializer.
-  bool hasConstantFieldInitializer(FieldEntity field);
-
-  /// Returns the constant initializer for [field].
-  ConstantValue getConstantFieldInitializer(FieldEntity field);
-
-  /// Calls [f] for each parameter of [function] providing the type and name of
-  /// the parameter and the [defaultValue] if the parameter is optional.
-  void forEachParameter(FunctionEntity function,
-      void f(DartType type, String name, ConstantValue defaultValue));
-}
-
-abstract class KernelToElementMapBase extends KernelToElementMapBaseMixin {
+abstract class KernelToElementMapBase implements IrToElementMap {
   final CompilerOptions options;
   final DiagnosticReporter reporter;
   CommonElements _commonElements;
   ElementEnvironment _elementEnvironment;
   DartTypeConverter _typeConverter;
   KernelConstantEnvironment _constantEnvironment;
-  _KernelDartTypes _types;
+  KernelDartTypes _types;
   ir.TypeEnvironment _typeEnvironment;
-  bool _isStaticTypePrepared = false;
 
   /// Library environment. Used for fast lookup.
-  ProgramEnv _env = new ProgramEnv();
+  ProgramEnv env = new ProgramEnv();
 
-  final EntityDataEnvMap<IndexedLibrary, LibraryData, LibraryEnv> _libraries =
+  final EntityDataEnvMap<IndexedLibrary, LibraryData, LibraryEnv> libraries =
       new EntityDataEnvMap<IndexedLibrary, LibraryData, LibraryEnv>();
-  final EntityDataEnvMap<IndexedClass, ClassData, ClassEnv> _classes =
+  final EntityDataEnvMap<IndexedClass, ClassData, ClassEnv> classes =
       new EntityDataEnvMap<IndexedClass, ClassData, ClassEnv>();
-  final EntityDataMap<IndexedMember, MemberData> _members =
+  final EntityDataMap<IndexedMember, MemberData> members =
       new EntityDataMap<IndexedMember, MemberData>();
-  final EntityDataMap<IndexedTypeVariable, TypeVariableData> _typeVariables =
+  final EntityDataMap<IndexedTypeVariable, TypeVariableData> typeVariables =
       new EntityDataMap<IndexedTypeVariable, TypeVariableData>();
-  final EntityDataMap<IndexedTypedef, TypedefData> _typedefs =
+  final EntityDataMap<IndexedTypedef, TypedefData> typedefs =
       new EntityDataMap<IndexedTypedef, TypedefData>();
 
   KernelToElementMapBase(this.options, this.reporter, Environment environment) {
@@ -102,14 +94,13 @@
     _commonElements = new CommonElements(_elementEnvironment);
     _constantEnvironment = new KernelConstantEnvironment(this, environment);
     _typeConverter = new DartTypeConverter(this);
-    _types = new _KernelDartTypes(this);
+    _types = new KernelDartTypes(this);
   }
 
   bool checkFamily(Entity entity);
 
   DartTypes get types => _types;
 
-  @override
   ElementEnvironment get elementEnvironment => _elementEnvironment;
 
   @override
@@ -119,30 +110,30 @@
   NativeBasicData get nativeBasicData;
 
   FunctionEntity get _mainFunction {
-    return _env.mainMethod != null ? _getMethod(_env.mainMethod) : null;
+    return env.mainMethod != null ? getMethodInternal(env.mainMethod) : null;
   }
 
   LibraryEntity get _mainLibrary {
-    return _env.mainMethod != null
-        ? _getLibrary(_env.mainMethod.enclosingLibrary)
+    return env.mainMethod != null
+        ? getLibraryInternal(env.mainMethod.enclosingLibrary)
         : null;
   }
 
-  Iterable<LibraryEntity> get _libraryList;
+  Iterable<LibraryEntity> get libraryListInternal;
 
   SourceSpan getSourceSpan(Spannable spannable, Entity currentElement) {
     SourceSpan fromSpannable(Spannable spannable) {
       if (spannable is IndexedLibrary &&
-          spannable.libraryIndex < _libraries.length) {
-        LibraryEnv env = _libraries.getEnv(spannable);
+          spannable.libraryIndex < libraries.length) {
+        LibraryEnv env = libraries.getEnv(spannable);
         return computeSourceSpanFromTreeNode(env.library);
       } else if (spannable is IndexedClass &&
-          spannable.classIndex < _classes.length) {
-        ClassData data = _classes.getData(spannable);
+          spannable.classIndex < classes.length) {
+        ClassData data = classes.getData(spannable);
         return data.definition.location;
       } else if (spannable is IndexedMember &&
-          spannable.memberIndex < _members.length) {
-        MemberData data = _members.getData(spannable);
+          spannable.memberIndex < members.length) {
+        MemberData data = members.getData(spannable);
         return data.definition.location;
       } else if (spannable is KLocalFunction) {
         return getSourceSpan(spannable.memberContext, currentElement);
@@ -158,21 +149,21 @@
   }
 
   LibraryEntity lookupLibrary(Uri uri) {
-    LibraryEnv libraryEnv = _env.lookupLibrary(uri);
+    LibraryEnv libraryEnv = env.lookupLibrary(uri);
     if (libraryEnv == null) return null;
-    return _getLibrary(libraryEnv.library, libraryEnv);
+    return getLibraryInternal(libraryEnv.library, libraryEnv);
   }
 
   String _getLibraryName(IndexedLibrary library) {
     assert(checkFamily(library));
-    LibraryEnv libraryEnv = _libraries.getEnv(library);
+    LibraryEnv libraryEnv = libraries.getEnv(library);
     return libraryEnv.library.name ?? '';
   }
 
   MemberEntity lookupLibraryMember(IndexedLibrary library, String name,
       {bool setter: false}) {
     assert(checkFamily(library));
-    LibraryEnv libraryEnv = _libraries.getEnv(library);
+    LibraryEnv libraryEnv = libraries.getEnv(library);
     ir.Member member = libraryEnv.lookupMember(name, setter: setter);
     return member != null ? getMember(member) : null;
   }
@@ -180,7 +171,7 @@
   void _forEachLibraryMember(
       IndexedLibrary library, void f(MemberEntity member)) {
     assert(checkFamily(library));
-    LibraryEnv libraryEnv = _libraries.getEnv(library);
+    LibraryEnv libraryEnv = libraries.getEnv(library);
     libraryEnv.forEachMember((ir.Member node) {
       f(getMember(node));
     });
@@ -188,38 +179,38 @@
 
   ClassEntity lookupClass(IndexedLibrary library, String name) {
     assert(checkFamily(library));
-    LibraryEnv libraryEnv = _libraries.getEnv(library);
+    LibraryEnv libraryEnv = libraries.getEnv(library);
     ClassEnv classEnv = libraryEnv.lookupClass(name);
     if (classEnv != null) {
-      return _getClass(classEnv.cls, classEnv);
+      return getClassInternal(classEnv.cls, classEnv);
     }
     return null;
   }
 
   void _forEachClass(IndexedLibrary library, void f(ClassEntity cls)) {
     assert(checkFamily(library));
-    LibraryEnv libraryEnv = _libraries.getEnv(library);
+    LibraryEnv libraryEnv = libraries.getEnv(library);
     libraryEnv.forEachClass((ClassEnv classEnv) {
       if (!classEnv.isUnnamedMixinApplication) {
-        f(_getClass(classEnv.cls, classEnv));
+        f(getClassInternal(classEnv.cls, classEnv));
       }
     });
   }
 
   void ensureClassMembers(ir.Class node) {
-    _classes.getEnv(_getClass(node)).ensureMembers(this);
+    classes.getEnv(getClassInternal(node)).ensureMembers(this);
   }
 
   MemberEntity lookupClassMember(IndexedClass cls, String name,
       {bool setter: false}) {
     assert(checkFamily(cls));
-    ClassEnv classEnv = _classes.getEnv(cls);
+    ClassEnv classEnv = classes.getEnv(cls);
     return classEnv.lookupMember(this, name, setter: setter);
   }
 
   ConstructorEntity lookupConstructor(IndexedClass cls, String name) {
     assert(checkFamily(cls));
-    ClassEnv classEnv = _classes.getEnv(cls);
+    ClassEnv classEnv = classes.getEnv(cls);
     return classEnv.lookupConstructor(this, name);
   }
 
@@ -229,25 +220,25 @@
     return new InterfaceType(getClass(cls), getDartTypes(typeArguments));
   }
 
-  LibraryEntity getLibrary(ir.Library node) => _getLibrary(node);
+  LibraryEntity getLibrary(ir.Library node) => getLibraryInternal(node);
 
-  LibraryEntity _getLibrary(ir.Library node, [LibraryEnv libraryEnv]);
+  LibraryEntity getLibraryInternal(ir.Library node, [LibraryEnv libraryEnv]);
 
   @override
-  ClassEntity getClass(ir.Class node) => _getClass(node);
+  ClassEntity getClass(ir.Class node) => getClassInternal(node);
 
-  ClassEntity _getClass(ir.Class node, [ClassEnv classEnv]);
+  ClassEntity getClassInternal(ir.Class node, [ClassEnv classEnv]);
 
-  InterfaceType _getSuperType(IndexedClass cls) {
+  InterfaceType getSuperType(IndexedClass cls) {
     assert(checkFamily(cls));
-    ClassData data = _classes.getData(cls);
+    ClassData data = classes.getData(cls);
     _ensureSupertypes(cls, data);
     return data.supertype;
   }
 
   void _ensureThisAndRawType(ClassEntity cls, ClassData data) {
     assert(checkFamily(cls));
-    if (data.thisType == null) {
+    if (data is ClassDataImpl && data.thisType == null) {
       ir.Class node = data.cls;
       if (node.typeParameters.isEmpty) {
         data.thisType =
@@ -258,7 +249,7 @@
             new List<DartType>.generate(node.typeParameters.length,
                 (int index) {
               return new TypeVariableType(
-                  _getTypeVariable(node.typeParameters[index]));
+                  getTypeVariableInternal(node.typeParameters[index]));
             }));
         data.rawType = new InterfaceType(
             cls,
@@ -269,13 +260,13 @@
   }
 
   TypeVariableEntity getTypeVariable(ir.TypeParameter node) =>
-      _getTypeVariable(node);
+      getTypeVariableInternal(node);
 
-  TypeVariableEntity _getTypeVariable(ir.TypeParameter node);
+  TypeVariableEntity getTypeVariableInternal(ir.TypeParameter node);
 
   void _ensureSupertypes(ClassEntity cls, ClassData data) {
     assert(checkFamily(cls));
-    if (data.orderedTypeSet == null) {
+    if (data is ClassDataImpl && data.orderedTypeSet == null) {
       _ensureThisAndRawType(cls, data);
 
       ir.Class node = data.cls;
@@ -288,7 +279,7 @@
         InterfaceType processSupertype(ir.Supertype node) {
           InterfaceType supertype = _typeConverter.visitSupertype(node);
           IndexedClass superclass = supertype.element;
-          ClassData superdata = _classes.getData(superclass);
+          ClassData superdata = classes.getData(superclass);
           _ensureSupertypes(superclass, superdata);
           return supertype;
         }
@@ -316,7 +307,7 @@
         Link<InterfaceType> interfaces =
             linkBuilder.toLink(const Link<InterfaceType>());
         OrderedTypeSetBuilder setBuilder =
-            new _KernelOrderedTypeSetBuilder(this, cls);
+            new KernelOrderedTypeSetBuilder(this, cls);
         data.orderedTypeSet = setBuilder.createOrderedTypeSet(
             data.supertype, interfaces.reverse(const Link<InterfaceType>()));
         data.interfaces = new List<InterfaceType>.from(interfaces.toList());
@@ -326,23 +317,23 @@
 
   @override
   TypedefType getTypedefType(ir.Typedef node) {
-    IndexedTypedef typedef = _getTypedef(node);
-    return _typedefs.getData(typedef).rawType;
+    IndexedTypedef typedef = getTypedefInternal(node);
+    return typedefs.getData(typedef).rawType;
   }
 
-  TypedefEntity _getTypedef(ir.Typedef node);
+  TypedefEntity getTypedefInternal(ir.Typedef node);
 
   @override
   MemberEntity getMember(ir.Member node) {
     if (node is ir.Field) {
-      return _getField(node);
+      return getFieldInternal(node);
     } else if (node is ir.Constructor) {
-      return _getConstructor(node);
+      return getConstructorInternal(node);
     } else if (node is ir.Procedure) {
       if (node.kind == ir.ProcedureKind.Factory) {
-        return _getConstructor(node);
+        return getConstructorInternal(node);
       } else {
-        return _getMethod(node);
+        return getMethodInternal(node);
       }
     }
     throw new UnsupportedError("Unexpected member: $node");
@@ -359,9 +350,9 @@
         cls != null,
         failedAt(context,
             "No enclosing class for super member access in $context."));
-    IndexedClass superclass = _getSuperType(cls)?.element;
+    IndexedClass superclass = getSuperType(cls)?.element;
     while (superclass != null) {
-      ClassEnv env = _classes.getEnv(superclass);
+      ClassEnv env = classes.getEnv(superclass);
       MemberEntity superMember =
           env.lookupMember(this, name.name, setter: setter);
       if (superMember != null) {
@@ -370,15 +361,16 @@
           return superMember;
         }
       }
-      superclass = _getSuperType(superclass)?.element;
+      superclass = getSuperType(superclass)?.element;
     }
     return null;
   }
 
   @override
-  ConstructorEntity getConstructor(ir.Member node) => _getConstructor(node);
+  ConstructorEntity getConstructor(ir.Member node) =>
+      getConstructorInternal(node);
 
-  ConstructorEntity _getConstructor(ir.Member node);
+  ConstructorEntity getConstructorInternal(ir.Member node);
 
   ConstructorEntity getSuperConstructor(
       ir.Constructor sourceNode, ir.Member targetNode) {
@@ -386,11 +378,11 @@
     ClassEntity sourceClass = source.enclosingClass;
     ConstructorEntity target = getConstructor(targetNode);
     ClassEntity targetClass = target.enclosingClass;
-    IndexedClass superClass = _getSuperType(sourceClass)?.element;
+    IndexedClass superClass = getSuperType(sourceClass)?.element;
     if (superClass == targetClass) {
       return target;
     }
-    ClassEnv env = _classes.getEnv(superClass);
+    ClassEnv env = classes.getEnv(superClass);
     ConstructorEntity constructor = env.lookupConstructor(this, target.name);
     if (constructor != null) {
       return constructor;
@@ -399,19 +391,18 @@
   }
 
   @override
-  FunctionEntity getMethod(ir.Procedure node) => _getMethod(node);
+  FunctionEntity getMethod(ir.Procedure node) => getMethodInternal(node);
 
-  FunctionEntity _getMethod(ir.Procedure node);
+  FunctionEntity getMethodInternal(ir.Procedure node);
 
   @override
-  FieldEntity getField(ir.Field node) => _getField(node);
+  FieldEntity getField(ir.Field node) => getFieldInternal(node);
 
-  FieldEntity _getField(ir.Field node);
+  FieldEntity getFieldInternal(ir.Field node);
 
   @override
   DartType getDartType(ir.DartType type) => _typeConverter.convert(type);
 
-  @override
   TypeVariableType getTypeVariableType(ir.TypeParameterType type) =>
       getDartType(type);
 
@@ -423,7 +414,6 @@
     return list;
   }
 
-  @override
   InterfaceType getInterfaceType(ir.InterfaceType type) =>
       _typeConverter.convert(type);
 
@@ -494,7 +484,6 @@
         namedParameters, namedParameterTypes, typeVariables);
   }
 
-  @override
   ConstantValue computeConstantValue(
       Spannable spannable, ConstantExpression constant,
       {bool requireConstant: true}) {
@@ -502,140 +491,9 @@
         constantRequired: requireConstant);
   }
 
-  DartType _substByContext(DartType type, InterfaceType context) {
+  DartType substByContext(DartType type, InterfaceType context) {
     return type.subst(
-        context.typeArguments, _getThisType(context.element).typeArguments);
-  }
-
-  // TODO(johnniwinther): Remove this when call-type is provided by fasta.
-  void _ensureCallType(IndexedClass cls, ClassData data) {
-    if (!data.isCallTypeComputed) {
-      data.isCallTypeComputed = true;
-      if (!cls.isClosure) {
-        // In Dart 2, a regular class with a 'call' method is no longer a
-        // subtype of its function type.
-        return;
-      }
-      MemberEntity callMethod = lookupClassMember(cls, Identifiers.call);
-      if (callMethod != null) {
-        if (callMethod.isFunction) {
-          data.callType = _getFunctionType(callMethod);
-        } else {
-          data.callType = const DynamicType();
-        }
-        return;
-      }
-
-      Set<FunctionType> inheritedCallTypes = new Set<FunctionType>();
-      bool inheritsInvalidCallMember = false;
-
-      void addCallType(InterfaceType supertype) {
-        if (supertype == null) return;
-        DartType type = _getCallType(supertype);
-        if (type == null) return;
-        if (type.isFunctionType) {
-          inheritedCallTypes.add(type);
-        } else {
-          inheritsInvalidCallMember = true;
-        }
-      }
-
-      addCallType(_getSuperType(cls));
-      _getInterfaces(cls).forEach(addCallType);
-
-      // Following §11.1.1 in the spec.
-      if (inheritsInvalidCallMember) {
-        // From §11.1.1 in the spec (continued):
-        //
-        // If some but not all of the m_i, 1 ≤ i ≤ k are getters none of the m_i
-        // are inherited, and a static warning is issued.
-        data.callType = const DynamicType();
-      } else if (inheritedCallTypes.isEmpty) {
-        return;
-      } else if (inheritedCallTypes.length == 1) {
-        data.callType = inheritedCallTypes.single;
-      } else {
-        // From §11.1.1 in the spec (continued):
-        //
-        // Otherwise, if the static types T_1, ... , T_k of the members
-        // m_1, ..., m_k are not identical, then there must be a member m_x such
-        // that T_x <: T_i, 1 ≤ x ≤ k for all i ∈ 1..k, or a static type warning
-        // occurs.
-        List<FunctionType> subtypesOfAllInherited = <FunctionType>[];
-        outer:
-        for (FunctionType a in inheritedCallTypes) {
-          for (FunctionType b in inheritedCallTypes) {
-            if (identical(a, b)) continue;
-            if (!types.isSubtype(a, b)) continue outer;
-          }
-          subtypesOfAllInherited.add(a);
-        }
-        if (subtypesOfAllInherited.length == 1) {
-          // From §11.1.1 in the spec (continued):
-          //
-          // The member that is inherited is m_x, if it exists.
-          data.callType = subtypesOfAllInherited.single;
-          return;
-        }
-
-        // From §11.1.1 in the spec (continued):
-        //
-        // Otherwise: let numberOfPositionals(f) denote the number of
-        // positional parameters of a function f, and let
-        // numberOfRequiredParams(f) denote the number of required parameters of
-        // a function f. Furthermore, let s denote the set of all named
-        // parameters of the m_1, . . . , m_k. Then let
-        //
-        //     h = max(numberOfPositionals(mi)),
-        //     r = min(numberOfRequiredParams(mi)), i ∈ 1..k.
-
-        // Then I has a method named n, with r required parameters of type
-        // dynamic, h positional parameters of type dynamic, named parameters s
-        // of type dynamic and return type dynamic.
-
-        // Multiple signatures with different types => create the synthesized
-        // version.
-        int minRequiredParameters;
-        int maxPositionalParameters;
-        Set<String> names = new Set<String>();
-        for (FunctionType type in inheritedCallTypes) {
-          type.namedParameters.forEach((String name) => names.add(name));
-          int requiredParameters = type.parameterTypes.length;
-          int optionalParameters = type.optionalParameterTypes.length;
-          int positionalParameters = requiredParameters + optionalParameters;
-          if (minRequiredParameters == null ||
-              minRequiredParameters > requiredParameters) {
-            minRequiredParameters = requiredParameters;
-          }
-          if (maxPositionalParameters == null ||
-              maxPositionalParameters < positionalParameters) {
-            maxPositionalParameters = positionalParameters;
-          }
-        }
-        int optionalParameters =
-            maxPositionalParameters - minRequiredParameters;
-        // TODO(johnniwinther): Support function types with both optional
-        // and named parameters?
-        if (optionalParameters == 0 || names.isEmpty) {
-          DartType dynamic = const DynamicType();
-          List<DartType> requiredParameterTypes =
-              new List.filled(minRequiredParameters, dynamic);
-          List<DartType> optionalParameterTypes =
-              new List.filled(optionalParameters, dynamic);
-          List<String> namedParameters = names.toList()
-            ..sort((a, b) => a.compareTo(b));
-          List<DartType> namedParameterTypes =
-              new List.filled(namedParameters.length, dynamic);
-          data.callType = new FunctionType(dynamic, requiredParameterTypes,
-              optionalParameterTypes, namedParameters, namedParameterTypes,
-              // TODO(johnniwinther): Generate existential types here.
-              const <FunctionTypeVariable>[]);
-        } else {
-          // The function type is not valid.
-          data.callType = const DynamicType();
-        }
-      }
-    }
+        context.typeArguments, getThisType(context.element).typeArguments);
   }
 
   /// Returns the type of the `call` method on 'type'.
@@ -643,84 +501,90 @@
   /// If [type] doesn't have a `call` member `null` is returned. If [type] has
   /// an invalid `call` member (non-method or a synthesized method with both
   /// optional and named parameters) a [DynamicType] is returned.
-  DartType _getCallType(InterfaceType type) {
+  DartType getCallType(InterfaceType type) {
     IndexedClass cls = type.element;
     assert(checkFamily(cls));
-    ClassData data = _classes.getData(cls);
-    _ensureCallType(cls, data);
+    ClassData data = classes.getData(cls);
     if (data.callType != null) {
-      return _substByContext(data.callType, type);
+      return substByContext(data.callType, type);
     }
     return null;
   }
 
-  InterfaceType _getThisType(IndexedClass cls) {
+  InterfaceType getThisType(IndexedClass cls) {
     assert(checkFamily(cls));
-    ClassData data = _classes.getData(cls);
+    ClassData data = classes.getData(cls);
     _ensureThisAndRawType(cls, data);
     return data.thisType;
   }
 
   InterfaceType _getRawType(IndexedClass cls) {
     assert(checkFamily(cls));
-    ClassData data = _classes.getData(cls);
+    ClassData data = classes.getData(cls);
     _ensureThisAndRawType(cls, data);
     return data.rawType;
   }
 
   FunctionType _getFunctionType(IndexedFunction function) {
     assert(checkFamily(function));
-    FunctionData data = _members.getData(function);
+    FunctionData data = members.getData(function);
     return data.getFunctionType(this);
   }
 
   List<TypeVariableType> _getFunctionTypeVariables(IndexedFunction function) {
     assert(checkFamily(function));
-    FunctionData data = _members.getData(function);
+    FunctionData data = members.getData(function);
     return data.getFunctionTypeVariables(this);
   }
 
   DartType _getFieldType(IndexedField field) {
     assert(checkFamily(field));
-    FieldData data = _members.getData(field);
+    FieldData data = members.getData(field);
     return data.getFieldType(this);
   }
 
-  DartType _getTypeVariableBound(IndexedTypeVariable typeVariable) {
+  DartType getTypeVariableBound(IndexedTypeVariable typeVariable) {
     assert(checkFamily(typeVariable));
-    TypeVariableData data = _typeVariables.getData(typeVariable);
+    TypeVariableData data = typeVariables.getData(typeVariable);
     return data.getBound(this);
   }
 
   DartType _getTypeVariableDefaultType(IndexedTypeVariable typeVariable) {
     assert(checkFamily(typeVariable));
-    TypeVariableData data = _typeVariables.getData(typeVariable);
+    TypeVariableData data = typeVariables.getData(typeVariable);
     return data.getDefaultType(this);
   }
 
-  ClassEntity _getAppliedMixin(IndexedClass cls) {
+  ClassEntity getAppliedMixin(IndexedClass cls) {
     assert(checkFamily(cls));
-    ClassData data = _classes.getData(cls);
+    ClassData data = classes.getData(cls);
     _ensureSupertypes(cls, data);
     return data.mixedInType?.element;
   }
 
   bool _isMixinApplication(IndexedClass cls) {
     assert(checkFamily(cls));
-    ClassData data = _classes.getData(cls);
+    ClassData data = classes.getData(cls);
     _ensureSupertypes(cls, data);
     return data.isMixinApplication;
   }
 
   bool _isUnnamedMixinApplication(IndexedClass cls) {
     assert(checkFamily(cls));
-    ClassEnv env = _classes.getEnv(cls);
+    ClassEnv env = classes.getEnv(cls);
     return env.isUnnamedMixinApplication;
   }
 
+  bool _isSuperMixinApplication(IndexedClass cls) {
+    assert(checkFamily(cls));
+    ClassEnv env = classes.getEnv(cls);
+    env.ensureMembers(this);
+    return env.isSuperMixinApplication;
+  }
+
   void _forEachSupertype(IndexedClass cls, void f(InterfaceType supertype)) {
     assert(checkFamily(cls));
-    ClassData data = _classes.getData(cls);
+    ClassData data = classes.getData(cls);
     _ensureSupertypes(cls, data);
     data.orderedTypeSet.supertypes.forEach(f);
   }
@@ -728,7 +592,7 @@
   void _forEachMixin(IndexedClass cls, void f(ClassEntity mixin)) {
     assert(checkFamily(cls));
     while (cls != null) {
-      ClassData data = _classes.getData(cls);
+      ClassData data = classes.getData(cls);
       _ensureSupertypes(cls, data);
       if (data.mixedInType != null) {
         f(data.mixedInType.element);
@@ -739,28 +603,28 @@
 
   void _forEachConstructor(IndexedClass cls, void f(ConstructorEntity member)) {
     assert(checkFamily(cls));
-    ClassEnv env = _classes.getEnv(cls);
+    ClassEnv env = classes.getEnv(cls);
     env.forEachConstructor(this, f);
   }
 
-  void _forEachConstructorBody(
+  void forEachConstructorBody(
       IndexedClass cls, void f(ConstructorBodyEntity member)) {
     throw new UnsupportedError(
         'KernelToElementMapBase._forEachConstructorBody');
   }
 
-  void _forEachNestedClosure(
+  void forEachNestedClosure(
       MemberEntity member, void f(FunctionEntity closure));
 
   void _forEachLocalClassMember(IndexedClass cls, void f(MemberEntity member)) {
     assert(checkFamily(cls));
-    ClassEnv env = _classes.getEnv(cls);
+    ClassEnv env = classes.getEnv(cls);
     env.forEachMember(this, (MemberEntity member) {
       f(member);
     });
   }
 
-  void _forEachInjectedClassMember(
+  void forEachInjectedClassMember(
       IndexedClass cls, void f(MemberEntity member)) {
     assert(checkFamily(cls));
     throw new UnsupportedError(
@@ -770,11 +634,11 @@
   void _forEachClassMember(
       IndexedClass cls, void f(ClassEntity cls, MemberEntity member)) {
     assert(checkFamily(cls));
-    ClassEnv env = _classes.getEnv(cls);
+    ClassEnv env = classes.getEnv(cls);
     env.forEachMember(this, (MemberEntity member) {
       f(cls, member);
     });
-    ClassData data = _classes.getData(cls);
+    ClassData data = classes.getData(cls);
     _ensureSupertypes(cls, data);
     if (data.supertype != null) {
       _forEachClassMember(data.supertype.element, f);
@@ -783,91 +647,73 @@
 
   ConstantConstructor _getConstructorConstant(IndexedConstructor constructor) {
     assert(checkFamily(constructor));
-    ConstructorData data = _members.getData(constructor);
+    ConstructorData data = members.getData(constructor);
     return data.getConstructorConstant(this, constructor);
   }
 
   ConstantExpression _getFieldConstantExpression(IndexedField field) {
     assert(checkFamily(field));
-    FieldData data = _members.getData(field);
+    FieldData data = members.getData(field);
     return data.getFieldConstantExpression(this);
   }
 
-  InterfaceType _asInstanceOf(InterfaceType type, ClassEntity cls) {
+  InterfaceType asInstanceOf(InterfaceType type, ClassEntity cls) {
     assert(checkFamily(cls));
-    OrderedTypeSet orderedTypeSet = _getOrderedTypeSet(type.element);
+    OrderedTypeSet orderedTypeSet = getOrderedTypeSet(type.element);
     InterfaceType supertype =
-        orderedTypeSet.asInstanceOf(cls, _getHierarchyDepth(cls));
+        orderedTypeSet.asInstanceOf(cls, getHierarchyDepth(cls));
     if (supertype != null) {
-      supertype = _substByContext(supertype, type);
+      supertype = substByContext(supertype, type);
     }
     return supertype;
   }
 
-  OrderedTypeSet _getOrderedTypeSet(IndexedClass cls) {
+  OrderedTypeSet getOrderedTypeSet(IndexedClass cls) {
     assert(checkFamily(cls));
-    ClassData data = _classes.getData(cls);
+    ClassData data = classes.getData(cls);
     _ensureSupertypes(cls, data);
     return data.orderedTypeSet;
   }
 
-  int _getHierarchyDepth(IndexedClass cls) {
+  int getHierarchyDepth(IndexedClass cls) {
     assert(checkFamily(cls));
-    ClassData data = _classes.getData(cls);
+    ClassData data = classes.getData(cls);
     _ensureSupertypes(cls, data);
     return data.orderedTypeSet.maxDepth;
   }
 
-  Iterable<InterfaceType> _getInterfaces(IndexedClass cls) {
+  Iterable<InterfaceType> getInterfaces(IndexedClass cls) {
     assert(checkFamily(cls));
-    ClassData data = _classes.getData(cls);
+    ClassData data = classes.getData(cls);
     _ensureSupertypes(cls, data);
     return data.interfaces;
   }
 
-  Spannable _getSpannable(MemberEntity member, ir.Node node) {
-    SourceSpan sourceSpan;
-    if (node is ir.TreeNode) {
-      sourceSpan = computeSourceSpanFromTreeNode(node);
-    }
-    sourceSpan ??= getSourceSpan(member, null);
-    return sourceSpan;
-  }
-
-  MemberDefinition _getMemberDefinition(covariant IndexedMember member) {
+  MemberDefinition getMemberDefinitionInternal(covariant IndexedMember member) {
     assert(checkFamily(member));
-    return _members.getData(member).definition;
+    return members.getData(member).definition;
   }
 
-  ClassDefinition _getClassDefinition(covariant IndexedClass cls) {
+  ClassDefinition getClassDefinitionInternal(covariant IndexedClass cls) {
     assert(checkFamily(cls));
-    return _classes.getData(cls).definition;
+    return classes.getData(cls).definition;
   }
 
   ir.Typedef _getTypedefNode(covariant IndexedTypedef typedef) {
-    return _typedefs.getData(typedef).node;
+    return typedefs.getData(typedef).node;
   }
 
-  @override
   ImportEntity getImport(ir.LibraryDependency node) {
     ir.Library library = node.parent;
-    LibraryData data = _libraries.getData(_getLibrary(library));
+    LibraryData data = libraries.getData(getLibraryInternal(library));
     return data.imports[node];
   }
 
   DartType getStaticType(ir.Expression node) {
-    if (!_isStaticTypePrepared) {
-      _isStaticTypePrepared = true;
-      try {
-        _typeEnvironment ??= new ir.TypeEnvironment(
-            new ir.CoreTypes(_env.mainComponent),
-            new ir.ClassHierarchy(_env.mainComponent));
-      } catch (e) {}
-    }
     if (_typeEnvironment == null) {
-      // The class hierarchy crashes on multiple inheritance. Use `dynamic`
-      // as static type.
-      return commonElements.dynamicType;
+      _typeEnvironment ??= new ir.TypeEnvironment(
+          new ir.CoreTypes(env.mainComponent),
+          new ir.ClassHierarchy(env.mainComponent));
     }
     ir.TreeNode enclosingClass = node;
     while (enclosingClass != null && enclosingClass is! ir.Class) {
@@ -883,276 +729,20 @@
       return commonElements.dynamicType;
     }
   }
-}
 
-/// Mixin that implements the abstract methods in [KernelToElementMapBase].
-abstract class ElementCreatorMixin implements KernelToElementMapBase {
-  /// Set to `true` before creating the J-World from the K-World to assert that
-  /// no entities are created late.
-  bool _envIsClosed = false;
-  ProgramEnv get _env;
-  EntityDataEnvMap<IndexedLibrary, LibraryData, LibraryEnv> get _libraries;
-  EntityDataEnvMap<IndexedClass, ClassData, ClassEnv> get _classes;
-  EntityDataMap<IndexedMember, MemberData> get _members;
-  EntityDataMap<IndexedTypeVariable, TypeVariableData> get _typeVariables;
-  EntityDataMap<IndexedTypedef, TypedefData> get _typedefs;
-
-  Map<ir.Library, IndexedLibrary> _libraryMap = <ir.Library, IndexedLibrary>{};
-  Map<ir.Class, IndexedClass> _classMap = <ir.Class, IndexedClass>{};
-  Map<ir.Typedef, IndexedTypedef> _typedefMap = <ir.Typedef, IndexedTypedef>{};
-
-  /// Map from [ir.TypeParameter] nodes to the corresponding
-  /// [TypeVariableEntity].
-  ///
-  /// Normally the type variables are [IndexedTypeVariable]s, but for type
-  /// parameters on local function (in the frontend) these are _not_ since
-  /// their type declaration is neither a class nor a member. In the backend,
-  /// these type parameters belong to the call-method and are therefore indexed.
-  Map<ir.TypeParameter, TypeVariableEntity> _typeVariableMap =
-      <ir.TypeParameter, TypeVariableEntity>{};
-  Map<ir.Member, IndexedConstructor> _constructorMap =
-      <ir.Member, IndexedConstructor>{};
-  Map<ir.Procedure, IndexedFunction> _methodMap =
-      <ir.Procedure, IndexedFunction>{};
-  Map<ir.Field, IndexedField> _fieldMap = <ir.Field, IndexedField>{};
-  Map<ir.TreeNode, Local> _localFunctionMap = <ir.TreeNode, Local>{};
-
-  Name getName(ir.Name node);
-  FunctionType getFunctionType(ir.FunctionNode node);
-  MemberEntity getMember(ir.Member node);
-  Entity getClosure(ir.FunctionDeclaration node);
-
-  Iterable<LibraryEntity> get _libraryList {
-    if (_env.length != _libraryMap.length) {
-      // Create a [KLibrary] for each library.
-      _env.forEachLibrary((LibraryEnv env) {
-        _getLibrary(env.library, env);
-      });
-    }
-    return _libraryMap.values;
+  Name getName(ir.Name name) {
+    return new Name(
+        name.name, name.isPrivate ? getLibrary(name.library) : null);
   }
 
-  LibraryEntity _getLibrary(ir.Library node, [LibraryEnv libraryEnv]) {
-    return _libraryMap[node] ??= _getLibraryCreate(node, libraryEnv);
+  CallStructure getCallStructure(ir.Arguments arguments) {
+    int argumentCount = arguments.positional.length + arguments.named.length;
+    List<String> namedArguments = arguments.named.map((e) => e.name).toList();
+    return new CallStructure(
+        argumentCount, namedArguments, arguments.types.length);
   }
 
-  LibraryEntity _getLibraryCreate(ir.Library node, LibraryEnv libraryEnv) {
-    assert(
-        !_envIsClosed,
-        "Environment of $this is closed. Trying to create "
-        "library for $node.");
-    Uri canonicalUri = node.importUri;
-    String name = node.name;
-    if (name == null) {
-      // Use the file name as script name.
-      String path = canonicalUri.path;
-      name = path.substring(path.lastIndexOf('/') + 1);
-    }
-    IndexedLibrary library = createLibrary(name, canonicalUri);
-    return _libraries.register(library, new LibraryData(node),
-        libraryEnv ?? _env.lookupLibrary(canonicalUri));
-  }
-
-  ClassEntity _getClass(ir.Class node, [ClassEnv classEnv]) {
-    return _classMap[node] ??= _getClassCreate(node, classEnv);
-  }
-
-  ClassEntity _getClassCreate(ir.Class node, ClassEnv classEnv) {
-    assert(
-        !_envIsClosed,
-        "Environment of $this is closed. Trying to create "
-        "class for $node.");
-    KLibrary library = _getLibrary(node.enclosingLibrary);
-    if (classEnv == null) {
-      classEnv = _libraries.getEnv(library).lookupClass(node.name);
-    }
-    IndexedClass cls =
-        createClass(library, node.name, isAbstract: node.isAbstract);
-    return _classes.register(cls,
-        new ClassData(node, new RegularClassDefinition(cls, node)), classEnv);
-  }
-
-  TypedefEntity _getTypedef(ir.Typedef node) {
-    return _typedefMap[node] ??= _getTypedefCreate(node);
-  }
-
-  TypedefEntity _getTypedefCreate(ir.Typedef node) {
-    assert(
-        !_envIsClosed,
-        "Environment of $this is closed. Trying to create "
-        "typedef for $node.");
-    IndexedLibrary library = _getLibrary(node.enclosingLibrary);
-    IndexedTypedef typedef = createTypedef(library, node.name);
-    TypedefType typedefType = new TypedefType(
-        typedef,
-        new List<DartType>.filled(
-            node.typeParameters.length, const DynamicType()),
-        getDartType(node.type));
-    return _typedefs.register(
-        typedef, new TypedefData(node, typedef, typedefType));
-  }
-
-  TypeVariableEntity _getTypeVariable(ir.TypeParameter node) {
-    return _typeVariableMap[node] ??= _getTypeVariableCreate(node);
-  }
-
-  TypeVariableEntity _getTypeVariableCreate(ir.TypeParameter node) {
-    assert(
-        !_envIsClosed,
-        "Environment of $this is closed. Trying to create "
-        "type variable for $node.");
-    if (node.parent is ir.Class) {
-      ir.Class cls = node.parent;
-      int index = cls.typeParameters.indexOf(node);
-      return _typeVariables.register(
-          createTypeVariable(_getClass(cls), node.name, index),
-          new TypeVariableData(node));
-    }
-    if (node.parent is ir.FunctionNode) {
-      ir.FunctionNode func = node.parent;
-      int index = func.typeParameters.indexOf(node);
-      if (func.parent is ir.Constructor) {
-        ir.Constructor constructor = func.parent;
-        ir.Class cls = constructor.enclosingClass;
-        return _getTypeVariable(cls.typeParameters[index]);
-      } else if (func.parent is ir.Procedure) {
-        ir.Procedure procedure = func.parent;
-        if (procedure.kind == ir.ProcedureKind.Factory) {
-          ir.Class cls = procedure.enclosingClass;
-          return _getTypeVariable(cls.typeParameters[index]);
-        } else {
-          return _typeVariables.register(
-              createTypeVariable(_getMethod(procedure), node.name, index),
-              new TypeVariableData(node));
-        }
-      } else {
-        throw new UnsupportedError('Unsupported function type parameter parent '
-            'node ${func.parent}.');
-      }
-    }
-    throw new UnsupportedError('Unsupported type parameter type node $node.');
-  }
-
-  ConstructorEntity _getConstructor(ir.Member node) {
-    return _constructorMap[node] ??= _getConstructorCreate(node);
-  }
-
-  ConstructorEntity _getConstructorCreate(ir.Member node) {
-    assert(
-        !_envIsClosed,
-        "Environment of $this is closed. Trying to create "
-        "constructor for $node.");
-    MemberDefinition definition;
-    ir.FunctionNode functionNode;
-    ClassEntity enclosingClass = _getClass(node.enclosingClass);
-    Name name = getName(node.name);
-    bool isExternal = node.isExternal;
-
-    IndexedConstructor constructor;
-    if (node is ir.Constructor) {
-      functionNode = node.function;
-      constructor = createGenerativeConstructor(enclosingClass, name,
-          _getParameterStructure(functionNode, includeTypeParameters: false),
-          isExternal: isExternal, isConst: node.isConst);
-      definition = new SpecialMemberDefinition(
-          constructor, node, MemberKind.constructor);
-    } else if (node is ir.Procedure) {
-      functionNode = node.function;
-      bool isFromEnvironment = isExternal &&
-          name.text == 'fromEnvironment' &&
-          const ['int', 'bool', 'String'].contains(enclosingClass.name);
-      constructor = createFactoryConstructor(enclosingClass, name,
-          _getParameterStructure(functionNode, includeTypeParameters: false),
-          isExternal: isExternal,
-          isConst: node.isConst,
-          isFromEnvironmentConstructor: isFromEnvironment);
-      definition = new RegularMemberDefinition(constructor, node);
-    } else {
-      // TODO(johnniwinther): Convert `node.location` to a [SourceSpan].
-      throw failedAt(
-          NO_LOCATION_SPANNABLE, "Unexpected constructor node: ${node}.");
-    }
-    return _members.register<IndexedConstructor, ConstructorData>(
-        constructor, new ConstructorDataImpl(node, functionNode, definition));
-  }
-
-  FunctionEntity _getMethod(ir.Procedure node) {
-    return _methodMap[node] ??= _getMethodCreate(node);
-  }
-
-  FunctionEntity _getMethodCreate(ir.Procedure node) {
-    assert(
-        !_envIsClosed,
-        "Environment of $this is closed. Trying to create "
-        "function for $node.");
-    LibraryEntity library;
-    ClassEntity enclosingClass;
-    if (node.enclosingClass != null) {
-      enclosingClass = _getClass(node.enclosingClass);
-      library = enclosingClass.library;
-    } else {
-      library = _getLibrary(node.enclosingLibrary);
-    }
-    Name name = getName(node.name);
-    bool isStatic = node.isStatic;
-    bool isExternal = node.isExternal;
-    // TODO(johnniwinther): Remove `&& !node.isExternal` when #31233 is fixed.
-    bool isAbstract = node.isAbstract && !node.isExternal;
-    AsyncMarker asyncMarker = getAsyncMarker(node.function);
-    IndexedFunction function;
-    switch (node.kind) {
-      case ir.ProcedureKind.Factory:
-        throw new UnsupportedError("Cannot create method from factory.");
-      case ir.ProcedureKind.Getter:
-        function = createGetter(library, enclosingClass, name, asyncMarker,
-            isStatic: isStatic, isExternal: isExternal, isAbstract: isAbstract);
-        break;
-      case ir.ProcedureKind.Method:
-      case ir.ProcedureKind.Operator:
-        function = createMethod(library, enclosingClass, name,
-            _getParameterStructure(node.function), asyncMarker,
-            isStatic: isStatic, isExternal: isExternal, isAbstract: isAbstract);
-        break;
-      case ir.ProcedureKind.Setter:
-        assert(asyncMarker == AsyncMarker.SYNC);
-        function = createSetter(library, enclosingClass, name.setter,
-            isStatic: isStatic, isExternal: isExternal, isAbstract: isAbstract);
-        break;
-    }
-    return _members.register<IndexedFunction, FunctionData>(
-        function,
-        new FunctionDataImpl(
-            node, node.function, new RegularMemberDefinition(function, node)));
-  }
-
-  FieldEntity _getField(ir.Field node) {
-    return _fieldMap[node] ??= _getFieldCreate(node);
-  }
-
-  FieldEntity _getFieldCreate(ir.Field node) {
-    assert(
-        !_envIsClosed,
-        "Environment of $this is closed. Trying to create "
-        "field for $node.");
-    LibraryEntity library;
-    ClassEntity enclosingClass;
-    if (node.enclosingClass != null) {
-      enclosingClass = _getClass(node.enclosingClass);
-      library = enclosingClass.library;
-    } else {
-      library = _getLibrary(node.enclosingLibrary);
-    }
-    Name name = getName(node.name);
-    bool isStatic = node.isStatic;
-    IndexedField field = createField(library, enclosingClass, name,
-        isStatic: isStatic,
-        isAssignable: node.isMutable,
-        isConst: node.isConst);
-    return _members.register<IndexedField, FieldData>(field,
-        new FieldDataImpl(node, new RegularMemberDefinition(field, node)));
-  }
-
-  ParameterStructure _getParameterStructure(ir.FunctionNode node,
+  ParameterStructure getParameterStructure(ir.FunctionNode node,
       // TODO(johnniwinther): Remove this when type arguments are passed to
       // constructors like calling a generic method.
       {bool includeTypeParameters: true}) {
@@ -1166,6 +756,592 @@
         namedParameters, includeTypeParameters ? typeParameters : 0);
   }
 
+  Selector getSelector(ir.Expression node) {
+    // TODO(efortuna): This is screaming for a common interface between
+    // PropertyGet and SuperPropertyGet (and same for *Get). Talk to kernel
+    // folks.
+    if (node is ir.PropertyGet) {
+      return getGetterSelector(node.name);
+    }
+    if (node is ir.SuperPropertyGet) {
+      return getGetterSelector(node.name);
+    }
+    if (node is ir.PropertySet) {
+      return getSetterSelector(node.name);
+    }
+    if (node is ir.SuperPropertySet) {
+      return getSetterSelector(node.name);
+    }
+    if (node is ir.InvocationExpression) {
+      return getInvocationSelector(node);
+    }
+    throw failedAt(
+        CURRENT_ELEMENT_SPANNABLE,
+        "Can only get the selector for a property get or an invocation: "
+        "${node}");
+  }
+
+  Selector getInvocationSelector(ir.InvocationExpression invocation) {
+    Name name = getName(invocation.name);
+    SelectorKind kind;
+    if (Selector.isOperatorName(name.text)) {
+      if (name == Names.INDEX_NAME || name == Names.INDEX_SET_NAME) {
+        kind = SelectorKind.INDEX;
+      } else {
+        kind = SelectorKind.OPERATOR;
+      }
+    } else {
+      kind = SelectorKind.CALL;
+    }
+
+    CallStructure callStructure = getCallStructure(invocation.arguments);
+    return new Selector(kind, name, callStructure);
+  }
+
+  Selector getGetterSelector(ir.Name irName) {
+    Name name = new Name(
+        irName.name, irName.isPrivate ? getLibrary(irName.library) : null);
+    return new Selector.getter(name);
+  }
+
+  Selector getSetterSelector(ir.Name irName) {
+    Name name = new Name(
+        irName.name, irName.isPrivate ? getLibrary(irName.library) : null);
+    return new Selector.setter(name);
+  }
+
+  /// Looks up [typeName] for use in the spec-string of a `JS` call.
+  // TODO(johnniwinther): Use this in [native.NativeBehavior] instead of calling
+  // the `ForeignResolver`.
+  native.TypeLookup typeLookup({bool resolveAsRaw: true}) {
+    return resolveAsRaw
+        ? (_cachedTypeLookupRaw ??= _typeLookup(resolveAsRaw: true))
+        : (_cachedTypeLookupFull ??= _typeLookup(resolveAsRaw: false));
+  }
+
+  native.TypeLookup _cachedTypeLookupRaw;
+  native.TypeLookup _cachedTypeLookupFull;
+
+  native.TypeLookup _typeLookup({bool resolveAsRaw: true}) {
+    bool cachedMayLookupInMain;
+    bool mayLookupInMain() {
+      var mainUri = elementEnvironment.mainLibrary.canonicalUri;
+      // Tests permit lookup outside of dart: libraries.
+      return mainUri.path.contains('tests/compiler/dart2js_native') ||
+          mainUri.path.contains('tests/compiler/dart2js_extra');
+    }
+
+    DartType lookup(String typeName, {bool required}) {
+      DartType findInLibrary(LibraryEntity library) {
+        if (library != null) {
+          ClassEntity cls = elementEnvironment.lookupClass(library, typeName);
+          if (cls != null) {
+            // TODO(johnniwinther): Align semantics.
+            return resolveAsRaw
+                ? elementEnvironment.getRawType(cls)
+                : elementEnvironment.getThisType(cls);
+          }
+        }
+        return null;
+      }
+
+      DartType findIn(Uri uri) {
+        return findInLibrary(elementEnvironment.lookupLibrary(uri));
+      }
+
+      // TODO(johnniwinther): Narrow the set of lookups based on the depending
+      // library.
+      // TODO(johnniwinther): Cache more results to avoid redundant lookups?
+      DartType type;
+      if (cachedMayLookupInMain ??= mayLookupInMain()) {
+        type ??= findInLibrary(elementEnvironment.mainLibrary);
+      }
+      type ??= findIn(Uris.dart_core);
+      type ??= findIn(Uris.dart__js_helper);
+      type ??= findIn(Uris.dart__interceptors);
+      type ??= findIn(Uris.dart__native_typed_data);
+      type ??= findIn(Uris.dart_collection);
+      type ??= findIn(Uris.dart_math);
+      type ??= findIn(Uris.dart_html);
+      type ??= findIn(Uris.dart_html_common);
+      type ??= findIn(Uris.dart_svg);
+      type ??= findIn(Uris.dart_web_audio);
+      type ??= findIn(Uris.dart_web_gl);
+      type ??= findIn(Uris.dart_web_sql);
+      type ??= findIn(Uris.dart_indexed_db);
+      type ??= findIn(Uris.dart_typed_data);
+      type ??= findIn(Uris.dart_mirrors);
+      if (type == null && required) {
+        reporter.reportErrorMessage(CURRENT_ELEMENT_SPANNABLE,
+            MessageKind.GENERIC, {'text': "Type '$typeName' not found."});
+      }
+      return type;
+    }
+
+    return lookup;
+  }
+
+  String _getStringArgument(ir.StaticInvocation node, int index) {
+    return node.arguments.positional[index].accept(new Stringifier());
+  }
+
+  /// Computes the [native.NativeBehavior] for a call to the [JS] function.
+  // TODO(johnniwinther): Cache this for later use.
+  native.NativeBehavior getNativeBehaviorForJsCall(ir.StaticInvocation node) {
+    if (node.arguments.positional.length < 2 ||
+        node.arguments.named.isNotEmpty) {
+      reporter.reportErrorMessage(
+          CURRENT_ELEMENT_SPANNABLE, MessageKind.WRONG_ARGUMENT_FOR_JS);
+      return new native.NativeBehavior();
+    }
+    String specString = _getStringArgument(node, 0);
+    if (specString == null) {
+      reporter.reportErrorMessage(
+          CURRENT_ELEMENT_SPANNABLE, MessageKind.WRONG_ARGUMENT_FOR_JS_FIRST);
+      return new native.NativeBehavior();
+    }
+
+    String codeString = _getStringArgument(node, 1);
+    if (codeString == null) {
+      reporter.reportErrorMessage(
+          CURRENT_ELEMENT_SPANNABLE, MessageKind.WRONG_ARGUMENT_FOR_JS_SECOND);
+      return new native.NativeBehavior();
+    }
+
+    return native.NativeBehavior.ofJsCall(
+        specString,
+        codeString,
+        typeLookup(resolveAsRaw: true),
+        CURRENT_ELEMENT_SPANNABLE,
+        reporter,
+        commonElements);
+  }
+
+  /// Computes the [native.NativeBehavior] for a call to the [JS_BUILTIN]
+  /// function.
+  // TODO(johnniwinther): Cache this for later use.
+  native.NativeBehavior getNativeBehaviorForJsBuiltinCall(
+      ir.StaticInvocation node) {
+    if (node.arguments.positional.length < 1) {
+      reporter.internalError(
+          CURRENT_ELEMENT_SPANNABLE, "JS builtin expression has no type.");
+      return new native.NativeBehavior();
+    }
+    if (node.arguments.positional.length < 2) {
+      reporter.internalError(
+          CURRENT_ELEMENT_SPANNABLE, "JS builtin is missing name.");
+      return new native.NativeBehavior();
+    }
+    String specString = _getStringArgument(node, 0);
+    if (specString == null) {
+      reporter.internalError(
+          CURRENT_ELEMENT_SPANNABLE, "Unexpected first argument.");
+      return new native.NativeBehavior();
+    }
+    return native.NativeBehavior.ofJsBuiltinCall(
+        specString,
+        typeLookup(resolveAsRaw: true),
+        CURRENT_ELEMENT_SPANNABLE,
+        reporter,
+        commonElements);
+  }
+
+  /// Computes the [native.NativeBehavior] for a call to the
+  /// [JS_EMBEDDED_GLOBAL] function.
+  // TODO(johnniwinther): Cache this for later use.
+  native.NativeBehavior getNativeBehaviorForJsEmbeddedGlobalCall(
+      ir.StaticInvocation node) {
+    if (node.arguments.positional.length < 1) {
+      reporter.internalError(CURRENT_ELEMENT_SPANNABLE,
+          "JS embedded global expression has no type.");
+      return new native.NativeBehavior();
+    }
+    if (node.arguments.positional.length < 2) {
+      reporter.internalError(
+          CURRENT_ELEMENT_SPANNABLE, "JS embedded global is missing name.");
+      return new native.NativeBehavior();
+    }
+    if (node.arguments.positional.length > 2 ||
+        node.arguments.named.isNotEmpty) {
+      reporter.internalError(CURRENT_ELEMENT_SPANNABLE,
+          "JS embedded global has more than 2 arguments.");
+      return new native.NativeBehavior();
+    }
+    String specString = _getStringArgument(node, 0);
+    if (specString == null) {
+      reporter.internalError(
+          CURRENT_ELEMENT_SPANNABLE, "Unexpected first argument.");
+      return new native.NativeBehavior();
+    }
+    return native.NativeBehavior.ofJsEmbeddedGlobalCall(
+        specString,
+        typeLookup(resolveAsRaw: true),
+        CURRENT_ELEMENT_SPANNABLE,
+        reporter,
+        commonElements);
+  }
+
+  js.Name getNameForJsGetName(ConstantValue constant, Namer namer) {
+    int index = extractEnumIndexFromConstantValue(
+        constant, commonElements.jsGetNameEnum);
+    if (index == null) return null;
+    return namer.getNameForJsGetName(
+        CURRENT_ELEMENT_SPANNABLE, JsGetName.values[index]);
+  }
+
+  int extractEnumIndexFromConstantValue(
+      ConstantValue constant, ClassEntity classElement) {
+    if (constant is ConstructedConstantValue) {
+      if (constant.type.element == classElement) {
+        assert(constant.fields.length == 1 || constant.fields.length == 2);
+        ConstantValue indexConstant = constant.fields.values.first;
+        if (indexConstant is IntConstantValue) {
+          return indexConstant.intValue.toInt();
+        }
+      }
+    }
+    return null;
+  }
+
+  ConstantValue getConstantValue(ir.Expression node,
+      {bool requireConstant: true, bool implicitNull: false}) {
+    ConstantExpression constant;
+    if (node == null) {
+      if (!implicitNull) {
+        throw failedAt(
+            CURRENT_ELEMENT_SPANNABLE, 'No expression for constant.');
+      }
+      constant = new NullConstantExpression();
+    } else {
+      constant =
+          new Constantifier(this, requireConstant: requireConstant).visit(node);
+    }
+    if (constant == null) {
+      if (requireConstant) {
+        throw new UnsupportedError(
+            'No constant for ${DebugPrinter.prettyPrint(node)}');
+      }
+      return null;
+    }
+    ConstantValue value = computeConstantValue(
+        computeSourceSpanFromTreeNode(node), constant,
+        requireConstant: requireConstant);
+    if (!value.isConstant && !requireConstant) {
+      return null;
+    }
+    return value;
+  }
+
+  /// Converts [annotations] into a list of [ConstantValue]s.
+  List<ConstantValue> getMetadata(List<ir.Expression> annotations) {
+    if (annotations.isEmpty) return const <ConstantValue>[];
+    List<ConstantValue> metadata = <ConstantValue>[];
+    annotations.forEach((ir.Expression node) {
+      metadata.add(getConstantValue(node));
+    });
+    return metadata;
+  }
+
+  FunctionEntity getSuperNoSuchMethod(ClassEntity cls) {
+    while (cls != null) {
+      cls = elementEnvironment.getSuperClass(cls);
+      MemberEntity member = elementEnvironment.lookupLocalClassMember(
+          cls, Identifiers.noSuchMethod_);
+      if (member != null && !member.isAbstract) {
+        if (member.isFunction) {
+          FunctionEntity function = member;
+          if (function.parameterStructure.positionalParameters >= 1) {
+            return function;
+          }
+        }
+        // If [member] is not a valid `noSuchMethod` the target is
+        // `Object.superNoSuchMethod`.
+        break;
+      }
+    }
+    FunctionEntity function = elementEnvironment.lookupLocalClassMember(
+        commonElements.objectClass, Identifiers.noSuchMethod_);
+    assert(function != null,
+        failedAt(cls, "No super noSuchMethod found for class $cls."));
+    return function;
+  }
+}
+
+/// Mixin that implements the abstract methods in [KernelToElementMapBase].
+abstract class ElementCreatorMixin implements KernelToElementMapBase {
+  /// Set to `true` before creating the J-World from the K-World to assert that
+  /// no entities are created late.
+  bool envIsClosed = false;
+  ProgramEnv get env;
+  EntityDataEnvMap<IndexedLibrary, LibraryData, LibraryEnv> get libraries;
+  EntityDataEnvMap<IndexedClass, ClassData, ClassEnv> get classes;
+  EntityDataMap<IndexedMember, MemberData> get members;
+  EntityDataMap<IndexedTypeVariable, TypeVariableData> get typeVariables;
+  EntityDataMap<IndexedTypedef, TypedefData> get typedefs;
+
+  final Map<ir.Library, IndexedLibrary> libraryMap = {};
+  final Map<ir.Class, IndexedClass> classMap = {};
+  final Map<ir.Typedef, IndexedTypedef> typedefMap = {};
+
+  /// Map from [ir.TypeParameter] nodes to the corresponding
+  /// [TypeVariableEntity].
+  ///
+  /// Normally the type variables are [IndexedTypeVariable]s, but for type
+  /// parameters on local function (in the frontend) these are _not_ since
+  /// their type declaration is neither a class nor a member. In the backend,
+  /// these type parameters belong to the call-method and are therefore indexed.
+  final Map<ir.TypeParameter, TypeVariableEntity> typeVariableMap = {};
+  final Map<ir.Member, IndexedConstructor> constructorMap = {};
+  final Map<ir.Procedure, IndexedFunction> methodMap = {};
+  final Map<ir.Field, IndexedField> fieldMap = {};
+  final Map<ir.TreeNode, Local> localFunctionMap = {};
+
+  Name getName(ir.Name node);
+  FunctionType getFunctionType(ir.FunctionNode node);
+  MemberEntity getMember(ir.Member node);
+  Entity getClosure(ir.FunctionDeclaration node);
+
+  Iterable<LibraryEntity> get libraryListInternal {
+    if (env.length != libraryMap.length) {
+      // Create a [KLibrary] for each library.
+      env.forEachLibrary((LibraryEnv env) {
+        getLibraryInternal(env.library, env);
+      });
+    }
+    return libraryMap.values;
+  }
+
+  LibraryEntity getLibraryInternal(ir.Library node, [LibraryEnv libraryEnv]) {
+    return libraryMap[node] ??= _getLibraryCreate(node, libraryEnv);
+  }
+
+  LibraryEntity _getLibraryCreate(ir.Library node, LibraryEnv libraryEnv) {
+    assert(
+        !envIsClosed,
+        "Environment of $this is closed. Trying to create "
+        "library for $node.");
+    Uri canonicalUri = node.importUri;
+    String name = node.name;
+    if (name == null) {
+      // Use the file name as script name.
+      String path = canonicalUri.path;
+      name = path.substring(path.lastIndexOf('/') + 1);
+    }
+    IndexedLibrary library = createLibrary(name, canonicalUri);
+    return libraries.register(library, new LibraryData(node),
+        libraryEnv ?? env.lookupLibrary(canonicalUri));
+  }
+
+  ClassEntity getClassInternal(ir.Class node, [ClassEnv classEnv]) {
+    return classMap[node] ??= _getClassCreate(node, classEnv);
+  }
+
+  ClassEntity _getClassCreate(ir.Class node, ClassEnv classEnv) {
+    assert(
+        !envIsClosed,
+        "Environment of $this is closed. Trying to create "
+        "class for $node.");
+    KLibrary library = getLibraryInternal(node.enclosingLibrary);
+    if (classEnv == null) {
+      classEnv = libraries.getEnv(library).lookupClass(node.name);
+    }
+    IndexedClass cls =
+        createClass(library, node.name, isAbstract: node.isAbstract);
+    return classes.register(
+        cls,
+        new ClassDataImpl(node, new RegularClassDefinition(cls, node)),
+        classEnv);
+  }
+
+  TypedefEntity getTypedefInternal(ir.Typedef node) {
+    return typedefMap[node] ??= _getTypedefCreate(node);
+  }
+
+  TypedefEntity _getTypedefCreate(ir.Typedef node) {
+    assert(
+        !envIsClosed,
+        "Environment of $this is closed. Trying to create "
+        "typedef for $node.");
+    IndexedLibrary library = getLibraryInternal(node.enclosingLibrary);
+    IndexedTypedef typedef = createTypedef(library, node.name);
+    TypedefType typedefType = new TypedefType(
+        typedef,
+        new List<DartType>.filled(
+            node.typeParameters.length, const DynamicType()),
+        getDartType(node.type));
+    return typedefs.register(
+        typedef, new TypedefData(node, typedef, typedefType));
+  }
+
+  TypeVariableEntity getTypeVariableInternal(ir.TypeParameter node) {
+    return typeVariableMap[node] ??= _getTypeVariableCreate(node);
+  }
+
+  TypeVariableEntity _getTypeVariableCreate(ir.TypeParameter node) {
+    assert(
+        !envIsClosed,
+        "Environment of $this is closed. Trying to create "
+        "type variable for $node.");
+    if (node.parent is ir.Class) {
+      ir.Class cls = node.parent;
+      int index = cls.typeParameters.indexOf(node);
+      return typeVariables.register(
+          createTypeVariable(getClassInternal(cls), node.name, index),
+          new TypeVariableData(node));
+    }
+    if (node.parent is ir.FunctionNode) {
+      ir.FunctionNode func = node.parent;
+      int index = func.typeParameters.indexOf(node);
+      if (func.parent is ir.Constructor) {
+        ir.Constructor constructor = func.parent;
+        ir.Class cls = constructor.enclosingClass;
+        return getTypeVariableInternal(cls.typeParameters[index]);
+      } else if (func.parent is ir.Procedure) {
+        ir.Procedure procedure = func.parent;
+        if (procedure.kind == ir.ProcedureKind.Factory) {
+          ir.Class cls = procedure.enclosingClass;
+          return getTypeVariableInternal(cls.typeParameters[index]);
+        } else {
+          return typeVariables.register(
+              createTypeVariable(
+                  getMethodInternal(procedure), node.name, index),
+              new TypeVariableData(node));
+        }
+      } else {
+        throw new UnsupportedError('Unsupported function type parameter parent '
+            'node ${func.parent}.');
+      }
+    }
+    throw new UnsupportedError('Unsupported type parameter type node $node.');
+  }
+
+  ConstructorEntity getConstructorInternal(ir.Member node) {
+    return constructorMap[node] ??= _getConstructorCreate(node);
+  }
+
+  ConstructorEntity _getConstructorCreate(ir.Member node) {
+    assert(
+        !envIsClosed,
+        "Environment of $this is closed. Trying to create "
+        "constructor for $node.");
+    MemberDefinition definition;
+    ir.FunctionNode functionNode;
+    ClassEntity enclosingClass = getClassInternal(node.enclosingClass);
+    Name name = getName(node.name);
+    bool isExternal = node.isExternal;
+
+    IndexedConstructor constructor;
+    if (node is ir.Constructor) {
+      functionNode = node.function;
+      constructor = createGenerativeConstructor(enclosingClass, name,
+          getParameterStructure(functionNode, includeTypeParameters: false),
+          isExternal: isExternal, isConst: node.isConst);
+      definition = new SpecialMemberDefinition(
+          constructor, node, MemberKind.constructor);
+    } else if (node is ir.Procedure) {
+      functionNode = node.function;
+      bool isFromEnvironment = isExternal &&
+          name.text == 'fromEnvironment' &&
+          const ['int', 'bool', 'String'].contains(enclosingClass.name);
+      constructor = createFactoryConstructor(enclosingClass, name,
+          getParameterStructure(functionNode, includeTypeParameters: false),
+          isExternal: isExternal,
+          isConst: node.isConst,
+          isFromEnvironmentConstructor: isFromEnvironment);
+      definition = new RegularMemberDefinition(constructor, node);
+    } else {
+      // TODO(johnniwinther): Convert `node.location` to a [SourceSpan].
+      throw failedAt(
+          NO_LOCATION_SPANNABLE, "Unexpected constructor node: ${node}.");
+    }
+    return members.register<IndexedConstructor, ConstructorData>(
+        constructor, new ConstructorDataImpl(node, functionNode, definition));
+  }
+
+  FunctionEntity getMethodInternal(ir.Procedure node) {
+    // [_getMethodCreate] inserts the created function in [methodMap] so we
+    // don't need to use ??= here.
+    return methodMap[node] ?? _getMethodCreate(node);
+  }
+
+  FunctionEntity _getMethodCreate(ir.Procedure node) {
+    assert(
+        !envIsClosed,
+        "Environment of $this is closed. Trying to create "
+        "function for $node.");
+    FunctionEntity function;
+    LibraryEntity library;
+    ClassEntity enclosingClass;
+    if (node.enclosingClass != null) {
+      enclosingClass = getClassInternal(node.enclosingClass);
+      library = enclosingClass.library;
+    } else {
+      library = getLibraryInternal(node.enclosingLibrary);
+    }
+    Name name = getName(node.name);
+    bool isStatic = node.isStatic;
+    bool isExternal = node.isExternal;
+    // TODO(johnniwinther): Remove `&& !node.isExternal` when #31233 is fixed.
+    bool isAbstract = node.isAbstract && !node.isExternal;
+    AsyncMarker asyncMarker = getAsyncMarker(node.function);
+    switch (node.kind) {
+      case ir.ProcedureKind.Factory:
+        throw new UnsupportedError("Cannot create method from factory.");
+      case ir.ProcedureKind.Getter:
+        function = createGetter(library, enclosingClass, name, asyncMarker,
+            isStatic: isStatic, isExternal: isExternal, isAbstract: isAbstract);
+        break;
+      case ir.ProcedureKind.Method:
+      case ir.ProcedureKind.Operator:
+        function = createMethod(library, enclosingClass, name,
+            getParameterStructure(node.function), asyncMarker,
+            isStatic: isStatic, isExternal: isExternal, isAbstract: isAbstract);
+        break;
+      case ir.ProcedureKind.Setter:
+        assert(asyncMarker == AsyncMarker.SYNC);
+        function = createSetter(library, enclosingClass, name.setter,
+            isStatic: isStatic, isExternal: isExternal, isAbstract: isAbstract);
+        break;
+    }
+    members.register<IndexedFunction, FunctionData>(
+        function,
+        new FunctionDataImpl(
+            node, node.function, new RegularMemberDefinition(function, node)));
+    // We need to register the function before creating the type variables.
+    methodMap[node] = function;
+    for (ir.TypeParameter typeParameter in node.function.typeParameters) {
+      getTypeVariable(typeParameter);
+    }
+    return function;
+  }
+
+  FieldEntity getFieldInternal(ir.Field node) {
+    return fieldMap[node] ??= _getFieldCreate(node);
+  }
+
+  FieldEntity _getFieldCreate(ir.Field node) {
+    assert(
+        !envIsClosed,
+        "Environment of $this is closed. Trying to create "
+        "field for $node.");
+    LibraryEntity library;
+    ClassEntity enclosingClass;
+    if (node.enclosingClass != null) {
+      enclosingClass = getClassInternal(node.enclosingClass);
+      library = enclosingClass.library;
+    } else {
+      library = getLibraryInternal(node.enclosingLibrary);
+    }
+    Name name = getName(node.name);
+    bool isStatic = node.isStatic;
+    IndexedField field = createField(library, enclosingClass, name,
+        isStatic: isStatic,
+        isAssignable: node.isMutable,
+        isConst: node.isConst);
+    return members.register<IndexedField, FieldData>(field,
+        new FieldDataImpl(node, new RegularMemberDefinition(field, node)));
+  }
+
   IndexedLibrary createLibrary(String name, Uri canonicalUri);
 
   IndexedClass createClass(LibraryEntity library, String name,
@@ -1207,8 +1383,269 @@
       {bool isStatic, bool isAssignable, bool isConst});
 }
 
-/// Completes the [ElementCreatorMixin] by creating K-model elements.
-abstract class KElementCreatorMixin implements ElementCreatorMixin {
+/// Implementation of [KernelToElementMap] that only supports world
+/// impact computation.
+class KernelToElementMapImpl extends KernelToElementMapBase
+    with ElementCreatorMixin
+    implements KernelToElementMap {
+  native.BehaviorBuilder _nativeBehaviorBuilder;
+  FrontendStrategy _frontendStrategy;
+
+  KernelToElementMapImpl(DiagnosticReporter reporter, Environment environment,
+      this._frontendStrategy, CompilerOptions options)
+      : super(options, reporter, environment);
+
+  @override
+  bool checkFamily(Entity entity) {
+    assert(
+        '$entity'.startsWith(kElementPrefix),
+        failedAt(entity,
+            "Unexpected entity $entity, expected family $kElementPrefix."));
+    return true;
+  }
+
+  DartType getTypeVariableBound(TypeVariableEntity typeVariable) {
+    if (typeVariable is KLocalTypeVariable) return typeVariable.bound;
+    return super.getTypeVariableBound(typeVariable);
+  }
+
+  DartType _getTypeVariableDefaultType(TypeVariableEntity typeVariable) {
+    if (typeVariable is KLocalTypeVariable) return typeVariable.defaultType;
+    return super._getTypeVariableDefaultType(typeVariable);
+  }
+
+  @override
+  void forEachNestedClosure(
+      MemberEntity member, void f(FunctionEntity closure)) {
+    throw new UnsupportedError(
+        "KernelToElementMapForImpactImpl._forEachNestedClosure");
+  }
+
+  @override
+  NativeBasicData get nativeBasicData => _frontendStrategy.nativeBasicData;
+
+  /// Adds libraries in [component] to the set of libraries.
+  ///
+  /// The main method of the first component is used as the main method for the
+  /// compilation.
+  void addComponent(ir.Component component) {
+    env.addComponent(component);
+  }
+
+  native.BehaviorBuilder get nativeBehaviorBuilder =>
+      _nativeBehaviorBuilder ??= new KernelBehaviorBuilder(elementEnvironment,
+          commonElements, nativeBasicData, reporter, options);
+
+  ResolutionImpact computeWorldImpact(KMember member) {
+    return buildKernelImpact(
+        members.getData(member).definition.node, this, reporter, options);
+  }
+
+  ScopeModel computeScopeModel(KMember member) {
+    ir.Member node = members.getData(member).definition.node;
+    return KernelClosureAnalysis.computeScopeModel(member, node);
+  }
+
+  /// Returns the kernel [ir.Procedure] node for the [method].
+  ir.Procedure _lookupProcedure(KFunction method) {
+    return members.getData(method).definition.node;
+  }
+
+  @override
+  ir.Library getLibraryNode(LibraryEntity library) {
+    return libraries.getData(library).library;
+  }
+
+  @override
+  Entity getClosure(ir.FunctionDeclaration node) {
+    return getLocalFunction(node);
+  }
+
+  @override
+  Local getLocalFunction(ir.TreeNode node) {
+    assert(
+        node is ir.FunctionDeclaration || node is ir.FunctionExpression,
+        failedAt(
+            CURRENT_ELEMENT_SPANNABLE, 'Invalid local function node: $node'));
+    KLocalFunction localFunction = localFunctionMap[node];
+    if (localFunction == null) {
+      MemberEntity memberContext;
+      Entity executableContext;
+      ir.TreeNode parent = node.parent;
+      while (parent != null) {
+        if (parent is ir.Member) {
+          executableContext = memberContext = getMember(parent);
+          break;
+        }
+        if (parent is ir.FunctionDeclaration ||
+            parent is ir.FunctionExpression) {
+          KLocalFunction localFunction = getLocalFunction(parent);
+          executableContext = localFunction;
+          memberContext = localFunction.memberContext;
+          break;
+        }
+        parent = parent.parent;
+      }
+      String name;
+      ir.FunctionNode function;
+      if (node is ir.FunctionDeclaration) {
+        name = node.variable.name;
+        function = node.function;
+      } else if (node is ir.FunctionExpression) {
+        function = node.function;
+      }
+      localFunction = localFunctionMap[node] =
+          new KLocalFunction(name, memberContext, executableContext, node);
+      int index = 0;
+      List<KLocalTypeVariable> typeVariables = <KLocalTypeVariable>[];
+      for (ir.TypeParameter typeParameter in function.typeParameters) {
+        typeVariables.add(typeVariableMap[typeParameter] =
+            new KLocalTypeVariable(localFunction, typeParameter.name, index));
+        index++;
+      }
+      index = 0;
+      for (ir.TypeParameter typeParameter in function.typeParameters) {
+        typeVariables[index].bound = getDartType(typeParameter.bound);
+        typeVariables[index].defaultType =
+            getDartType(typeParameter.defaultType);
+        index++;
+      }
+      localFunction.functionType = getFunctionType(function);
+    }
+    return localFunction;
+  }
+
+  bool _implementsFunction(IndexedClass cls) {
+    assert(checkFamily(cls));
+    ClassData data = classes.getData(cls);
+    OrderedTypeSet orderedTypeSet = data.orderedTypeSet;
+    InterfaceType supertype = orderedTypeSet.asInstanceOf(
+        commonElements.functionClass,
+        getHierarchyDepth(commonElements.functionClass));
+    if (supertype != null) {
+      return true;
+    }
+    return data.callType is FunctionType;
+  }
+
+  @override
+  MemberDefinition getMemberDefinition(MemberEntity member) {
+    return getMemberDefinitionInternal(member);
+  }
+
+  @override
+  ClassDefinition getClassDefinition(ClassEntity cls) {
+    return getClassDefinitionInternal(cls);
+  }
+
+  @override
+  ir.Typedef getTypedefNode(TypedefEntity typedef) {
+    return _getTypedefNode(typedef);
+  }
+
+  /// Returns the element type of a async/sync*/async* function.
+  @override
+  DartType getFunctionAsyncOrSyncStarElementType(ir.FunctionNode functionNode) {
+    DartType returnType = getDartType(functionNode.returnType);
+    switch (functionNode.asyncMarker) {
+      case ir.AsyncMarker.SyncStar:
+        return elementEnvironment.getAsyncOrSyncStarElementType(
+            AsyncMarker.SYNC_STAR, returnType);
+      case ir.AsyncMarker.Async:
+        return elementEnvironment.getAsyncOrSyncStarElementType(
+            AsyncMarker.ASYNC, returnType);
+      case ir.AsyncMarker.AsyncStar:
+        return elementEnvironment.getAsyncOrSyncStarElementType(
+            AsyncMarker.ASYNC_STAR, returnType);
+      default:
+        failedAt(CURRENT_ELEMENT_SPANNABLE,
+            "Unexpected ir.AsyncMarker: ${functionNode.asyncMarker}");
+    }
+    return null;
+  }
+
+  /// Returns `true` is [node] has a `@Native(...)` annotation.
+  // TODO(johnniwinther): Cache this for later use.
+  bool isNativeClass(ir.Class node) {
+    for (ir.Expression annotation in node.annotations) {
+      if (annotation is ir.ConstructorInvocation) {
+        FunctionEntity target = getConstructor(annotation.target);
+        if (target.enclosingClass == commonElements.nativeAnnotationClass) {
+          return true;
+        }
+      }
+    }
+    return false;
+  }
+
+  /// Compute the kind of foreign helper function called by [node], if any.
+  ForeignKind getForeignKind(ir.StaticInvocation node) {
+    if (commonElements.isForeignHelper(getMember(node.target))) {
+      switch (node.target.name.name) {
+        case JavaScriptBackend.JS:
+          return ForeignKind.JS;
+        case JavaScriptBackend.JS_BUILTIN:
+          return ForeignKind.JS_BUILTIN;
+        case JavaScriptBackend.JS_EMBEDDED_GLOBAL:
+          return ForeignKind.JS_EMBEDDED_GLOBAL;
+        case JavaScriptBackend.JS_INTERCEPTOR_CONSTANT:
+          return ForeignKind.JS_INTERCEPTOR_CONSTANT;
+      }
+    }
+    return ForeignKind.NONE;
+  }
+
+  /// Computes the [InterfaceType] referenced by a call to the
+  /// [JS_INTERCEPTOR_CONSTANT] function, if any.
+  InterfaceType getInterfaceTypeForJsInterceptorCall(ir.StaticInvocation node) {
+    if (node.arguments.positional.length != 1 ||
+        node.arguments.named.isNotEmpty) {
+      reporter.reportErrorMessage(CURRENT_ELEMENT_SPANNABLE,
+          MessageKind.WRONG_ARGUMENT_FOR_JS_INTERCEPTOR_CONSTANT);
+    }
+    ir.Node argument = node.arguments.positional.first;
+    if (argument is ir.TypeLiteral && argument.type is ir.InterfaceType) {
+      return getInterfaceType(argument.type);
+    }
+    return null;
+  }
+
+  /// Computes the native behavior for reading the native [field].
+  // TODO(johnniwinther): Cache this for later use.
+  native.NativeBehavior getNativeBehaviorForFieldLoad(ir.Field field,
+      {bool isJsInterop}) {
+    DartType type = getDartType(field.type);
+    List<ConstantValue> metadata = getMetadata(field.annotations);
+    return nativeBehaviorBuilder.buildFieldLoadBehavior(
+        type, metadata, typeLookup(resolveAsRaw: false),
+        isJsInterop: isJsInterop);
+  }
+
+  /// Computes the native behavior for writing to the native [field].
+  // TODO(johnniwinther): Cache this for later use.
+  native.NativeBehavior getNativeBehaviorForFieldStore(ir.Field field) {
+    DartType type = getDartType(field.type);
+    return nativeBehaviorBuilder.buildFieldStoreBehavior(type);
+  }
+
+  /// Computes the native behavior for calling [member].
+  // TODO(johnniwinther): Cache this for later use.
+  native.NativeBehavior getNativeBehaviorForMethod(ir.Member member,
+      {bool isJsInterop}) {
+    DartType type;
+    if (member is ir.Procedure) {
+      type = getFunctionType(member.function);
+    } else if (member is ir.Constructor) {
+      type = getFunctionType(member.function);
+    } else {
+      failedAt(CURRENT_ELEMENT_SPANNABLE, "Unexpected method node $member.");
+    }
+    List<ConstantValue> metadata = getMetadata(member.annotations);
+    return nativeBehaviorBuilder.buildMethodBehavior(
+        type, metadata, typeLookup(resolveAsRaw: false),
+        isJsInterop: isJsInterop);
+  }
+
   IndexedLibrary createLibrary(String name, Uri canonicalUri) {
     return new KLibrary(name, canonicalUri);
   }
@@ -1280,192 +1717,6 @@
   }
 }
 
-/// Implementation of [KernelToElementMapForImpact] that only supports world
-/// impact computation.
-class KernelToElementMapForImpactImpl extends KernelToElementMapBase
-    with
-        KernelToElementMapForImpactMixin,
-        ElementCreatorMixin,
-        KElementCreatorMixin {
-  native.BehaviorBuilder _nativeBehaviorBuilder;
-  FrontendStrategy _frontendStrategy;
-
-  KernelToElementMapForImpactImpl(DiagnosticReporter reporter,
-      Environment environment, this._frontendStrategy, CompilerOptions options)
-      : super(options, reporter, environment);
-
-  @override
-  bool checkFamily(Entity entity) {
-    assert(
-        '$entity'.startsWith(kElementPrefix),
-        failedAt(entity,
-            "Unexpected entity $entity, expected family $kElementPrefix."));
-    return true;
-  }
-
-  DartType _getTypeVariableBound(TypeVariableEntity typeVariable) {
-    if (typeVariable is KLocalTypeVariable) return typeVariable.bound;
-    return super._getTypeVariableBound(typeVariable);
-  }
-
-  DartType _getTypeVariableDefaultType(TypeVariableEntity typeVariable) {
-    if (typeVariable is KLocalTypeVariable) return typeVariable.defaultType;
-    return super._getTypeVariableDefaultType(typeVariable);
-  }
-
-  @override
-  void _forEachNestedClosure(
-      MemberEntity member, void f(FunctionEntity closure)) {
-    throw new UnsupportedError(
-        "KernelToElementMapForImpactImpl._forEachNestedClosure");
-  }
-
-  @override
-  NativeBasicData get nativeBasicData => _frontendStrategy.nativeBasicData;
-
-  /// Adds libraries in [component] to the set of libraries.
-  ///
-  /// The main method of the first component is used as the main method for the
-  /// compilation.
-  void addComponent(ir.Component component) {
-    _env.addComponent(component);
-  }
-
-  @override
-  native.BehaviorBuilder get nativeBehaviorBuilder =>
-      _nativeBehaviorBuilder ??= new KernelBehaviorBuilder(elementEnvironment,
-          commonElements, nativeBasicData, reporter, options);
-
-  ResolutionImpact computeWorldImpact(KMember member) {
-    return buildKernelImpact(
-        _members.getData(member).definition.node, this, reporter, options);
-  }
-
-  ScopeModel computeScopeModel(KMember member) {
-    ir.Member node = _members.getData(member).definition.node;
-    return KernelClosureAnalysis.computeScopeModel(member, node);
-  }
-
-  /// Returns the kernel [ir.Procedure] node for the [method].
-  ir.Procedure _lookupProcedure(KFunction method) {
-    return _members.getData(method).definition.node;
-  }
-
-  @override
-  ir.Library getLibraryNode(LibraryEntity library) {
-    return _libraries.getData(library).library;
-  }
-
-  @override
-  Entity getClosure(ir.FunctionDeclaration node) {
-    return getLocalFunction(node);
-  }
-
-  @override
-  Local getLocalFunction(ir.TreeNode node) {
-    assert(
-        node is ir.FunctionDeclaration || node is ir.FunctionExpression,
-        failedAt(
-            CURRENT_ELEMENT_SPANNABLE, 'Invalid local function node: $node'));
-    KLocalFunction localFunction = _localFunctionMap[node];
-    if (localFunction == null) {
-      MemberEntity memberContext;
-      Entity executableContext;
-      ir.TreeNode parent = node.parent;
-      while (parent != null) {
-        if (parent is ir.Member) {
-          executableContext = memberContext = getMember(parent);
-          break;
-        }
-        if (parent is ir.FunctionDeclaration ||
-            parent is ir.FunctionExpression) {
-          KLocalFunction localFunction = getLocalFunction(parent);
-          executableContext = localFunction;
-          memberContext = localFunction.memberContext;
-          break;
-        }
-        parent = parent.parent;
-      }
-      String name;
-      ir.FunctionNode function;
-      if (node is ir.FunctionDeclaration) {
-        name = node.variable.name;
-        function = node.function;
-      } else if (node is ir.FunctionExpression) {
-        function = node.function;
-      }
-      localFunction = _localFunctionMap[node] =
-          new KLocalFunction(name, memberContext, executableContext, node);
-      int index = 0;
-      List<KLocalTypeVariable> typeVariables = <KLocalTypeVariable>[];
-      for (ir.TypeParameter typeParameter in function.typeParameters) {
-        typeVariables.add(_typeVariableMap[typeParameter] =
-            new KLocalTypeVariable(localFunction, typeParameter.name, index));
-        index++;
-      }
-      index = 0;
-      for (ir.TypeParameter typeParameter in function.typeParameters) {
-        typeVariables[index].bound = getDartType(typeParameter.bound);
-        typeVariables[index].defaultType =
-            getDartType(typeParameter.defaultType);
-        index++;
-      }
-      localFunction.functionType = getFunctionType(function);
-    }
-    return localFunction;
-  }
-
-  bool _implementsFunction(IndexedClass cls) {
-    assert(checkFamily(cls));
-    ClassData data = _classes.getData(cls);
-    OrderedTypeSet orderedTypeSet = data.orderedTypeSet;
-    InterfaceType supertype = orderedTypeSet.asInstanceOf(
-        commonElements.functionClass,
-        _getHierarchyDepth(commonElements.functionClass));
-    if (supertype != null) {
-      return true;
-    }
-    _ensureCallType(cls, data);
-    return data.callType is FunctionType;
-  }
-
-  @override
-  MemberDefinition getMemberDefinition(MemberEntity member) {
-    return _getMemberDefinition(member);
-  }
-
-  @override
-  ClassDefinition getClassDefinition(ClassEntity cls) {
-    return _getClassDefinition(cls);
-  }
-
-  @override
-  ir.Typedef getTypedefNode(TypedefEntity typedef) {
-    return _getTypedefNode(typedef);
-  }
-
-  /// Returns the element type of a async/sync*/async* function.
-  @override
-  DartType getFunctionAsyncOrSyncStarElementType(ir.FunctionNode functionNode) {
-    DartType returnType = getDartType(functionNode.returnType);
-    switch (functionNode.asyncMarker) {
-      case ir.AsyncMarker.SyncStar:
-        return elementEnvironment.getAsyncOrSyncStarElementType(
-            AsyncMarker.SYNC_STAR, returnType);
-      case ir.AsyncMarker.Async:
-        return elementEnvironment.getAsyncOrSyncStarElementType(
-            AsyncMarker.ASYNC, returnType);
-      case ir.AsyncMarker.AsyncStar:
-        return elementEnvironment.getAsyncOrSyncStarElementType(
-            AsyncMarker.ASYNC_STAR, returnType);
-      default:
-        failedAt(CURRENT_ELEMENT_SPANNABLE,
-            "Unexpected ir.AsyncMarker: ${functionNode.asyncMarker}");
-    }
-    return null;
-  }
-}
-
 class KernelElementEnvironment extends ElementEnvironment {
   final KernelToElementMapBase elementMap;
 
@@ -1481,7 +1732,7 @@
   FunctionEntity get mainFunction => elementMap._mainFunction;
 
   @override
-  Iterable<LibraryEntity> get libraries => elementMap._libraryList;
+  Iterable<LibraryEntity> get libraries => elementMap.libraryListInternal;
 
   @override
   String getLibraryName(LibraryEntity library) {
@@ -1490,7 +1741,7 @@
 
   @override
   InterfaceType getThisType(ClassEntity cls) {
-    return elementMap._getThisType(cls);
+    return elementMap.getThisType(cls);
   }
 
   @override
@@ -1514,17 +1765,22 @@
   }
 
   @override
+  bool isSuperMixinApplication(ClassEntity cls) {
+    return elementMap._isSuperMixinApplication(cls);
+  }
+
+  @override
   ClassEntity getEffectiveMixinClass(ClassEntity cls) {
     if (!isMixinApplication(cls)) return null;
     do {
-      cls = elementMap._getAppliedMixin(cls);
+      cls = elementMap.getAppliedMixin(cls);
     } while (isMixinApplication(cls));
     return cls;
   }
 
   @override
   DartType getTypeVariableBound(TypeVariableEntity typeVariable) {
-    return elementMap._getTypeVariableBound(typeVariable);
+    return elementMap.getTypeVariableBound(typeVariable);
   }
 
   @override
@@ -1635,11 +1891,11 @@
   ClassEntity getSuperClass(ClassEntity cls,
       {bool skipUnnamedMixinApplications: false}) {
     assert(elementMap.checkFamily(cls));
-    ClassEntity superclass = elementMap._getSuperType(cls)?.element;
+    ClassEntity superclass = elementMap.getSuperType(cls)?.element;
     if (skipUnnamedMixinApplications) {
       while (superclass != null &&
           elementMap._isUnnamedMixinApplication(superclass)) {
-        superclass = elementMap._getSuperType(superclass)?.element;
+        superclass = elementMap.getSuperType(superclass)?.element;
       }
     }
     return superclass;
@@ -1663,7 +1919,7 @@
   @override
   void forEachInjectedClassMember(
       ClassEntity cls, void f(MemberEntity member)) {
-    elementMap._forEachInjectedClassMember(cls, f);
+    elementMap.forEachInjectedClassMember(cls, f);
   }
 
   @override
@@ -1682,13 +1938,13 @@
   @override
   void forEachConstructorBody(
       ClassEntity cls, void f(ConstructorBodyEntity constructor)) {
-    elementMap._forEachConstructorBody(cls, f);
+    elementMap.forEachConstructorBody(cls, f);
   }
 
   @override
   void forEachNestedClosure(
       MemberEntity member, void f(FunctionEntity closure)) {
-    elementMap._forEachNestedClosure(member, f);
+    elementMap.forEachNestedClosure(member, f);
   }
 
   @override
@@ -1744,21 +2000,21 @@
   @override
   Iterable<ConstantValue> getLibraryMetadata(covariant IndexedLibrary library) {
     assert(elementMap.checkFamily(library));
-    LibraryData libraryData = elementMap._libraries.getData(library);
+    LibraryData libraryData = elementMap.libraries.getData(library);
     return libraryData.getMetadata(elementMap);
   }
 
   @override
   Iterable<ImportEntity> getImports(covariant IndexedLibrary library) {
     assert(elementMap.checkFamily(library));
-    LibraryData libraryData = elementMap._libraries.getData(library);
+    LibraryData libraryData = elementMap.libraries.getData(library);
     return libraryData.getImports(elementMap);
   }
 
   @override
   Iterable<ConstantValue> getClassMetadata(covariant IndexedClass cls) {
     assert(elementMap.checkFamily(cls));
-    ClassData classData = elementMap._classes.getData(cls);
+    ClassData classData = elementMap.classes.getData(cls);
     return classData.getMetadata(elementMap);
   }
 
@@ -1767,131 +2023,18 @@
       {bool includeParameterMetadata: false}) {
     // TODO(redemption): Support includeParameterMetadata.
     assert(elementMap.checkFamily(member));
-    MemberData memberData = elementMap._members.getData(member);
+    MemberData memberData = elementMap.members.getData(member);
     return memberData.getMetadata(elementMap);
   }
 
   @override
   bool isEnumClass(ClassEntity cls) {
     assert(elementMap.checkFamily(cls));
-    ClassData classData = elementMap._classes.getData(cls);
+    ClassData classData = elementMap.classes.getData(cls);
     return classData.isEnumClass;
   }
 }
 
-/// Visitor that converts kernel dart types into [DartType].
-class DartTypeConverter extends ir.DartTypeVisitor<DartType> {
-  final KernelToElementMapBase elementMap;
-  final Map<ir.TypeParameter, DartType> currentFunctionTypeParameters =
-      <ir.TypeParameter, DartType>{};
-  bool topLevel = true;
-
-  DartTypeConverter(this.elementMap);
-
-  DartType convert(ir.DartType type) {
-    topLevel = true;
-    return type.accept(this);
-  }
-
-  /// Visit a inner type.
-  DartType visitType(ir.DartType type) {
-    topLevel = false;
-    return type.accept(this);
-  }
-
-  InterfaceType visitSupertype(ir.Supertype node) {
-    ClassEntity cls = elementMap.getClass(node.classNode);
-    return new InterfaceType(cls, visitTypes(node.typeArguments));
-  }
-
-  List<DartType> visitTypes(List<ir.DartType> types) {
-    topLevel = false;
-    return new List.generate(
-        types.length, (int index) => types[index].accept(this));
-  }
-
-  @override
-  DartType visitTypeParameterType(ir.TypeParameterType node) {
-    DartType typeParameter = currentFunctionTypeParameters[node.parameter];
-    if (typeParameter != null) {
-      return typeParameter;
-    }
-    if (node.parameter.parent is ir.Typedef) {
-      // Typedefs are only used in type literals so we never need their type
-      // variables.
-      return const DynamicType();
-    }
-    return new TypeVariableType(elementMap.getTypeVariable(node.parameter));
-  }
-
-  @override
-  DartType visitFunctionType(ir.FunctionType node) {
-    int index = 0;
-    List<FunctionTypeVariable> typeVariables;
-    for (ir.TypeParameter typeParameter in node.typeParameters) {
-      FunctionTypeVariable typeVariable = new FunctionTypeVariable(index);
-      currentFunctionTypeParameters[typeParameter] = typeVariable;
-      typeVariables ??= <FunctionTypeVariable>[];
-      typeVariables.add(typeVariable);
-      index++;
-    }
-    if (typeVariables != null) {
-      for (int index = 0; index < typeVariables.length; index++) {
-        typeVariables[index].bound =
-            node.typeParameters[index].bound.accept(this);
-      }
-    }
-
-    FunctionType type = new FunctionType(
-        visitType(node.returnType),
-        visitTypes(node.positionalParameters
-            .take(node.requiredParameterCount)
-            .toList()),
-        visitTypes(node.positionalParameters
-            .skip(node.requiredParameterCount)
-            .toList()),
-        node.namedParameters.map((n) => n.name).toList(),
-        node.namedParameters.map((n) => visitType(n.type)).toList(),
-        typeVariables ?? const <FunctionTypeVariable>[]);
-    for (ir.TypeParameter typeParameter in node.typeParameters) {
-      currentFunctionTypeParameters.remove(typeParameter);
-    }
-    return type;
-  }
-
-  @override
-  DartType visitInterfaceType(ir.InterfaceType node) {
-    ClassEntity cls = elementMap.getClass(node.classNode);
-    if (cls.name == 'FutureOr' &&
-        cls.library == elementMap.commonElements.asyncLibrary) {
-      return new FutureOrType(visitTypes(node.typeArguments).single);
-    }
-    return new InterfaceType(cls, visitTypes(node.typeArguments));
-  }
-
-  @override
-  DartType visitVoidType(ir.VoidType node) {
-    return const VoidType();
-  }
-
-  @override
-  DartType visitDynamicType(ir.DynamicType node) {
-    return const DynamicType();
-  }
-
-  @override
-  DartType visitInvalidType(ir.InvalidType node) {
-    // Root uses such a `o is Unresolved` and `o as Unresolved` must be special
-    // cased in the builder, nested invalid types are treated as `dynamic`.
-    return const DynamicType();
-  }
-
-  @override
-  DartType visitBottomType(ir.BottomType node) {
-    return elementMap.commonElements.nullType;
-  }
-}
-
 /// [native.BehaviorBuilder] for kernel based elements.
 class KernelBehaviorBuilder extends native.BehaviorBuilder {
   final ElementEnvironment elementEnvironment;
@@ -1953,7 +2096,7 @@
 
   @override
   DartType substByContext(DartType base, InterfaceType target) {
-    return _elementMap._substByContext(base, target);
+    return _elementMap.substByContext(base, target);
   }
 
   @override
@@ -1983,77 +2126,8 @@
   bool get enableAssertions => _elementMap.options.enableUserAssertions;
 }
 
-abstract class KernelClosedWorldMixin implements ClosedWorldBase {
-  KernelToElementMapBase get elementMap;
-
-  @override
-  bool hasElementIn(ClassEntity cls, Selector selector, Entity element) {
-    while (cls != null) {
-      MemberEntity member = elementEnvironment.lookupLocalClassMember(
-          cls, selector.name,
-          setter: selector.isSetter);
-      if (member != null &&
-          !member.isAbstract &&
-          (!selector.memberName.isPrivate ||
-              member.library == selector.library)) {
-        return member == element;
-      }
-      cls = elementEnvironment.getSuperClass(cls);
-    }
-    return false;
-  }
-
-  @override
-  bool hasConcreteMatch(ClassEntity cls, Selector selector,
-      {ClassEntity stopAtSuperclass}) {
-    assert(classHierarchy.isInstantiated(cls),
-        failedAt(cls, '$cls has not been instantiated.'));
-    MemberEntity element = elementEnvironment
-        .lookupClassMember(cls, selector.name, setter: selector.isSetter);
-    if (element == null) return false;
-
-    if (element.isAbstract) {
-      ClassEntity enclosingClass = element.enclosingClass;
-      return hasConcreteMatch(
-          elementEnvironment.getSuperClass(enclosingClass), selector);
-    }
-    return selector.appliesUntyped(element);
-  }
-
-  @override
-  bool isNamedMixinApplication(ClassEntity cls) {
-    return elementMap._isMixinApplication(cls) &&
-        !elementMap._isUnnamedMixinApplication(cls);
-  }
-
-  @override
-  ClassEntity getAppliedMixin(ClassEntity cls) {
-    return elementMap._getAppliedMixin(cls);
-  }
-
-  @override
-  Iterable<ClassEntity> getInterfaces(ClassEntity cls) {
-    return elementMap._getInterfaces(cls).map((t) => t.element);
-  }
-
-  @override
-  ClassEntity getSuperClass(ClassEntity cls) {
-    return elementMap._getSuperType(cls)?.element;
-  }
-
-  @override
-  int getHierarchyDepth(ClassEntity cls) {
-    return elementMap._getHierarchyDepth(cls);
-  }
-
-  @override
-  OrderedTypeSet getOrderedTypeSet(ClassEntity cls) {
-    return elementMap._getOrderedTypeSet(cls);
-  }
-}
-
 class KClosedWorldImpl extends ClosedWorldRtiNeedMixin implements KClosedWorld {
-  final KernelToElementMapForImpactImpl elementMap;
+  final KernelToElementMapImpl elementMap;
   final ElementEnvironment elementEnvironment;
   final DartTypes dartTypes;
   final CommonElements commonElements;
@@ -2081,6 +2155,8 @@
 
   final ClassHierarchy classHierarchy;
 
+  final AnnotationsData annotationsData;
+
   KClosedWorldImpl(this.elementMap,
       {CompilerOptions options,
       this.elementEnvironment,
@@ -2101,7 +2177,8 @@
       this.mixinUses,
       this.typesImplementedBySubclasses,
       Map<ClassEntity, ClassHierarchyNode> classHierarchyNodes,
-      Map<ClassEntity, ClassSet> classSets})
+      Map<ClassEntity, ClassSet> classSets,
+      this.annotationsData})
       : _implementedClasses = implementedClasses,
         classHierarchy = new ClassHierarchyImpl(
             commonElements, classHierarchyNodes, classSets) {
@@ -2114,34 +2191,8 @@
   }
 }
 
-// Interface for testing equivalence of Kernel-based entities.
-class WorldDeconstructionForTesting {
-  final KernelToElementMapBase elementMap;
-
-  WorldDeconstructionForTesting(this.elementMap);
-
-  IndexedClass getSuperclassForClass(IndexedClass cls) {
-    ClassEnv env = elementMap._classes.getEnv(cls);
-    ir.Supertype supertype = env.cls.supertype;
-    if (supertype == null) return null;
-    return elementMap.getClass(supertype.classNode);
-  }
-
-  bool isUnnamedMixinApplication(IndexedClass cls) {
-    return elementMap._isUnnamedMixinApplication(cls);
-  }
-
-  InterfaceType getMixinTypeForClass(IndexedClass cls) {
-    ClassEnv env = elementMap._classes.getEnv(cls);
-    ir.Supertype mixedInType = env.cls.mixedInType;
-    if (mixedInType == null) return null;
-    return elementMap.createInterfaceType(
-        mixedInType.classNode, mixedInType.typeArguments);
-  }
-}
-
 class KernelNativeMemberResolver extends NativeMemberResolverBase {
-  final KernelToElementMapForImpactImpl elementMap;
+  final KernelToElementMapImpl elementMap;
   final NativeBasicData nativeBasicData;
   final NativeDataBuilder nativeDataBuilder;
 
@@ -2157,14 +2208,14 @@
   @override
   native.NativeBehavior computeNativeFieldStoreBehavior(
       covariant KField field) {
-    ir.Field node = elementMap._members.getData(field).definition.node;
+    ir.Field node = elementMap.members.getData(field).definition.node;
     return elementMap.getNativeBehaviorForFieldStore(node);
   }
 
   @override
   native.NativeBehavior computeNativeFieldLoadBehavior(covariant KField field,
       {bool isJsInterop}) {
-    ir.Field node = elementMap._members.getData(field).definition.node;
+    ir.Field node = elementMap.members.getData(field).definition.node;
     return elementMap.getNativeBehaviorForFieldLoad(node,
         isJsInterop: isJsInterop);
   }
@@ -2173,7 +2224,7 @@
   native.NativeBehavior computeNativeMethodBehavior(
       covariant KFunction function,
       {bool isJsInterop}) {
-    ir.Member node = elementMap._members.getData(function).definition.node;
+    ir.Member node = elementMap.members.getData(function).definition.node;
     return elementMap.getNativeBehaviorForMethod(node,
         isJsInterop: isJsInterop);
   }
@@ -2181,7 +2232,7 @@
   @override
   bool isNativeMethod(covariant KFunction function) {
     if (!native.maybeEnableNative(function.library.canonicalUri)) return false;
-    ir.Member node = elementMap._members.getData(function).definition.node;
+    ir.Member node = elementMap.members.getData(function).definition.node;
     return node.annotations.any((ir.Expression expression) {
       return expression is ir.ConstructorInvocation &&
           elementMap.getInterfaceType(expression.constructedType) ==
@@ -2202,19 +2253,19 @@
   JsToFrontendMapImpl(this._backend);
 
   LibraryEntity toBackendLibrary(covariant IndexedLibrary library) {
-    return _backend._libraries.getEntity(library.libraryIndex);
+    return _backend.libraries.getEntity(library.libraryIndex);
   }
 
   ClassEntity toBackendClass(covariant IndexedClass cls) {
-    return _backend._classes.getEntity(cls.classIndex);
+    return _backend.classes.getEntity(cls.classIndex);
   }
 
   MemberEntity toBackendMember(covariant IndexedMember member) {
-    return _backend._members.getEntity(member.memberIndex);
+    return _backend.members.getEntity(member.memberIndex);
   }
 
   TypedefEntity toBackendTypedef(covariant IndexedTypedef typedef) {
-    return _backend._typedefs.getEntity(typedef.typedefIndex);
+    return _backend.typedefs.getEntity(typedef.typedefIndex);
   }
 
   TypeVariableEntity toBackendTypeVariable(TypeVariableEntity typeVariable) {
@@ -2223,732 +2274,13 @@
           typeVariable, "Local function type variables are not supported.");
     }
     IndexedTypeVariable indexedTypeVariable = typeVariable;
-    return _backend._typeVariables
+    return _backend.typeVariables
         .getEntity(indexedTypeVariable.typeVariableIndex);
   }
 }
 
-class JsKernelToElementMap extends KernelToElementMapBase
-    with
-        KernelToElementMapForBuildingMixin,
-        JsElementCreatorMixin,
-        // TODO(johnniwinther): Avoid mixing in [ElementCreatorMixin]. The
-        // codegen world should be a strict subset of the resolution world and
-        // creating elements for IR nodes should therefore not be needed.
-        // Currently some are created purely for testing (like
-        // `element == commonElements.foo`, where 'foo' might not be live).
-        // Others are created because we do a
-        // `elementEnvironment.forEachLibraryMember(...)` call on each emitted
-        // library.
-        ElementCreatorMixin
-    implements
-        KernelToWorldBuilder {
-  /// Map from members to the call methods created for their nested closures.
-  Map<MemberEntity, List<FunctionEntity>> _nestedClosureMap =
-      <MemberEntity, List<FunctionEntity>>{};
-
-  NativeBasicData nativeBasicData;
-
-  Map<FunctionEntity, JGeneratorBody> _generatorBodies =
-      <FunctionEntity, JGeneratorBody>{};
-
-  Map<ClassEntity, List<MemberEntity>> _injectedClassMembers =
-      <ClassEntity, List<MemberEntity>>{};
-
-  JsKernelToElementMap(
-      DiagnosticReporter reporter,
-      Environment environment,
-      KernelToElementMapForImpactImpl _elementMap,
-      Iterable<MemberEntity> liveMembers)
-      : super(_elementMap.options, reporter, environment) {
-    _env = _elementMap._env;
-    for (int libraryIndex = 0;
-        libraryIndex < _elementMap._libraries.length;
-        libraryIndex++) {
-      IndexedLibrary oldLibrary =
-          _elementMap._libraries.getEntity(libraryIndex);
-      LibraryEnv env = _elementMap._libraries.getEnv(oldLibrary);
-      LibraryData data = _elementMap._libraries.getData(oldLibrary);
-      IndexedLibrary newLibrary = convertLibrary(oldLibrary);
-      _libraryMap[env.library] =
-          _libraries.register<IndexedLibrary, LibraryData, LibraryEnv>(
-              newLibrary,
-              data.copy(),
-              useStrongModeWorldStrategy
-                  ? env.copyLive(_elementMap, liveMembers)
-                  : env);
-      assert(newLibrary.libraryIndex == oldLibrary.libraryIndex);
-    }
-    for (int classIndex = 0;
-        classIndex < _elementMap._classes.length;
-        classIndex++) {
-      IndexedClass oldClass = _elementMap._classes.getEntity(classIndex);
-      ClassEnv env = _elementMap._classes.getEnv(oldClass);
-      ClassData data = _elementMap._classes.getData(oldClass);
-      IndexedLibrary oldLibrary = oldClass.library;
-      LibraryEntity newLibrary = _libraries.getEntity(oldLibrary.libraryIndex);
-      IndexedClass newClass = convertClass(newLibrary, oldClass);
-      _classMap[env.cls] = _classes.register(
-          newClass,
-          data.copy(),
-          useStrongModeWorldStrategy
-              ? env.copyLive(_elementMap, liveMembers)
-              : env);
-      assert(newClass.classIndex == oldClass.classIndex);
-    }
-    for (int typedefIndex = 0;
-        typedefIndex < _elementMap._typedefs.length;
-        typedefIndex++) {
-      IndexedTypedef oldTypedef = _elementMap._typedefs.getEntity(typedefIndex);
-      TypedefData data = _elementMap._typedefs.getData(oldTypedef);
-      IndexedLibrary oldLibrary = oldTypedef.library;
-      LibraryEntity newLibrary = _libraries.getEntity(oldLibrary.libraryIndex);
-      IndexedTypedef newTypedef = convertTypedef(newLibrary, oldTypedef);
-      _typedefMap[data.node] = _typedefs.register(
-          newTypedef,
-          new TypedefData(
-              data.node,
-              newTypedef,
-              new TypedefType(
-                  newTypedef,
-                  new List<DartType>.filled(
-                      data.node.typeParameters.length, const DynamicType()),
-                  getDartType(data.node.type))));
-      assert(newTypedef.typedefIndex == oldTypedef.typedefIndex);
-    }
-    for (int memberIndex = 0;
-        memberIndex < _elementMap._members.length;
-        memberIndex++) {
-      IndexedMember oldMember = _elementMap._members.getEntity(memberIndex);
-      if (useStrongModeWorldStrategy && !liveMembers.contains(oldMember)) {
-        _members.skipIndex(oldMember.memberIndex);
-        continue;
-      }
-      MemberDataImpl data = _elementMap._members.getData(oldMember);
-      IndexedLibrary oldLibrary = oldMember.library;
-      IndexedClass oldClass = oldMember.enclosingClass;
-      LibraryEntity newLibrary = _libraries.getEntity(oldLibrary.libraryIndex);
-      ClassEntity newClass =
-          oldClass != null ? _classes.getEntity(oldClass.classIndex) : null;
-      IndexedMember newMember = convertMember(newLibrary, newClass, oldMember);
-      _members.register(newMember, data.copy());
-      assert(newMember.memberIndex == oldMember.memberIndex);
-      if (newMember.isField) {
-        _fieldMap[data.node] = newMember;
-      } else if (newMember.isConstructor) {
-        _constructorMap[data.node] = newMember;
-      } else {
-        _methodMap[data.node] = newMember;
-      }
-    }
-    for (int typeVariableIndex = 0;
-        typeVariableIndex < _elementMap._typeVariables.length;
-        typeVariableIndex++) {
-      IndexedTypeVariable oldTypeVariable =
-          _elementMap._typeVariables.getEntity(typeVariableIndex);
-      TypeVariableData oldTypeVariableData =
-          _elementMap._typeVariables.getData(oldTypeVariable);
-      Entity newTypeDeclaration;
-      if (oldTypeVariable.typeDeclaration is ClassEntity) {
-        IndexedClass cls = oldTypeVariable.typeDeclaration;
-        newTypeDeclaration = _classes.getEntity(cls.classIndex);
-      } else if (oldTypeVariable.typeDeclaration is MemberEntity) {
-        IndexedMember member = oldTypeVariable.typeDeclaration;
-        newTypeDeclaration = _members.getEntity(member.memberIndex);
-      } else {
-        assert(oldTypeVariable.typeDeclaration is Local);
-      }
-      IndexedTypeVariable newTypeVariable = createTypeVariable(
-          newTypeDeclaration, oldTypeVariable.name, oldTypeVariable.index);
-      _typeVariables.register<IndexedTypeVariable, TypeVariableData>(
-          newTypeVariable, oldTypeVariableData.copy());
-      assert(newTypeVariable.typeVariableIndex ==
-          oldTypeVariable.typeVariableIndex);
-    }
-    // TODO(johnniwinther): We should close the environment in the beginning of
-    // this constructor but currently we need the [MemberEntity] to query if the
-    // member is live, thus potentially creating the [MemberEntity] in the
-    // process. Avoid this.
-    _elementMap._envIsClosed = true;
-  }
-
-  @override
-  Entity getClosure(ir.FunctionDeclaration node) {
-    throw new UnsupportedError('JsKernelToElementMap.getClosure');
-  }
-
-  @override
-  void _forEachNestedClosure(
-      MemberEntity member, void f(FunctionEntity closure)) {
-    assert(checkFamily(member));
-    _nestedClosureMap[member]?.forEach(f);
-  }
-
-  InterfaceType getMemberThisType(MemberEntity member) {
-    return _members.getData(member).getMemberThisType(this);
-  }
-
-  ClassTypeVariableAccess getClassTypeVariableAccessForMember(
-      MemberEntity member) {
-    return _members.getData(member).classTypeVariableAccess;
-  }
-
-  @override
-  bool checkFamily(Entity entity) {
-    assert(
-        '$entity'.startsWith(jsElementPrefix),
-        failedAt(entity,
-            "Unexpected entity $entity, expected family $jsElementPrefix."));
-    return true;
-  }
-
-  @override
-  Spannable getSpannable(MemberEntity member, ir.Node node) {
-    return _getSpannable(member, node);
-  }
-
-  Iterable<LibraryEntity> get _libraryList {
-    return _libraryMap.values;
-  }
-
-  @override
-  LibraryEntity _getLibrary(ir.Library node, [LibraryEnv env]) {
-    LibraryEntity library = _libraryMap[node];
-    assert(library != null, "No library entity for $node");
-    return library;
-  }
-
-  @override
-  ClassEntity _getClass(ir.Class node, [ClassEnv env]) {
-    ClassEntity cls = _classMap[node];
-    assert(cls != null, "No class entity for $node");
-    return cls;
-  }
-
-  // TODO(johnniwinther): Reinsert these when [ElementCreatorMixin] is no longer
-  // mixed in.
-  /*@override
-  FieldEntity _getField(ir.Field node) {
-    FieldEntity field = _fieldMap[node];
-    assert(field != null, "No field entity for $node");
-    return field;
-  }*/
-
-  /*@override
-  FunctionEntity _getMethod(ir.Procedure node) {
-    FunctionEntity function = _methodMap[node];
-    assert(function != null, "No function entity for $node");
-    return function;
-  }*/
-
-  /*@override
-  ConstructorEntity _getConstructor(ir.Member node) {
-    ConstructorEntity constructor = _constructorMap[node];
-    assert(constructor != null, "No constructor entity for $node");
-    return constructor;
-  }*/
-
-  FunctionEntity getConstructorBody(ir.Constructor node) {
-    ConstructorEntity constructor = getConstructor(node);
-    return _getConstructorBody(node, constructor);
-  }
-
-  FunctionEntity _getConstructorBody(
-      ir.Constructor node, covariant IndexedConstructor constructor) {
-    ConstructorDataImpl data = _members.getData(constructor);
-    if (data.constructorBody == null) {
-      JConstructorBody constructorBody = createConstructorBody(constructor);
-      _members.register<IndexedFunction, FunctionData>(
-          constructorBody,
-          new ConstructorBodyDataImpl(
-              node,
-              node.function,
-              new SpecialMemberDefinition(
-                  constructorBody, node, MemberKind.constructorBody)));
-      IndexedClass cls = constructor.enclosingClass;
-      ClassEnvImpl classEnv = _classes.getEnv(cls);
-      // TODO(johnniwinther): Avoid this by only including live members in the
-      // js-model.
-      classEnv.addConstructorBody(constructorBody);
-      data.constructorBody = constructorBody;
-    }
-    return data.constructorBody;
-  }
-
-  JConstructorBody createConstructorBody(ConstructorEntity constructor);
-
-  @override
-  MemberDefinition getMemberDefinition(MemberEntity member) {
-    return _getMemberDefinition(member);
-  }
-
-  @override
-  ClassDefinition getClassDefinition(ClassEntity cls) {
-    return _getClassDefinition(cls);
-  }
-
-  @override
-  ConstantValue getFieldConstantValue(covariant IndexedField field) {
-    assert(checkFamily(field));
-    FieldData data = _members.getData(field);
-    return data.getFieldConstantValue(this);
-  }
-
-  bool hasConstantFieldInitializer(covariant IndexedField field) {
-    FieldData data = _members.getData(field);
-    return data.hasConstantFieldInitializer(this);
-  }
-
-  ConstantValue getConstantFieldInitializer(covariant IndexedField field) {
-    FieldData data = _members.getData(field);
-    return data.getConstantFieldInitializer(this);
-  }
-
-  void forEachParameter(covariant IndexedFunction function,
-      void f(DartType type, String name, ConstantValue defaultValue)) {
-    FunctionData data = _members.getData(function);
-    data.forEachParameter(this, f);
-  }
-
-  void _forEachConstructorBody(
-      IndexedClass cls, void f(ConstructorBodyEntity member)) {
-    ClassEnv env = _classes.getEnv(cls);
-    env.forEachConstructorBody(f);
-  }
-
-  void _forEachInjectedClassMember(
-      IndexedClass cls, void f(MemberEntity member)) {
-    _injectedClassMembers[cls]?.forEach(f);
-  }
-
-  JRecordField _constructRecordFieldEntry(
-      InterfaceType memberThisType,
-      ir.VariableDeclaration variable,
-      BoxLocal boxLocal,
-      JClass container,
-      Map<String, MemberEntity> memberMap,
-      KernelToLocalsMap localsMap) {
-    Local local = localsMap.getLocalVariable(variable);
-    JRecordField boxedField =
-        new JRecordField(local.name, boxLocal, container, variable.isConst);
-    _members.register(
-        boxedField,
-        new ClosureFieldData(
-            new ClosureMemberDefinition(
-                boxedField,
-                computeSourceSpanFromTreeNode(variable),
-                MemberKind.closureField,
-                variable),
-            memberThisType));
-    memberMap[boxedField.name] = boxedField;
-
-    return boxedField;
-  }
-
-  /// Make a container controlling access to records, that is, variables that
-  /// are accessed in different scopes. This function creates the container
-  /// and returns a map of locals to the corresponding records created.
-  Map<Local, JRecordField> makeRecordContainer(
-      KernelScopeInfo info, MemberEntity member, KernelToLocalsMap localsMap) {
-    Map<Local, JRecordField> boxedFields = {};
-    if (info.boxedVariables.isNotEmpty) {
-      NodeBox box = info.capturedVariablesAccessor;
-
-      Map<String, MemberEntity> memberMap = <String, MemberEntity>{};
-      JRecord container = new JRecord(member.library, box.name);
-      var containerData = new ClassData(
-          null,
-          new ClosureClassDefinition(container,
-              computeSourceSpanFromTreeNode(getMemberDefinition(member).node)));
-      containerData
-        ..isMixinApplication = false
-        ..thisType = new InterfaceType(container, const <DartType>[])
-        ..supertype = commonElements.objectType
-        ..interfaces = const <InterfaceType>[];
-      _classes.register(container, containerData, new RecordEnv(memberMap));
-
-      var setBuilder = new _KernelOrderedTypeSetBuilder(this, container);
-      containerData.orderedTypeSet = setBuilder.createOrderedTypeSet(
-          containerData.supertype, const Link<InterfaceType>());
-
-      BoxLocal boxLocal = new BoxLocal(box.name);
-      InterfaceType memberThisType = member.enclosingClass != null
-          ? _elementEnvironment.getThisType(member.enclosingClass)
-          : null;
-      for (ir.VariableDeclaration variable in info.boxedVariables) {
-        boxedFields[localsMap.getLocalVariable(variable)] =
-            _constructRecordFieldEntry(memberThisType, variable, boxLocal,
-                container, memberMap, localsMap);
-      }
-    }
-    return boxedFields;
-  }
-
-  bool _isInRecord(
-          Local local, Map<Local, JRecordField> recordFieldsVisibleInScope) =>
-      recordFieldsVisibleInScope.containsKey(local);
-
-  KernelClosureClassInfo constructClosureClass(
-      MemberEntity member,
-      ir.FunctionNode node,
-      JLibrary enclosingLibrary,
-      Map<Local, JRecordField> recordFieldsVisibleInScope,
-      KernelScopeInfo info,
-      KernelToLocalsMap localsMap,
-      InterfaceType supertype,
-      {bool createSignatureMethod}) {
-    InterfaceType memberThisType = member.enclosingClass != null
-        ? _elementEnvironment.getThisType(member.enclosingClass)
-        : null;
-    ClassTypeVariableAccess typeVariableAccess =
-        _members.getData(member).classTypeVariableAccess;
-    if (typeVariableAccess == ClassTypeVariableAccess.instanceField) {
-      // A closure in a field initializer will only be executed in the
-      // constructor and type variables are therefore accessed through
-      // parameters.
-      typeVariableAccess = ClassTypeVariableAccess.parameter;
-    }
-    String name = _computeClosureName(node);
-    SourceSpan location = computeSourceSpanFromTreeNode(node);
-    Map<String, MemberEntity> memberMap = <String, MemberEntity>{};
-
-    JClass classEntity = new JClosureClass(enclosingLibrary, name);
-    // Create a classData and set up the interfaces and subclass
-    // relationships that _ensureSupertypes and _ensureThisAndRawType are doing
-    var closureData =
-        new ClassData(null, new ClosureClassDefinition(classEntity, location));
-    closureData
-      ..isMixinApplication = false
-      ..thisType = closureData.rawType =
-          new InterfaceType(classEntity, const <DartType>[])
-      ..supertype = supertype
-      ..interfaces = const <InterfaceType>[];
-    _classes.register(classEntity, closureData, new ClosureClassEnv(memberMap));
-    var setBuilder = new _KernelOrderedTypeSetBuilder(this, classEntity);
-    closureData.orderedTypeSet = setBuilder.createOrderedTypeSet(
-        closureData.supertype, const Link<InterfaceType>());
-
-    Local closureEntity;
-    if (node.parent is ir.FunctionDeclaration) {
-      ir.FunctionDeclaration parent = node.parent;
-      closureEntity = localsMap.getLocalVariable(parent.variable);
-    } else if (node.parent is ir.FunctionExpression) {
-      closureEntity = new JLocal('', localsMap.currentMember);
-    }
-
-    FunctionEntity callMethod = new JClosureCallMethod(
-        classEntity, _getParameterStructure(node), getAsyncMarker(node));
-    _nestedClosureMap
-        .putIfAbsent(member, () => <FunctionEntity>[])
-        .add(callMethod);
-    // We need create the type variable here - before we try to make local
-    // variables from them (in `JsScopeInfo.from` called through
-    // `KernelClosureClassInfo.fromScopeInfo` below).
-    int index = 0;
-    for (ir.TypeParameter typeParameter in node.typeParameters) {
-      _typeVariableMap[typeParameter] = _typeVariables.register(
-          createTypeVariable(callMethod, typeParameter.name, index),
-          new TypeVariableData(typeParameter));
-      index++;
-    }
-
-    KernelClosureClassInfo closureClassInfo =
-        new KernelClosureClassInfo.fromScopeInfo(
-            classEntity,
-            node,
-            <Local, JRecordField>{},
-            info,
-            localsMap,
-            closureEntity,
-            info.hasThisLocal ? new ThisLocal(localsMap.currentMember) : null,
-            this);
-    _buildClosureClassFields(closureClassInfo, member, memberThisType, info,
-        localsMap, recordFieldsVisibleInScope, memberMap);
-
-    if (createSignatureMethod) {
-      _constructSignatureMethod(closureClassInfo, memberMap, node,
-          memberThisType, location, typeVariableAccess);
-    }
-
-    _members.register<IndexedFunction, FunctionData>(
-        callMethod,
-        new ClosureFunctionData(
-            new ClosureMemberDefinition(
-                callMethod, location, MemberKind.closureCall, node.parent),
-            memberThisType,
-            getFunctionType(node),
-            node,
-            typeVariableAccess));
-    memberMap[callMethod.name] = closureClassInfo.callMethod = callMethod;
-    return closureClassInfo;
-  }
-
-  void _buildClosureClassFields(
-      KernelClosureClassInfo closureClassInfo,
-      MemberEntity member,
-      InterfaceType memberThisType,
-      KernelScopeInfo info,
-      KernelToLocalsMap localsMap,
-      Map<Local, JRecordField> recordFieldsVisibleInScope,
-      Map<String, MemberEntity> memberMap) {
-    // TODO(efortuna): Limit field number usage to when we need to distinguish
-    // between two variables with the same name from different scopes.
-    int fieldNumber = 0;
-
-    // For the captured variables that are boxed, ensure this closure has a
-    // field to reference the box. This puts the boxes first in the closure like
-    // the AST front-end, but otherwise there is no reason to separate this loop
-    // from the one below.
-    // TODO(redemption): Merge this loop and the following.
-
-    for (ir.Node variable in info.freeVariables) {
-      if (variable is ir.VariableDeclaration) {
-        Local capturedLocal = localsMap.getLocalVariable(variable);
-        if (_isInRecord(capturedLocal, recordFieldsVisibleInScope)) {
-          bool constructedField = _constructClosureFieldForRecord(
-              capturedLocal,
-              closureClassInfo,
-              memberThisType,
-              memberMap,
-              variable,
-              recordFieldsVisibleInScope,
-              fieldNumber);
-          if (constructedField) fieldNumber++;
-        }
-      }
-    }
-
-    // Add a field for the captured 'this'.
-    if (info.thisUsedAsFreeVariable) {
-      _constructClosureField(
-          closureClassInfo.thisLocal,
-          closureClassInfo,
-          memberThisType,
-          memberMap,
-          getClassDefinition(member.enclosingClass).node,
-          true,
-          false,
-          fieldNumber);
-      fieldNumber++;
-    }
-
-    for (ir.Node variable in info.freeVariables) {
-      // Make a corresponding field entity in this closure class for the
-      // free variables in the KernelScopeInfo.freeVariable.
-      if (variable is ir.VariableDeclaration) {
-        Local capturedLocal = localsMap.getLocalVariable(variable);
-        if (!_isInRecord(capturedLocal, recordFieldsVisibleInScope)) {
-          _constructClosureField(
-              capturedLocal,
-              closureClassInfo,
-              memberThisType,
-              memberMap,
-              variable,
-              variable.isConst,
-              false, // Closure field is never assigned (only box fields).
-              fieldNumber);
-          fieldNumber++;
-        }
-      } else if (variable is TypeVariableTypeWithContext) {
-        _constructClosureField(
-            localsMap.getLocalTypeVariable(variable.type, this),
-            closureClassInfo,
-            memberThisType,
-            memberMap,
-            variable.type.parameter,
-            true,
-            false,
-            fieldNumber);
-        fieldNumber++;
-      } else {
-        throw new UnsupportedError("Unexpected field node type: $variable");
-      }
-    }
-  }
-
-  /// Records point to one or more local variables declared in another scope
-  /// that are captured in a scope. Access to those variables goes entirely
-  /// through the record container, so we only create a field for the *record*
-  /// holding [capturedLocal] and not the individual local variables accessed
-  /// through the record. Records, by definition, are not mutable (though the
-  /// locals they contain may be). Returns `true` if we constructed a new field
-  /// in the closure class.
-  bool _constructClosureFieldForRecord(
-      Local capturedLocal,
-      KernelClosureClassInfo closureClassInfo,
-      InterfaceType memberThisType,
-      Map<String, MemberEntity> memberMap,
-      ir.TreeNode sourceNode,
-      Map<Local, JRecordField> recordFieldsVisibleInScope,
-      int fieldNumber) {
-    JRecordField recordField = recordFieldsVisibleInScope[capturedLocal];
-
-    // Don't construct a new field if the box that holds this local already has
-    // a field in the closure class.
-    if (closureClassInfo.localToFieldMap.containsKey(recordField.box)) {
-      closureClassInfo.boxedVariables[capturedLocal] = recordField;
-      return false;
-    }
-
-    FieldEntity closureField = new JClosureField(
-        '_box_$fieldNumber', closureClassInfo, true, false, recordField.box);
-
-    _members.register<IndexedField, FieldData>(
-        closureField,
-        new ClosureFieldData(
-            new ClosureMemberDefinition(
-                closureClassInfo.localToFieldMap[capturedLocal],
-                computeSourceSpanFromTreeNode(sourceNode),
-                MemberKind.closureField,
-                sourceNode),
-            memberThisType));
-    memberMap[closureField.name] = closureField;
-    closureClassInfo.localToFieldMap[recordField.box] = closureField;
-    closureClassInfo.boxedVariables[capturedLocal] = recordField;
-    return true;
-  }
-
-  void _constructSignatureMethod(
-      KernelClosureClassInfo closureClassInfo,
-      Map<String, MemberEntity> memberMap,
-      ir.FunctionNode closureSourceNode,
-      InterfaceType memberThisType,
-      SourceSpan location,
-      ClassTypeVariableAccess typeVariableAccess) {
-    FunctionEntity signatureMethod = new JSignatureMethod(
-        closureClassInfo.closureClassEntity.library,
-        closureClassInfo.closureClassEntity,
-        // SignatureMethod takes no arguments.
-        const ParameterStructure(0, 0, const [], 0),
-        AsyncMarker.SYNC);
-    _members.register<IndexedFunction, FunctionData>(
-        signatureMethod,
-        new SignatureFunctionData(
-            new SpecialMemberDefinition(signatureMethod,
-                closureSourceNode.parent, MemberKind.signature),
-            memberThisType,
-            null,
-            closureSourceNode.typeParameters,
-            typeVariableAccess));
-    memberMap[signatureMethod.name] =
-        closureClassInfo.signatureMethod = signatureMethod;
-  }
-
-  _constructClosureField(
-      Local capturedLocal,
-      KernelClosureClassInfo closureClassInfo,
-      InterfaceType memberThisType,
-      Map<String, MemberEntity> memberMap,
-      ir.TreeNode sourceNode,
-      bool isConst,
-      bool isAssignable,
-      int fieldNumber) {
-    FieldEntity closureField = new JClosureField(
-        _getClosureVariableName(capturedLocal.name, fieldNumber),
-        closureClassInfo,
-        isConst,
-        isAssignable,
-        capturedLocal);
-
-    _members.register<IndexedField, FieldData>(
-        closureField,
-        new ClosureFieldData(
-            new ClosureMemberDefinition(
-                closureClassInfo.localToFieldMap[capturedLocal],
-                computeSourceSpanFromTreeNode(sourceNode),
-                MemberKind.closureField,
-                sourceNode),
-            memberThisType));
-    memberMap[closureField.name] = closureField;
-    closureClassInfo.localToFieldMap[capturedLocal] = closureField;
-  }
-
-  // Returns a non-unique name for the given closure element.
-  String _computeClosureName(ir.TreeNode treeNode) {
-    var parts = <String>[];
-    // First anonymous is called 'closure', outer ones called '' to give a
-    // compound name where increasing nesting level corresponds to extra
-    // underscores.
-    var anonymous = 'closure';
-    ir.TreeNode current = treeNode;
-    // TODO(johnniwinther): Simplify computed names.
-    while (current != null) {
-      var node = current;
-      if (node is ir.FunctionExpression) {
-        parts.add(anonymous);
-        anonymous = '';
-      } else if (node is ir.FunctionDeclaration) {
-        String name = node.variable.name;
-        if (name != null && name != "") {
-          parts.add(utils.operatorNameToIdentifier(name));
-        } else {
-          parts.add(anonymous);
-          anonymous = '';
-        }
-      } else if (node is ir.Class) {
-        // TODO(sra): Do something with abstracted mixin type names like '^#U0'.
-        parts.add(node.name);
-        break;
-      } else if (node is ir.Procedure) {
-        if (node.kind == ir.ProcedureKind.Factory) {
-          parts.add(utils.reconstructConstructorName(getMember(node)));
-        } else {
-          parts.add(utils.operatorNameToIdentifier(node.name.name));
-        }
-      } else if (node is ir.Constructor) {
-        parts.add(utils.reconstructConstructorName(getMember(node)));
-        break;
-      }
-      current = current.parent;
-    }
-    return parts.reversed.join('_');
-  }
-
-  /// Generate a unique name for the [id]th closure field, with proposed name
-  /// [name].
-  ///
-  /// The result is used as the name of [ClosureFieldElement]s, and must
-  /// therefore be unique to avoid breaking an invariant in the element model
-  /// (classes cannot declare multiple fields with the same name).
-  ///
-  /// Also, the names should be distinct from real field names to prevent
-  /// clashes with selectors for those fields.
-  ///
-  /// These names are not used in generated code, just as element name.
-  String _getClosureVariableName(String name, int id) {
-    return "_captured_${name}_$id";
-  }
-
-  JGeneratorBody getGeneratorBody(covariant IndexedFunction function) {
-    JGeneratorBody generatorBody = _generatorBodies[function];
-    if (generatorBody == null) {
-      FunctionData functionData = _members.getData(function);
-      ir.TreeNode node = functionData.definition.node;
-      DartType elementType =
-          _elementEnvironment.getFunctionAsyncOrSyncStarElementType(function);
-      generatorBody = createGeneratorBody(function, elementType);
-      _members.register<IndexedFunction, FunctionData>(
-          generatorBody,
-          new GeneratorBodyFunctionData(
-              functionData,
-              new SpecialMemberDefinition(
-                  generatorBody, node, MemberKind.generatorBody)));
-
-      if (function.enclosingClass != null) {
-        // TODO(sra): Integrate this with ClassEnvImpl.addConstructorBody ?
-        (_injectedClassMembers[function.enclosingClass] ??= <MemberEntity>[])
-            .add(generatorBody);
-      }
-    }
-    return generatorBody;
-  }
-
-  JGeneratorBody createGeneratorBody(
-      FunctionEntity function, DartType elementType);
-}
-
 class KernelClassQueries extends ClassQueries {
-  final KernelToElementMapForImpactImpl elementMap;
+  final KernelToElementMapImpl elementMap;
 
   KernelClassQueries(this.elementMap);
 
@@ -2959,12 +2291,12 @@
 
   @override
   Iterable<InterfaceType> getSupertypes(ClassEntity cls) {
-    return elementMap._getOrderedTypeSet(cls).supertypes;
+    return elementMap.getOrderedTypeSet(cls).supertypes;
   }
 
   @override
   ClassEntity getSuperClass(ClassEntity cls) {
-    return elementMap._getSuperType(cls)?.element;
+    return elementMap.getSuperType(cls)?.element;
   }
 
   @override
@@ -2974,11 +2306,11 @@
 
   @override
   int getHierarchyDepth(ClassEntity cls) {
-    return elementMap._getHierarchyDepth(cls);
+    return elementMap.getHierarchyDepth(cls);
   }
 
   @override
   ClassEntity getAppliedMixin(ClassEntity cls) {
-    return elementMap._getAppliedMixin(cls);
+    return elementMap.getAppliedMixin(cls);
   }
 }
diff --git a/pkg/compiler/lib/src/kernel/element_map_mixins.dart b/pkg/compiler/lib/src/kernel/element_map_mixins.dart
deleted file mode 100644
index 5dc1496..0000000
--- a/pkg/compiler/lib/src/kernel/element_map_mixins.dart
+++ /dev/null
@@ -1,956 +0,0 @@
-// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
-// for 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:js_runtime/shared/embedded_names.dart';
-import 'package:kernel/ast.dart' as ir;
-
-import '../common.dart';
-import '../common/names.dart';
-import '../constants/constructors.dart';
-import '../constants/expressions.dart';
-import '../constants/values.dart';
-import '../common_elements.dart';
-import '../elements/entities.dart';
-import '../elements/names.dart';
-import '../elements/operators.dart';
-import '../elements/types.dart';
-import '../js/js.dart' as js;
-import '../js_backend/backend.dart' show JavaScriptBackend;
-import '../js_backend/namer.dart';
-import '../js_emitter/code_emitter_task.dart';
-import '../native/native.dart' as native;
-import '../options.dart';
-import '../universe/call_structure.dart';
-import '../universe/selector.dart';
-import 'element_map.dart';
-import 'kernel_debug.dart';
-
-abstract class KernelToElementMapBaseMixin implements KernelToElementMap {
-  CompilerOptions get options;
-  DiagnosticReporter get reporter;
-  ElementEnvironment get elementEnvironment;
-  LibraryEntity getLibrary(ir.Library node);
-
-  ConstantValue computeConstantValue(
-      Spannable spannable, ConstantExpression constant,
-      {bool requireConstant: true});
-
-  @override
-  Name getName(ir.Name name) {
-    return new Name(
-        name.name, name.isPrivate ? getLibrary(name.library) : null);
-  }
-
-  CallStructure getCallStructure(ir.Arguments arguments) {
-    int argumentCount = arguments.positional.length + arguments.named.length;
-    List<String> namedArguments = arguments.named.map((e) => e.name).toList();
-    return new CallStructure(
-        argumentCount, namedArguments, arguments.types.length);
-  }
-
-  @override
-  Selector getSelector(ir.Expression node) {
-    // TODO(efortuna): This is screaming for a common interface between
-    // PropertyGet and SuperPropertyGet (and same for *Get). Talk to kernel
-    // folks.
-    if (node is ir.PropertyGet) {
-      return getGetterSelector(node.name);
-    }
-    if (node is ir.SuperPropertyGet) {
-      return getGetterSelector(node.name);
-    }
-    if (node is ir.PropertySet) {
-      return getSetterSelector(node.name);
-    }
-    if (node is ir.SuperPropertySet) {
-      return getSetterSelector(node.name);
-    }
-    if (node is ir.InvocationExpression) {
-      return getInvocationSelector(node);
-    }
-    throw failedAt(
-        CURRENT_ELEMENT_SPANNABLE,
-        "Can only get the selector for a property get or an invocation: "
-        "${node}");
-  }
-
-  Selector getInvocationSelector(ir.InvocationExpression invocation) {
-    Name name = getName(invocation.name);
-    SelectorKind kind;
-    if (Selector.isOperatorName(name.text)) {
-      if (name == Names.INDEX_NAME || name == Names.INDEX_SET_NAME) {
-        kind = SelectorKind.INDEX;
-      } else {
-        kind = SelectorKind.OPERATOR;
-      }
-    } else {
-      kind = SelectorKind.CALL;
-    }
-
-    CallStructure callStructure = getCallStructure(invocation.arguments);
-    return new Selector(kind, name, callStructure);
-  }
-
-  Selector getGetterSelector(ir.Name irName) {
-    Name name = new Name(
-        irName.name, irName.isPrivate ? getLibrary(irName.library) : null);
-    return new Selector.getter(name);
-  }
-
-  Selector getSetterSelector(ir.Name irName) {
-    Name name = new Name(
-        irName.name, irName.isPrivate ? getLibrary(irName.library) : null);
-    return new Selector.setter(name);
-  }
-
-  /// Looks up [typeName] for use in the spec-string of a `JS` call.
-  // TODO(johnniwinther): Use this in [native.NativeBehavior] instead of calling
-  // the `ForeignResolver`.
-  native.TypeLookup typeLookup({bool resolveAsRaw: true}) {
-    return resolveAsRaw
-        ? (_cachedTypeLookupRaw ??= _typeLookup(resolveAsRaw: true))
-        : (_cachedTypeLookupFull ??= _typeLookup(resolveAsRaw: false));
-  }
-
-  native.TypeLookup _cachedTypeLookupRaw;
-  native.TypeLookup _cachedTypeLookupFull;
-
-  native.TypeLookup _typeLookup({bool resolveAsRaw: true}) {
-    bool cachedMayLookupInMain;
-    bool mayLookupInMain() {
-      var mainUri = elementEnvironment.mainLibrary.canonicalUri;
-      // Tests permit lookup outside of dart: libraries.
-      return mainUri.path.contains('tests/compiler/dart2js_native') ||
-          mainUri.path.contains('tests/compiler/dart2js_extra');
-    }
-
-    DartType lookup(String typeName, {bool required}) {
-      DartType findInLibrary(LibraryEntity library) {
-        if (library != null) {
-          ClassEntity cls = elementEnvironment.lookupClass(library, typeName);
-          if (cls != null) {
-            // TODO(johnniwinther): Align semantics.
-            return resolveAsRaw
-                ? elementEnvironment.getRawType(cls)
-                : elementEnvironment.getThisType(cls);
-          }
-        }
-        return null;
-      }
-
-      DartType findIn(Uri uri) {
-        return findInLibrary(elementEnvironment.lookupLibrary(uri));
-      }
-
-      // TODO(johnniwinther): Narrow the set of lookups based on the depending
-      // library.
-      // TODO(johnniwinther): Cache more results to avoid redundant lookups?
-      DartType type;
-      if (cachedMayLookupInMain ??= mayLookupInMain()) {
-        type ??= findInLibrary(elementEnvironment.mainLibrary);
-      }
-      type ??= findIn(Uris.dart_core);
-      type ??= findIn(Uris.dart__js_helper);
-      type ??= findIn(Uris.dart__interceptors);
-      type ??= findIn(Uris.dart__native_typed_data);
-      type ??= findIn(Uris.dart_collection);
-      type ??= findIn(Uris.dart_math);
-      type ??= findIn(Uris.dart_html);
-      type ??= findIn(Uris.dart_html_common);
-      type ??= findIn(Uris.dart_svg);
-      type ??= findIn(Uris.dart_web_audio);
-      type ??= findIn(Uris.dart_web_gl);
-      type ??= findIn(Uris.dart_web_sql);
-      type ??= findIn(Uris.dart_indexed_db);
-      type ??= findIn(Uris.dart_typed_data);
-      type ??= findIn(Uris.dart_mirrors);
-      if (type == null && required) {
-        reporter.reportErrorMessage(CURRENT_ELEMENT_SPANNABLE,
-            MessageKind.GENERIC, {'text': "Type '$typeName' not found."});
-      }
-      return type;
-    }
-
-    return lookup;
-  }
-
-  String _getStringArgument(ir.StaticInvocation node, int index) {
-    return node.arguments.positional[index].accept(new Stringifier());
-  }
-
-  /// Computes the [native.NativeBehavior] for a call to the [JS] function.
-  // TODO(johnniwinther): Cache this for later use.
-  native.NativeBehavior getNativeBehaviorForJsCall(ir.StaticInvocation node) {
-    if (node.arguments.positional.length < 2 ||
-        node.arguments.named.isNotEmpty) {
-      reporter.reportErrorMessage(
-          CURRENT_ELEMENT_SPANNABLE, MessageKind.WRONG_ARGUMENT_FOR_JS);
-      return new native.NativeBehavior();
-    }
-    String specString = _getStringArgument(node, 0);
-    if (specString == null) {
-      reporter.reportErrorMessage(
-          CURRENT_ELEMENT_SPANNABLE, MessageKind.WRONG_ARGUMENT_FOR_JS_FIRST);
-      return new native.NativeBehavior();
-    }
-
-    String codeString = _getStringArgument(node, 1);
-    if (codeString == null) {
-      reporter.reportErrorMessage(
-          CURRENT_ELEMENT_SPANNABLE, MessageKind.WRONG_ARGUMENT_FOR_JS_SECOND);
-      return new native.NativeBehavior();
-    }
-
-    return native.NativeBehavior.ofJsCall(
-        specString,
-        codeString,
-        typeLookup(resolveAsRaw: true),
-        CURRENT_ELEMENT_SPANNABLE,
-        reporter,
-        commonElements);
-  }
-
-  /// Computes the [native.NativeBehavior] for a call to the [JS_BUILTIN]
-  /// function.
-  // TODO(johnniwinther): Cache this for later use.
-  native.NativeBehavior getNativeBehaviorForJsBuiltinCall(
-      ir.StaticInvocation node) {
-    if (node.arguments.positional.length < 1) {
-      reporter.internalError(
-          CURRENT_ELEMENT_SPANNABLE, "JS builtin expression has no type.");
-      return new native.NativeBehavior();
-    }
-    if (node.arguments.positional.length < 2) {
-      reporter.internalError(
-          CURRENT_ELEMENT_SPANNABLE, "JS builtin is missing name.");
-      return new native.NativeBehavior();
-    }
-    String specString = _getStringArgument(node, 0);
-    if (specString == null) {
-      reporter.internalError(
-          CURRENT_ELEMENT_SPANNABLE, "Unexpected first argument.");
-      return new native.NativeBehavior();
-    }
-    return native.NativeBehavior.ofJsBuiltinCall(
-        specString,
-        typeLookup(resolveAsRaw: true),
-        CURRENT_ELEMENT_SPANNABLE,
-        reporter,
-        commonElements);
-  }
-
-  /// Computes the [native.NativeBehavior] for a call to the
-  /// [JS_EMBEDDED_GLOBAL] function.
-  // TODO(johnniwinther): Cache this for later use.
-  native.NativeBehavior getNativeBehaviorForJsEmbeddedGlobalCall(
-      ir.StaticInvocation node) {
-    if (node.arguments.positional.length < 1) {
-      reporter.internalError(CURRENT_ELEMENT_SPANNABLE,
-          "JS embedded global expression has no type.");
-      return new native.NativeBehavior();
-    }
-    if (node.arguments.positional.length < 2) {
-      reporter.internalError(
-          CURRENT_ELEMENT_SPANNABLE, "JS embedded global is missing name.");
-      return new native.NativeBehavior();
-    }
-    if (node.arguments.positional.length > 2 ||
-        node.arguments.named.isNotEmpty) {
-      reporter.internalError(CURRENT_ELEMENT_SPANNABLE,
-          "JS embedded global has more than 2 arguments.");
-      return new native.NativeBehavior();
-    }
-    String specString = _getStringArgument(node, 0);
-    if (specString == null) {
-      reporter.internalError(
-          CURRENT_ELEMENT_SPANNABLE, "Unexpected first argument.");
-      return new native.NativeBehavior();
-    }
-    return native.NativeBehavior.ofJsEmbeddedGlobalCall(
-        specString,
-        typeLookup(resolveAsRaw: true),
-        CURRENT_ELEMENT_SPANNABLE,
-        reporter,
-        commonElements);
-  }
-
-  js.Name getNameForJsGetName(ConstantValue constant, Namer namer) {
-    int index = _extractEnumIndexFromConstantValue(
-        constant, commonElements.jsGetNameEnum);
-    if (index == null) return null;
-    return namer.getNameForJsGetName(
-        CURRENT_ELEMENT_SPANNABLE, JsGetName.values[index]);
-  }
-
-  int _extractEnumIndexFromConstantValue(
-      ConstantValue constant, ClassEntity classElement) {
-    if (constant is ConstructedConstantValue) {
-      if (constant.type.element == classElement) {
-        assert(constant.fields.length == 1 || constant.fields.length == 2);
-        ConstantValue indexConstant = constant.fields.values.first;
-        if (indexConstant is IntConstantValue) {
-          return indexConstant.intValue.toInt();
-        }
-      }
-    }
-    return null;
-  }
-
-  ConstantValue getConstantValue(ir.Expression node,
-      {bool requireConstant: true, bool implicitNull: false}) {
-    ConstantExpression constant;
-    if (node == null) {
-      if (!implicitNull) {
-        throw failedAt(
-            CURRENT_ELEMENT_SPANNABLE, 'No expression for constant.');
-      }
-      constant = new NullConstantExpression();
-    } else {
-      constant =
-          new Constantifier(this, requireConstant: requireConstant).visit(node);
-    }
-    if (constant == null) {
-      if (requireConstant) {
-        throw new UnsupportedError(
-            'No constant for ${DebugPrinter.prettyPrint(node)}');
-      }
-      return null;
-    }
-    ConstantValue value = computeConstantValue(
-        computeSourceSpanFromTreeNode(node), constant,
-        requireConstant: requireConstant);
-    if (!value.isConstant && !requireConstant) {
-      return null;
-    }
-    return value;
-  }
-
-  /// Converts [annotations] into a list of [ConstantValue]s.
-  List<ConstantValue> getMetadata(List<ir.Expression> annotations) {
-    if (annotations.isEmpty) return const <ConstantValue>[];
-    List<ConstantValue> metadata = <ConstantValue>[];
-    annotations.forEach((ir.Expression node) {
-      metadata.add(getConstantValue(node));
-    });
-    return metadata;
-  }
-
-  FunctionEntity getSuperNoSuchMethod(ClassEntity cls) {
-    while (cls != null) {
-      cls = elementEnvironment.getSuperClass(cls);
-      MemberEntity member = elementEnvironment.lookupLocalClassMember(
-          cls, Identifiers.noSuchMethod_);
-      if (member != null && !member.isAbstract) {
-        if (member.isFunction) {
-          FunctionEntity function = member;
-          if (function.parameterStructure.positionalParameters >= 1) {
-            return function;
-          }
-        }
-        // If [member] is not a valid `noSuchMethod` the target is
-        // `Object.superNoSuchMethod`.
-        break;
-      }
-    }
-    FunctionEntity function = elementEnvironment.lookupLocalClassMember(
-        commonElements.objectClass, Identifiers.noSuchMethod_);
-    assert(function != null,
-        failedAt(cls, "No super noSuchMethod found for class $cls."));
-    return function;
-  }
-}
-
-abstract class KernelToElementMapForImpactMixin
-    implements KernelToElementMapForImpact, KernelToElementMapBaseMixin {
-  DiagnosticReporter get reporter;
-  native.BehaviorBuilder get nativeBehaviorBuilder;
-
-  /// Returns `true` is [node] has a `@Native(...)` annotation.
-  // TODO(johnniwinther): Cache this for later use.
-  bool isNativeClass(ir.Class node) {
-    for (ir.Expression annotation in node.annotations) {
-      if (annotation is ir.ConstructorInvocation) {
-        FunctionEntity target = getConstructor(annotation.target);
-        if (target.enclosingClass == commonElements.nativeAnnotationClass) {
-          return true;
-        }
-      }
-    }
-    return false;
-  }
-
-  /// Compute the kind of foreign helper function called by [node], if any.
-  ForeignKind getForeignKind(ir.StaticInvocation node) {
-    if (commonElements.isForeignHelper(getMember(node.target))) {
-      switch (node.target.name.name) {
-        case JavaScriptBackend.JS:
-          return ForeignKind.JS;
-        case JavaScriptBackend.JS_BUILTIN:
-          return ForeignKind.JS_BUILTIN;
-        case JavaScriptBackend.JS_EMBEDDED_GLOBAL:
-          return ForeignKind.JS_EMBEDDED_GLOBAL;
-        case JavaScriptBackend.JS_INTERCEPTOR_CONSTANT:
-          return ForeignKind.JS_INTERCEPTOR_CONSTANT;
-      }
-    }
-    return ForeignKind.NONE;
-  }
-
-  /// Computes the [InterfaceType] referenced by a call to the
-  /// [JS_INTERCEPTOR_CONSTANT] function, if any.
-  InterfaceType getInterfaceTypeForJsInterceptorCall(ir.StaticInvocation node) {
-    if (node.arguments.positional.length != 1 ||
-        node.arguments.named.isNotEmpty) {
-      reporter.reportErrorMessage(CURRENT_ELEMENT_SPANNABLE,
-          MessageKind.WRONG_ARGUMENT_FOR_JS_INTERCEPTOR_CONSTANT);
-    }
-    ir.Node argument = node.arguments.positional.first;
-    if (argument is ir.TypeLiteral && argument.type is ir.InterfaceType) {
-      return getInterfaceType(argument.type);
-    }
-    return null;
-  }
-
-  /// Computes the native behavior for reading the native [field].
-  // TODO(johnniwinther): Cache this for later use.
-  native.NativeBehavior getNativeBehaviorForFieldLoad(ir.Field field,
-      {bool isJsInterop}) {
-    DartType type = getDartType(field.type);
-    List<ConstantValue> metadata = getMetadata(field.annotations);
-    return nativeBehaviorBuilder.buildFieldLoadBehavior(
-        type, metadata, typeLookup(resolveAsRaw: false),
-        isJsInterop: isJsInterop);
-  }
-
-  /// Computes the native behavior for writing to the native [field].
-  // TODO(johnniwinther): Cache this for later use.
-  native.NativeBehavior getNativeBehaviorForFieldStore(ir.Field field) {
-    DartType type = getDartType(field.type);
-    return nativeBehaviorBuilder.buildFieldStoreBehavior(type);
-  }
-
-  /// Computes the native behavior for calling [member].
-  // TODO(johnniwinther): Cache this for later use.
-  native.NativeBehavior getNativeBehaviorForMethod(ir.Member member,
-      {bool isJsInterop}) {
-    DartType type;
-    if (member is ir.Procedure) {
-      type = getFunctionType(member.function);
-    } else if (member is ir.Constructor) {
-      type = getFunctionType(member.function);
-    } else {
-      failedAt(CURRENT_ELEMENT_SPANNABLE, "Unexpected method node $member.");
-    }
-    List<ConstantValue> metadata = getMetadata(member.annotations);
-    return nativeBehaviorBuilder.buildMethodBehavior(
-        type, metadata, typeLookup(resolveAsRaw: false),
-        isJsInterop: isJsInterop);
-  }
-}
-
-abstract class KernelToElementMapForBuildingMixin
-    implements KernelToElementMapForBuilding, KernelToElementMapBaseMixin {
-  js.Template getJsBuiltinTemplate(
-      ConstantValue constant, CodeEmitterTask emitter) {
-    int index = _extractEnumIndexFromConstantValue(
-        constant, commonElements.jsBuiltinEnum);
-    if (index == null) return null;
-    return emitter.builtinTemplateFor(JsBuiltin.values[index]);
-  }
-}
-
-/// Visitor that converts string literals and concatenations of string literals
-/// into the string value.
-class Stringifier extends ir.ExpressionVisitor<String> {
-  @override
-  String visitStringLiteral(ir.StringLiteral node) => node.value;
-
-  @override
-  String visitStringConcatenation(ir.StringConcatenation node) {
-    StringBuffer sb = new StringBuffer();
-    for (ir.Expression expression in node.expressions) {
-      String value = expression.accept(this);
-      if (value == null) return null;
-      sb.write(value);
-    }
-    return sb.toString();
-  }
-}
-
-/// Visitor that converts a kernel constant expression into a
-/// [ConstantExpression].
-class Constantifier extends ir.ExpressionVisitor<ConstantExpression> {
-  final bool requireConstant;
-  final KernelToElementMapBaseMixin elementMap;
-  ir.TreeNode failNode;
-  final Map<ir.VariableDeclaration, ConstantExpression> _initializerLocals =
-      <ir.VariableDeclaration, ConstantExpression>{};
-
-  Constantifier(this.elementMap, {this.requireConstant: true});
-
-  CommonElements get _commonElements => elementMap.commonElements;
-
-  ConstantExpression visit(ir.Expression node) {
-    ConstantExpression constant = node.accept(this);
-    if (constant == null && requireConstant) {
-      // TODO(johnniwinther): Support contextual error messages.
-      elementMap.reporter.reportErrorMessage(
-          computeSourceSpanFromTreeNode(failNode ?? node),
-          MessageKind.NOT_A_COMPILE_TIME_CONSTANT);
-      return new ErroneousConstantExpression();
-    }
-    return constant;
-  }
-
-  ConstantExpression defaultExpression(ir.Expression node) {
-    if (requireConstant) {
-      failNode ??= node;
-    }
-    return null;
-  }
-
-  List<ConstantExpression> _computeList(List<ir.Expression> expressions) {
-    List<ConstantExpression> list = <ConstantExpression>[];
-    for (ir.Expression expression in expressions) {
-      ConstantExpression constant = visit(expression);
-      if (constant == null) return null;
-      list.add(constant);
-    }
-    return list;
-  }
-
-  List<ConstantExpression> _computeArguments(ir.Arguments node) {
-    List<ConstantExpression> arguments = <ConstantExpression>[];
-    for (ir.Expression argument in node.positional) {
-      ConstantExpression constant = visit(argument);
-      if (constant == null) return null;
-      arguments.add(constant);
-    }
-    for (ir.NamedExpression argument in node.named) {
-      ConstantExpression constant = visit(argument.value);
-      if (constant == null) return null;
-      arguments.add(constant);
-    }
-    return arguments;
-  }
-
-  ConstructedConstantExpression _computeConstructorInvocation(
-      ir.Constructor target, ir.Arguments arguments) {
-    List<ConstantExpression> expressions = _computeArguments(arguments);
-    if (expressions == null) return null;
-    return new ConstructedConstantExpression(
-        elementMap.createInterfaceType(target.enclosingClass, arguments.types),
-        elementMap.getConstructor(target),
-        elementMap.getCallStructure(arguments),
-        expressions);
-  }
-
-  @override
-  ConstantExpression visitConstructorInvocation(ir.ConstructorInvocation node) {
-    if (!node.isConst) return null;
-    return _computeConstructorInvocation(node.target, node.arguments);
-  }
-
-  @override
-  ConstantExpression visitVariableGet(ir.VariableGet node) {
-    ConstantExpression constant = _initializerLocals[node.variable];
-    if (constant != null) {
-      return constant;
-    }
-    if (node.variable.parent is ir.FunctionNode) {
-      ir.FunctionNode function = node.variable.parent;
-      int index = function.positionalParameters.indexOf(node.variable);
-      if (index != -1) {
-        return new PositionalArgumentReference(index);
-      } else {
-        assert(function.namedParameters.contains(node.variable));
-        return new NamedArgumentReference(node.variable.name);
-      }
-    } else if (node.variable.isConst) {
-      return visit(node.variable.initializer);
-    }
-    return defaultExpression(node);
-  }
-
-  @override
-  ConstantExpression visitStaticGet(ir.StaticGet node) {
-    ir.Member target = node.target;
-    if (target is ir.Field && target.isConst) {
-      return new FieldConstantExpression(elementMap.getField(node.target));
-    } else if (target is ir.Procedure &&
-        target.kind == ir.ProcedureKind.Method) {
-      FunctionEntity function = elementMap.getMethod(node.target);
-      DartType type = elementMap.getFunctionType(node.target.function);
-      return new FunctionConstantExpression(function, type);
-    }
-    return defaultExpression(node);
-  }
-
-  @override
-  ConstantExpression visitNullLiteral(ir.NullLiteral node) {
-    return new NullConstantExpression();
-  }
-
-  @override
-  ConstantExpression visitBoolLiteral(ir.BoolLiteral node) {
-    return new BoolConstantExpression(node.value);
-  }
-
-  @override
-  ConstantExpression visitIntLiteral(ir.IntLiteral node) {
-    return new IntConstantExpression(
-        new BigInt.from(node.value).toUnsigned(64));
-  }
-
-  @override
-  ConstantExpression visitDoubleLiteral(ir.DoubleLiteral node) {
-    return new DoubleConstantExpression(node.value);
-  }
-
-  @override
-  ConstantExpression visitStringLiteral(ir.StringLiteral node) {
-    return new StringConstantExpression(node.value);
-  }
-
-  @override
-  ConstantExpression visitSymbolLiteral(ir.SymbolLiteral node) {
-    return new SymbolConstantExpression(node.value);
-  }
-
-  @override
-  ConstantExpression visitStringConcatenation(ir.StringConcatenation node) {
-    List<ConstantExpression> expressions = _computeList(node.expressions);
-    if (expressions == null) return null;
-    return new ConcatenateConstantExpression(expressions);
-  }
-
-  @override
-  ConstantExpression visitMapLiteral(ir.MapLiteral node) {
-    if (!node.isConst) {
-      return defaultExpression(node);
-    }
-    DartType keyType = elementMap.getDartType(node.keyType);
-    DartType valueType = elementMap.getDartType(node.valueType);
-    List<ConstantExpression> keys = <ConstantExpression>[];
-    List<ConstantExpression> values = <ConstantExpression>[];
-    for (ir.MapEntry entry in node.entries) {
-      ConstantExpression key = visit(entry.key);
-      if (key == null) return null;
-      keys.add(key);
-      ConstantExpression value = visit(entry.value);
-      if (value == null) return null;
-      values.add(value);
-    }
-    return new MapConstantExpression(
-        _commonElements.mapType(keyType, valueType), keys, values);
-  }
-
-  @override
-  ConstantExpression visitListLiteral(ir.ListLiteral node) {
-    if (!node.isConst) {
-      return defaultExpression(node);
-    }
-    DartType elementType = elementMap.getDartType(node.typeArgument);
-    List<ConstantExpression> values = <ConstantExpression>[];
-    for (ir.Expression expression in node.expressions) {
-      ConstantExpression value = visit(expression);
-      if (value == null) return null;
-      values.add(value);
-    }
-    return new ListConstantExpression(
-        _commonElements.listType(elementType), values);
-  }
-
-  @override
-  ConstantExpression visitTypeLiteral(ir.TypeLiteral node) {
-    String name;
-    DartType type = elementMap.getDartType(node.type);
-    if (type.isDynamic) {
-      name = 'dynamic';
-    } else if (type is InterfaceType) {
-      name = type.element.name;
-    } else if (type.isTypedef) {
-      // TODO(johnniwinther): Compute a name for the type literal? It is only
-      // used in error messages in the old SSA builder.
-      name = '?';
-    } else if (node.type is ir.FunctionType) {
-      ir.FunctionType functionType = node.type;
-      assert(functionType.typedef != null);
-      type = elementMap.getTypedefType(functionType.typedef);
-      name = functionType.typedef.name;
-    } else {
-      return defaultExpression(node);
-    }
-    return new TypeConstantExpression(type, name);
-  }
-
-  @override
-  ConstantExpression visitAsExpression(ir.AsExpression node) {
-    ConstantExpression expression = visit(node.operand);
-    if (expression == null) return null;
-    DartType type = elementMap.getDartType(node.type);
-    return new AsConstantExpression(expression, type);
-  }
-
-  @override
-  ConstantExpression visitInstantiation(ir.Instantiation node) {
-    List<DartType> typeArguments =
-        node.typeArguments.map(elementMap.getDartType).toList();
-    for (DartType typeArgument in typeArguments) {
-      if (typeArgument.containsTypeVariables) {
-        return null;
-      }
-    }
-    ConstantExpression expression = visit(node.expression);
-    if (expression == null) return null;
-    return new InstantiationConstantExpression(typeArguments, expression);
-  }
-
-  @override
-  ConstantExpression visitNot(ir.Not node) {
-    ConstantExpression expression = visit(node.operand);
-    if (expression == null) return null;
-    return new UnaryConstantExpression(UnaryOperator.NOT, expression);
-  }
-
-  @override
-  ConstantExpression visitConditionalExpression(ir.ConditionalExpression node) {
-    ConstantExpression condition = visit(node.condition);
-    if (condition == null) return null;
-    ConstantExpression trueExp = visit(node.then);
-    if (trueExp == null) return null;
-    ConstantExpression falseExp = visit(node.otherwise);
-    if (falseExp == null) return null;
-    return new ConditionalConstantExpression(condition, trueExp, falseExp);
-  }
-
-  @override
-  ConstantExpression visitPropertyGet(ir.PropertyGet node) {
-    if (node.name.name != 'length') {
-      failNode ??= node;
-      return null;
-    }
-    ConstantExpression receiver = visit(node.receiver);
-    if (receiver == null) return null;
-    return new StringLengthConstantExpression(receiver);
-  }
-
-  @override
-  ConstantExpression visitMethodInvocation(ir.MethodInvocation node) {
-    // Method invocations are generally not constant expressions but unary
-    // and binary expressions are encoded as method invocations in kernel.
-    if (node.arguments.named.isNotEmpty) {
-      return defaultExpression(node);
-    }
-    if (node.arguments.positional.length == 0) {
-      UnaryOperator operator;
-      if (node.name.name == UnaryOperator.NEGATE.selectorName) {
-        operator = UnaryOperator.NEGATE;
-      } else {
-        operator = UnaryOperator.parse(node.name.name);
-      }
-      if (operator != null) {
-        ConstantExpression expression = visit(node.receiver);
-        if (expression == null) return null;
-        return new UnaryConstantExpression(operator, expression);
-      }
-    }
-    if (node.arguments.positional.length == 1) {
-      BinaryOperator operator = BinaryOperator.parse(node.name.name);
-      if (operator != null) {
-        ConstantExpression left = visit(node.receiver);
-        if (left == null) return null;
-        ConstantExpression right = visit(node.arguments.positional.single);
-        if (right == null) return null;
-        return new BinaryConstantExpression(left, operator, right);
-      }
-    }
-    return defaultExpression(node);
-  }
-
-  @override
-  ConstantExpression visitStaticInvocation(ir.StaticInvocation node) {
-    MemberEntity member = elementMap.getMember(node.target);
-    if (member == _commonElements.identicalFunction) {
-      if (node.arguments.positional.length == 2 &&
-          node.arguments.named.isEmpty) {
-        ConstantExpression left = visit(node.arguments.positional[0]);
-        if (left == null) return null;
-        ConstantExpression right = visit(node.arguments.positional[1]);
-        if (right == null) return null;
-        return new IdenticalConstantExpression(left, right);
-      }
-    } else if (member.name == 'fromEnvironment' &&
-        node.arguments.positional.length == 1) {
-      ConstantExpression name = visit(node.arguments.positional.single);
-      if (name == null) return null;
-      ConstantExpression defaultValue;
-      if (node.arguments.named.length == 1) {
-        if (node.arguments.named.single.name != 'defaultValue') {
-          return defaultExpression(node);
-        }
-        defaultValue = visit(node.arguments.named.single.value);
-        if (defaultValue == null) return null;
-      }
-      if (member.enclosingClass == _commonElements.boolClass) {
-        return new BoolFromEnvironmentConstantExpression(name, defaultValue);
-      } else if (member.enclosingClass == _commonElements.intClass) {
-        return new IntFromEnvironmentConstantExpression(name, defaultValue);
-      } else if (member.enclosingClass == _commonElements.stringClass) {
-        return new StringFromEnvironmentConstantExpression(name, defaultValue);
-      }
-    }
-    return defaultExpression(node);
-  }
-
-  @override
-  ConstantExpression visitLogicalExpression(ir.LogicalExpression node) {
-    BinaryOperator operator = BinaryOperator.parse(node.operator);
-    if (operator != null &&
-        BinaryConstantExpression.potentialOperator(operator)) {
-      ConstantExpression left = visit(node.left);
-      if (left == null) return null;
-      ConstantExpression right = visit(node.right);
-      if (right == null) return null;
-      return new BinaryConstantExpression(left, operator, right);
-    }
-    return defaultExpression(node);
-  }
-
-  @override
-  ConstantExpression visitLet(ir.Let node) {
-    ir.Expression body = node.body;
-    if (body is ir.ConditionalExpression) {
-      ir.Expression condition = body.condition;
-      if (condition is ir.MethodInvocation) {
-        ir.Expression receiver = condition.receiver;
-        ir.Expression otherwise = body.otherwise;
-        if (condition.name.name == BinaryOperator.EQ.name &&
-            receiver is ir.VariableGet &&
-            condition.arguments.positional.single is ir.NullLiteral &&
-            otherwise is ir.VariableGet) {
-          if (receiver.variable == node.variable &&
-              otherwise.variable == node.variable) {
-            // We have <left> ?? <right> encoded as:
-            //    let #1 = <left> in #1 == null ? <right> : #1
-            ConstantExpression left = visit(node.variable.initializer);
-            if (left == null) return null;
-            ConstantExpression right = visit(body.then);
-            if (right == null) return null;
-            // TODO(johnniwinther): Remove [IF_NULL] binary constant expression
-            // when the resolver is removed; then we no longer need the
-            // expressions to be structurally equivalence for equivalence
-            // testing.
-            return new BinaryConstantExpression(
-                left, BinaryOperator.IF_NULL, right);
-          }
-        }
-      }
-    }
-    return defaultExpression(node);
-  }
-
-  /// Compute the [ConstantConstructor] corresponding to the const constructor
-  /// [node].
-  ConstantConstructor computeConstantConstructor(ir.Constructor node) {
-    assert(node.isConst);
-    ir.Class cls = node.enclosingClass;
-    InterfaceType type =
-        elementMap.elementEnvironment.getThisType(elementMap.getClass(cls));
-
-    Map<dynamic, ConstantExpression> defaultValues =
-        <dynamic, ConstantExpression>{};
-    int parameterIndex = 0;
-    for (ir.VariableDeclaration parameter
-        in node.function.positionalParameters) {
-      if (parameterIndex >= node.function.requiredParameterCount) {
-        ConstantExpression defaultValue;
-        if (parameter.initializer != null) {
-          defaultValue = visit(parameter.initializer);
-        } else {
-          defaultValue = new NullConstantExpression();
-        }
-        if (defaultValue == null) return null;
-        defaultValues[parameterIndex] = defaultValue;
-      }
-      parameterIndex++;
-    }
-    for (ir.VariableDeclaration parameter in node.function.namedParameters) {
-      ConstantExpression defaultValue = visit(parameter.initializer);
-      if (defaultValue == null) return null;
-      defaultValues[parameter.name] = defaultValue;
-    }
-
-    bool isRedirecting = node.initializers.length == 1 &&
-        node.initializers.single is ir.RedirectingInitializer;
-
-    Map<FieldEntity, ConstantExpression> fieldMap =
-        <FieldEntity, ConstantExpression>{};
-
-    void registerField(ir.Field field, ConstantExpression constant) {
-      fieldMap[elementMap.getField(field)] = constant;
-    }
-
-    if (!isRedirecting) {
-      for (ir.Field field in cls.fields) {
-        if (field.isStatic) continue;
-        if (field.initializer != null) {
-          registerField(field, visit(field.initializer));
-        }
-      }
-    }
-
-    ConstructedConstantExpression superConstructorInvocation;
-    List<AssertConstantExpression> assertions = <AssertConstantExpression>[];
-    for (ir.Initializer initializer in node.initializers) {
-      if (initializer is ir.FieldInitializer) {
-        registerField(initializer.field, visit(initializer.value));
-      } else if (initializer is ir.SuperInitializer) {
-        superConstructorInvocation = _computeConstructorInvocation(
-            initializer.target, initializer.arguments);
-      } else if (initializer is ir.RedirectingInitializer) {
-        superConstructorInvocation = _computeConstructorInvocation(
-            initializer.target, initializer.arguments);
-      } else if (initializer is ir.AssertInitializer) {
-        ConstantExpression condition = visit(initializer.statement.condition);
-        ConstantExpression message = initializer.statement.message != null
-            ? visit(initializer.statement.message)
-            : null;
-        assertions.add(new AssertConstantExpression(condition, message));
-      } else if (initializer is ir.InvalidInitializer) {
-        String constructorName = '${cls.name}.${node.name}';
-        elementMap.reporter.reportErrorMessage(
-            computeSourceSpanFromTreeNode(initializer),
-            MessageKind.INVALID_CONSTANT_CONSTRUCTOR,
-            {'constructorName': constructorName});
-        return new ErroneousConstantConstructor();
-      } else if (initializer is ir.LocalInitializer) {
-        ir.VariableDeclaration variable = initializer.variable;
-        ConstantExpression constant = visit(variable.initializer);
-        if (constant != null) {
-          _initializerLocals[variable] = constant;
-        } else {
-          // TODO(johnniwinther): Use [_ErroneousInitializerVisitor] in
-          // `ssa/builder_kernel.dart` to identify erroneous initializer.
-          String constructorName = '${cls.name}.${node.name}';
-          elementMap.reporter.reportErrorMessage(
-              computeSourceSpanFromTreeNode(initializer),
-              MessageKind.INVALID_CONSTANT_CONSTRUCTOR,
-              {'constructorName': constructorName});
-          return new ErroneousConstantConstructor();
-        }
-      } else {
-        throw new UnsupportedError(
-            'Unexpected initializer $initializer (${initializer.runtimeType})');
-      }
-    }
-    if (isRedirecting) {
-      return new RedirectingGenerativeConstantConstructor(
-          defaultValues, superConstructorInvocation);
-    } else {
-      return new GenerativeConstantConstructor(type, defaultValues, fieldMap,
-          assertions, superConstructorInvocation);
-    }
-  }
-}
diff --git a/pkg/compiler/lib/src/kernel/env.dart b/pkg/compiler/lib/src/kernel/env.dart
index 82dfbb8..3e895e4 100644
--- a/pkg/compiler/lib/src/kernel/env.dart
+++ b/pkg/compiler/lib/src/kernel/env.dart
@@ -16,11 +16,14 @@
 import '../constants/values.dart';
 import '../elements/entities.dart';
 import '../elements/types.dart';
+import '../ir/element_map.dart';
+import '../ir/visitors.dart';
+import '../ir/util.dart';
+import '../js_model/element_map.dart';
 import '../ordered_typeset.dart';
 import '../ssa/type_builder.dart';
 import 'element_map.dart';
 import 'element_map_impl.dart';
-import 'element_map_mixins.dart';
 import 'kelements.dart' show KImport;
 
 /// Environment for fast lookup of component libraries.
@@ -161,7 +164,7 @@
   /// Currently all classes are copied.
   // TODO(johnniwinther): Filter unused classes.
   LibraryEnv copyLive(
-      KernelToElementMap elementMap, Iterable<MemberEntity> liveMembers) {
+      IrToElementMap elementMap, Iterable<MemberEntity> liveMembers) {
     Map<String, ClassEnv> classMap;
     Map<String, ir.Member> memberMap;
     Map<String, ir.Member> setterMap;
@@ -240,26 +243,28 @@
   /// Whether the class is an unnamed mixin application.
   bool get isUnnamedMixinApplication;
 
+  /// Whether the class is a mixin application that mixes in methods with super
+  /// calls.
+  bool get isSuperMixinApplication;
+
   /// Ensures that all members have been computed for [cls].
   void ensureMembers(KernelToElementMapBase elementMap);
 
   /// Return the [MemberEntity] for the member [name] in the class. If [setter]
   /// is `true`, the setter or assignable field corresponding to [name] is
   /// returned.
-  MemberEntity lookupMember(KernelToElementMap elementMap, String name,
+  MemberEntity lookupMember(IrToElementMap elementMap, String name,
       {bool setter: false});
 
   /// Calls [f] for each member of the class.
-  void forEachMember(
-      KernelToElementMap elementMap, void f(MemberEntity member));
+  void forEachMember(IrToElementMap elementMap, void f(MemberEntity member));
 
   /// Return the [ConstructorEntity] for the constructor [name] in the class.
-  ConstructorEntity lookupConstructor(
-      KernelToElementMap elementMap, String name);
+  ConstructorEntity lookupConstructor(IrToElementMap elementMap, String name);
 
   /// Calls [f] for each constructor of the class.
   void forEachConstructor(
-      KernelToElementMap elementMap, void f(ConstructorEntity constructor));
+      IrToElementMap elementMap, void f(ConstructorEntity constructor));
 
   /// Calls [f] for each constructor body for the live constructors in the
   /// class.
@@ -267,7 +272,7 @@
 
   /// Creates a new [ClassEnv] containing only the members in [liveMembers].
   ClassEnv copyLive(
-      KernelToElementMap elementMap, Iterable<MemberEntity> liveMembers);
+      IrToElementMap elementMap, Iterable<MemberEntity> liveMembers);
 }
 
 int orderByFileOffset(ir.TreeNode a, ir.TreeNode b) {
@@ -288,6 +293,7 @@
   Map<String, ir.Member> _memberMap;
   Map<String, ir.Member> _setterMap;
   List<ir.Member> _members; // in declaration order.
+  bool _isSuperMixinApplication;
 
   /// Constructor bodies created for this class.
   List<ConstructorBodyEntity> _constructorBodyList;
@@ -295,10 +301,15 @@
   ClassEnvImpl(this.cls);
 
   ClassEnvImpl.internal(this.cls, this._constructorMap, this._memberMap,
-      this._setterMap, this._members);
+      this._setterMap, this._members, this._isSuperMixinApplication);
 
   bool get isUnnamedMixinApplication => cls.isAnonymousMixin;
 
+  bool get isSuperMixinApplication {
+    assert(_isSuperMixinApplication != null);
+    return _isSuperMixinApplication;
+  }
+
   /// Copied from 'package:kernel/transformations/mixin_full_resolution.dart'.
   ir.Constructor _buildForwardingConstructor(
       CloneVisitor cloner, ir.Constructor superclassConstructor) {
@@ -356,69 +367,65 @@
     _setterMap = <String, ir.Member>{};
     _constructorMap = <String, ir.Member>{};
     var members = <ir.Member>[];
+    _isSuperMixinApplication = false;
 
-    void addFields(ir.Class c, {bool includeStatic}) {
-      for (ir.Field member in c.fields) {
-        if (!includeStatic && member.isStatic) continue;
-        var name = member.name.name;
-        if (name.contains('#')) {
-          // Skip synthetic .dill members.
-          continue;
-        }
-        _memberMap[name] = member;
-        if (member.isMutable) {
-          _setterMap[name] = member;
-        }
-        members.add(member);
+    void addField(ir.Field member, {bool includeStatic}) {
+      if (!includeStatic && member.isStatic) return;
+      var name = member.name.name;
+      if (name.contains('#')) {
+        // Skip synthetic .dill members.
+        return;
       }
+      _memberMap[name] = member;
+      if (member.isMutable) {
+        _setterMap[name] = member;
+      }
+      members.add(member);
     }
 
-    void addProcedures(ir.Class c,
+    void addProcedure(ir.Procedure member,
         {bool includeStatic, bool includeNoSuchMethodForwarders}) {
-      for (ir.Procedure member in c.procedures) {
-        if (member.isForwardingStub && member.isAbstract) {
-          // Skip abstract forwarding stubs. These are never emitted but they
-          // might shadow the inclusion of a mixed in method in code like:
-          //
-          //     class Super {}
-          //     class Mixin<T> {
-          //       void method(T t) {}
-          //     }
-          //     class Class extends Super with Mixin<int> {}
-          //     main() => new Class().method();
-          //
-          // Here a stub is created for `Super&Mixin.method` hiding that
-          // `Mixin.method` is inherited by `Class`.
-          continue;
+      if (member.isForwardingStub && member.isAbstract) {
+        // Skip abstract forwarding stubs. These are never emitted but they
+        // might shadow the inclusion of a mixed in method in code like:
+        //
+        //     class Super {}
+        //     class Mixin<T> {
+        //       void method(T t) {}
+        //     }
+        //     class Class extends Super with Mixin<int> {}
+        //     main() => new Class().method();
+        //
+        // Here a stub is created for `Super&Mixin.method` hiding that
+        // `Mixin.method` is inherited by `Class`.
+        return;
+      }
+      if (!includeStatic && member.isStatic) return;
+      if (member.isNoSuchMethodForwarder) {
+        // TODO(sigmund): remove once #33665 is fixed.
+        if (!includeNoSuchMethodForwarders ||
+            member.name.isPrivate &&
+                member.name.libraryName != member.enclosingLibrary.reference) {
+          return;
         }
-        if (!includeStatic && member.isStatic) continue;
-        if (member.isNoSuchMethodForwarder) {
-          // TODO(sigmund): remove once #33665 is fixed.
-          if (!includeNoSuchMethodForwarders ||
-              member.name.isPrivate &&
-                  member.name.libraryName !=
-                      member.enclosingLibrary.reference) {
-            continue;
-          }
+      }
+      var name = member.name.name;
+      assert(!name.contains('#'));
+      if (member.kind == ir.ProcedureKind.Factory) {
+        if (member.function.body is ir.RedirectingFactoryBody) {
+          // Don't include redirecting factories.
+          return;
         }
-        var name = member.name.name;
-        assert(!name.contains('#'));
-        if (member.kind == ir.ProcedureKind.Factory) {
-          if (member.function.body is ir.RedirectingFactoryBody) {
-            // Don't include redirecting factories.
-            continue;
-          }
-          _constructorMap[name] = member;
-        } else if (member.kind == ir.ProcedureKind.Setter) {
-          _setterMap[name] = member;
-          members.add(member);
-        } else {
-          assert(member.kind == ir.ProcedureKind.Method ||
-              member.kind == ir.ProcedureKind.Getter ||
-              member.kind == ir.ProcedureKind.Operator);
-          _memberMap[name] = member;
-          members.add(member);
-        }
+        _constructorMap[name] = member;
+      } else if (member.kind == ir.ProcedureKind.Setter) {
+        _setterMap[name] = member;
+        members.add(member);
+      } else {
+        assert(member.kind == ir.ProcedureKind.Method ||
+            member.kind == ir.ProcedureKind.Getter ||
+            member.kind == ir.ProcedureKind.Operator);
+        _memberMap[name] = member;
+        members.add(member);
       }
     }
 
@@ -431,18 +438,40 @@
     }
 
     int mixinMemberCount = 0;
+
     if (cls.mixedInClass != null) {
-      elementMap.ensureClassMembers(cls.mixedInClass);
-      addFields(cls.mixedInClass.mixin, includeStatic: false);
-      addProcedures(cls.mixedInClass.mixin,
-          includeStatic: false, includeNoSuchMethodForwarders: false);
+      CloneVisitor cloneVisitor;
+      for (ir.Field field in cls.mixedInClass.mixin.fields) {
+        if (field.containsSuperCalls) {
+          _isSuperMixinApplication = true;
+          cloneVisitor ??= new SuperCloner(getSubstitutionMap(cls.mixedInType));
+          cls.addMember(cloneVisitor.clone(field));
+          continue;
+        }
+        addField(field, includeStatic: false);
+      }
+      for (ir.Procedure procedure in cls.mixedInClass.mixin.procedures) {
+        if (procedure.containsSuperCalls) {
+          _isSuperMixinApplication = true;
+          cloneVisitor ??= new SuperCloner(getSubstitutionMap(cls.mixedInType));
+          cls.addMember(cloneVisitor.clone(procedure));
+          continue;
+        }
+        addProcedure(procedure,
+            includeStatic: false, includeNoSuchMethodForwarders: false);
+      }
       mergeSort(members, compare: orderByFileOffset);
       mixinMemberCount = members.length;
     }
-    addFields(cls, includeStatic: true);
+
+    for (ir.Field member in cls.fields) {
+      addField(member, includeStatic: true);
+    }
     addConstructors(cls);
-    addProcedures(cls,
-        includeStatic: true, includeNoSuchMethodForwarders: true);
+    for (ir.Procedure member in cls.procedures) {
+      addProcedure(member,
+          includeStatic: true, includeNoSuchMethodForwarders: true);
+    }
 
     if (isUnnamedMixinApplication && _constructorMap.isEmpty) {
       // Ensure that constructors are created for the superclass in case it
@@ -476,7 +505,7 @@
   /// Return the [MemberEntity] for the member [name] in [cls]. If [setter] is
   /// `true`, the setter or assignable field corresponding to [name] is
   /// returned.
-  MemberEntity lookupMember(KernelToElementMap elementMap, String name,
+  MemberEntity lookupMember(IrToElementMap elementMap, String name,
       {bool setter: false}) {
     _ensureMaps(elementMap);
     ir.Member member = setter ? _setterMap[name] : _memberMap[name];
@@ -484,8 +513,7 @@
   }
 
   /// Calls [f] for each member of [cls].
-  void forEachMember(
-      KernelToElementMap elementMap, void f(MemberEntity member)) {
+  void forEachMember(IrToElementMap elementMap, void f(MemberEntity member)) {
     _ensureMaps(elementMap);
     _members.forEach((ir.Member member) {
       f(elementMap.getMember(member));
@@ -493,8 +521,7 @@
   }
 
   /// Return the [ConstructorEntity] for the constructor [name] in [cls].
-  ConstructorEntity lookupConstructor(
-      KernelToElementMap elementMap, String name) {
+  ConstructorEntity lookupConstructor(IrToElementMap elementMap, String name) {
     _ensureMaps(elementMap);
     ir.Member constructor = _constructorMap[name];
     return constructor != null ? elementMap.getConstructor(constructor) : null;
@@ -502,7 +529,7 @@
 
   /// Calls [f] for each constructor of [cls].
   void forEachConstructor(
-      KernelToElementMap elementMap, void f(ConstructorEntity constructor)) {
+      IrToElementMap elementMap, void f(ConstructorEntity constructor)) {
     _ensureMaps(elementMap);
     _constructorMap.values.forEach((ir.Member constructor) {
       f(elementMap.getConstructor(constructor));
@@ -519,7 +546,7 @@
   }
 
   ClassEnv copyLive(
-      KernelToElementMap elementMap, Iterable<MemberEntity> liveMembers) {
+      IrToElementMap elementMap, Iterable<MemberEntity> liveMembers) {
     Map<String, ir.Member> constructorMap;
     Map<String, ir.Member> memberMap;
     Map<String, ir.Member> setterMap;
@@ -568,8 +595,8 @@
         }
       });
     }
-    return new ClassEnvImpl.internal(
-        cls, constructorMap, memberMap, setterMap, members);
+    return new ClassEnvImpl.internal(cls, constructorMap, memberMap, setterMap,
+        members, _isSuperMixinApplication);
   }
 }
 
@@ -577,7 +604,7 @@
   ClosureClassEnv(Map<String, MemberEntity> memberMap) : super(memberMap);
 
   @override
-  MemberEntity lookupMember(KernelToElementMap elementMap, String name,
+  MemberEntity lookupMember(IrToElementMap elementMap, String name,
       {bool setter: false}) {
     if (setter) {
       // All closure fields are final.
@@ -588,7 +615,7 @@
 
   @override
   ClassEnv copyLive(
-          KernelToElementMap elementMap, Iterable<MemberEntity> liveMembers) =>
+          IrToElementMap elementMap, Iterable<MemberEntity> liveMembers) =>
       this;
 }
 
@@ -598,8 +625,9 @@
   RecordEnv(this._memberMap);
 
   @override
-  void ensureMembers(KernelToElementMapBase elementMap) {
+  List<ir.Member> ensureMembers(KernelToElementMapBase elementMap) {
     // All members have been computed at creation.
+    return const <ir.Member>[];
   }
 
   @override
@@ -609,25 +637,23 @@
 
   @override
   void forEachConstructor(
-      KernelToElementMap elementMap, void f(ConstructorEntity constructor)) {
+      IrToElementMap elementMap, void f(ConstructorEntity constructor)) {
     // We do not create constructors for containers.
   }
 
   @override
-  ConstructorEntity lookupConstructor(
-      KernelToElementMap elementMap, String name) {
+  ConstructorEntity lookupConstructor(IrToElementMap elementMap, String name) {
     // We do not create constructors for containers.
     return null;
   }
 
   @override
-  void forEachMember(
-      KernelToElementMap elementMap, void f(MemberEntity member)) {
+  void forEachMember(IrToElementMap elementMap, void f(MemberEntity member)) {
     _memberMap.values.forEach(f);
   }
 
   @override
-  MemberEntity lookupMember(KernelToElementMap elementMap, String name,
+  MemberEntity lookupMember(IrToElementMap elementMap, String name,
       {bool setter: false}) {
     return _memberMap[name];
   }
@@ -636,18 +662,38 @@
   bool get isUnnamedMixinApplication => false;
 
   @override
+  bool get isSuperMixinApplication => false;
+
+  @override
   ir.Class get cls => null;
 
   @override
   ClassEnv copyLive(
-      KernelToElementMap elementMap, Iterable<MemberEntity> liveMembers) {
+      IrToElementMap elementMap, Iterable<MemberEntity> liveMembers) {
     return this;
   }
 }
 
-class ClassData {
-  /// TODO(johnniwinther): Remove this from the [ClassData] interface. Use
-  /// `definition.node` instead.
+abstract class ClassData {
+  ClassDefinition get definition;
+
+  InterfaceType get thisType;
+  InterfaceType get rawType;
+  InterfaceType get supertype;
+  InterfaceType get mixedInType;
+  List<InterfaceType> get interfaces;
+  OrderedTypeSet get orderedTypeSet;
+  DartType get callType;
+
+  bool get isEnumClass;
+  bool get isMixinApplication;
+
+  Iterable<ConstantValue> getMetadata(IrToElementMap elementMap);
+
+  ClassData copy();
+}
+
+class ClassDataImpl implements ClassData {
   final ir.Class cls;
   final ClassDefinition definition;
   bool isMixinApplication;
@@ -659,29 +705,31 @@
   InterfaceType mixedInType;
   List<InterfaceType> interfaces;
   OrderedTypeSet orderedTypeSet;
-  DartType callType;
 
   Iterable<ConstantValue> _metadata;
 
-  ClassData(this.cls, this.definition);
+  ClassDataImpl(this.cls, this.definition);
 
   bool get isEnumClass => cls != null && cls.isEnum;
 
-  Iterable<ConstantValue> getMetadata(KernelToElementMapBase elementMap) {
+  DartType get callType => null;
+
+  Iterable<ConstantValue> getMetadata(
+      covariant KernelToElementMapBase elementMap) {
     return _metadata ??= elementMap.getMetadata(cls.annotations);
   }
 
   ClassData copy() {
-    return new ClassData(cls, definition);
+    return new ClassDataImpl(cls, definition);
   }
 }
 
 abstract class MemberData {
   MemberDefinition get definition;
 
-  Iterable<ConstantValue> getMetadata(KernelToElementMap elementMap);
+  Iterable<ConstantValue> getMetadata(IrToElementMap elementMap);
 
-  InterfaceType getMemberThisType(KernelToElementMapForBuilding elementMap);
+  InterfaceType getMemberThisType(JsToElementMap elementMap);
 
   ClassTypeVariableAccess get classTypeVariableAccess;
 }
@@ -702,7 +750,7 @@
     return _metadata ??= elementMap.getMetadata(node.annotations);
   }
 
-  InterfaceType getMemberThisType(KernelToElementMapForBuilding elementMap) {
+  InterfaceType getMemberThisType(JsToElementMap elementMap) {
     MemberEntity member = elementMap.getMember(node);
     ClassEntity cls = member.enclosingClass;
     if (cls != null) {
@@ -715,12 +763,11 @@
 }
 
 abstract class FunctionData implements MemberData {
-  FunctionType getFunctionType(KernelToElementMap elementMap);
+  FunctionType getFunctionType(IrToElementMap elementMap);
 
-  List<TypeVariableType> getFunctionTypeVariables(
-      KernelToElementMap elementMap);
+  List<TypeVariableType> getFunctionTypeVariables(IrToElementMap elementMap);
 
-  void forEachParameter(KernelToElementMapForBuilding elementMap,
+  void forEachParameter(JsToElementMap elementMap,
       void f(DartType type, String name, ConstantValue defaultValue));
 }
 
@@ -766,7 +813,7 @@
     return _type ??= elementMap.getFunctionType(functionNode);
   }
 
-  void forEachParameter(KernelToElementMapForBuilding elementMap,
+  void forEachParameter(JsToElementMap elementMap,
       void f(DartType type, String name, ConstantValue defaultValue)) {
     void handleParameter(ir.VariableDeclaration node, {bool isOptional: true}) {
       DartType type = elementMap.getDartType(node.type);
@@ -817,25 +864,24 @@
     return functionType;
   }
 
-  List<TypeVariableType> getFunctionTypeVariables(
-      KernelToElementMap elementMap) {
+  List<TypeVariableType> getFunctionTypeVariables(IrToElementMap elementMap) {
     return typeParameters
         .map<TypeVariableType>((ir.TypeParameter typeParameter) {
       return elementMap.getDartType(new ir.TypeParameterType(typeParameter));
     }).toList();
   }
 
-  void forEachParameter(KernelToElementMapForBuilding elementMap,
+  void forEachParameter(JsToElementMap elementMap,
       void f(DartType type, String name, ConstantValue defaultValue)) {
     throw new UnimplementedError('SignatureData.forEachParameter');
   }
 
   @override
-  Iterable<ConstantValue> getMetadata(KernelToElementMap elementMap) {
+  Iterable<ConstantValue> getMetadata(IrToElementMap elementMap) {
     return const <ConstantValue>[];
   }
 
-  InterfaceType getMemberThisType(KernelToElementMapForBuilding elementMap) {
+  InterfaceType getMemberThisType(JsToElementMap elementMap) {
     return memberThisType;
   }
 }
@@ -849,22 +895,21 @@
     return baseData.getFunctionType(elementMap);
   }
 
-  List<TypeVariableType> getFunctionTypeVariables(
-      KernelToElementMap elementMap) {
+  List<TypeVariableType> getFunctionTypeVariables(IrToElementMap elementMap) {
     return baseData.getFunctionTypeVariables(elementMap);
   }
 
-  void forEachParameter(KernelToElementMapForBuilding elementMap,
+  void forEachParameter(JsToElementMap elementMap,
       void f(DartType type, String name, ConstantValue defaultValue)) {
     return baseData.forEachParameter(elementMap, f);
   }
 
   @override
-  Iterable<ConstantValue> getMetadata(KernelToElementMap elementMap) {
+  Iterable<ConstantValue> getMetadata(IrToElementMap elementMap) {
     return const <ConstantValue>[];
   }
 
-  InterfaceType getMemberThisType(KernelToElementMapForBuilding elementMap) {
+  InterfaceType getMemberThisType(JsToElementMap elementMap) {
     return baseData.getMemberThisType(elementMap);
   }
 
@@ -930,7 +975,7 @@
 }
 
 abstract class FieldData extends MemberData {
-  DartType getFieldType(KernelToElementMap elementMap);
+  DartType getFieldType(IrToElementMap elementMap);
 
   ConstantExpression getFieldConstantExpression(
       KernelToElementMapBase elementMap);
@@ -1029,11 +1074,11 @@
 
   TypeVariableData(this.node);
 
-  DartType getBound(KernelToElementMap elementMap) {
+  DartType getBound(IrToElementMap elementMap) {
     return _bound ??= elementMap.getDartType(node.bound);
   }
 
-  DartType getDefaultType(KernelToElementMap elementMap) {
+  DartType getDefaultType(IrToElementMap elementMap) {
     return _defaultType ??= elementMap.getDartType(node.defaultType);
   }
 
@@ -1041,3 +1086,29 @@
     return new TypeVariableData(node);
   }
 }
+
+class SuperCloner extends CloneVisitor {
+  SuperCloner(Map<ir.TypeParameter, ir.DartType> typeSubstitution)
+      : super(typeSubstitution: typeSubstitution, cloneAnnotations: true);
+
+  @override
+  visitSuperMethodInvocation(ir.SuperMethodInvocation node) {
+    // We ensure that we re-resolve the target by setting the interface target
+    // to `null`.
+    return new ir.SuperMethodInvocation(node.name, clone(node.arguments));
+  }
+
+  @override
+  visitSuperPropertyGet(ir.SuperPropertyGet node) {
+    // We ensure that we re-resolve the target by setting the interface target
+    // to `null`.
+    return new ir.SuperPropertyGet(node.name);
+  }
+
+  @override
+  visitSuperPropertySet(ir.SuperPropertySet node) {
+    // We ensure that we re-resolve the target by setting the interface target
+    // to `null`.
+    return new ir.SuperPropertySet(node.name, clone(node.value), null);
+  }
+}
diff --git a/pkg/compiler/lib/src/kernel/kelements.dart b/pkg/compiler/lib/src/kernel/kelements.dart
index 38d7dd6..de67244 100644
--- a/pkg/compiler/lib/src/kernel/kelements.dart
+++ b/pkg/compiler/lib/src/kernel/kelements.dart
@@ -6,9 +6,9 @@
 
 import 'package:kernel/ast.dart' as ir;
 import '../elements/entities.dart';
+import '../elements/indexed.dart';
 import '../elements/names.dart';
 import '../elements/types.dart';
-import 'indexed.dart';
 
 const String kElementPrefix = 'k:';
 
diff --git a/pkg/compiler/lib/src/kernel/kernel_backend_strategy.dart b/pkg/compiler/lib/src/kernel/kernel_backend_strategy.dart
deleted file mode 100644
index 9b4dae7..0000000
--- a/pkg/compiler/lib/src/kernel/kernel_backend_strategy.dart
+++ /dev/null
@@ -1,299 +0,0 @@
-// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.kernel.backend_strategy;
-
-import 'package:kernel/ast.dart' as ir;
-
-import '../backend_strategy.dart';
-import '../common.dart';
-import '../common/codegen.dart' show CodegenRegistry, CodegenWorkItem;
-import '../common/tasks.dart';
-import '../compiler.dart';
-import '../elements/entities.dart';
-import '../elements/entity_utils.dart' as utils;
-import '../enqueue.dart';
-import '../js_backend/backend.dart';
-import '../js_emitter/sorter.dart';
-import '../js_model/js_strategy.dart';
-import '../js_model/locals.dart';
-import '../kernel/element_map.dart';
-import '../native/behavior.dart';
-import '../options.dart';
-import '../ssa/builder_kernel.dart';
-import '../ssa/nodes.dart';
-import '../ssa/ssa.dart';
-import '../ssa/types.dart';
-import '../types/abstract_value_domain.dart';
-import '../types/types.dart';
-import '../universe/selector.dart';
-import '../universe/world_impact.dart';
-import '../world.dart';
-
-/// A backend strategy based on Kernel IR nodes.
-abstract class KernelBackendStrategy implements BackendStrategy {
-  KernelToElementMapForBuilding get elementMap;
-  GlobalLocalsMap get globalLocalsMapForTesting;
-
-  factory KernelBackendStrategy(Compiler compiler) {
-    return new JsBackendStrategy(compiler);
-  }
-}
-
-class KernelCodegenWorkItemBuilder implements WorkItemBuilder {
-  final JavaScriptBackend _backend;
-  final JClosedWorld _closedWorld;
-  final GlobalTypeInferenceResults _globalInferenceResults;
-
-  KernelCodegenWorkItemBuilder(
-      this._backend, this._closedWorld, this._globalInferenceResults);
-
-  CompilerOptions get _options => _backend.compiler.options;
-
-  @override
-  CodegenWorkItem createWorkItem(MemberEntity entity) {
-    if (entity.isAbstract) return null;
-
-    // Codegen inlines field initializers. It only needs to generate
-    // code for checked setters.
-    if (entity.isField && entity.isInstanceMember) {
-      if (!_options.parameterCheckPolicy.isEmitted ||
-          entity.enclosingClass.isClosure) {
-        return null;
-      }
-    }
-
-    return new KernelCodegenWorkItem(
-        _backend, _closedWorld, _globalInferenceResults, entity);
-  }
-}
-
-class KernelCodegenWorkItem extends CodegenWorkItem {
-  final JavaScriptBackend _backend;
-  final JClosedWorld _closedWorld;
-  final MemberEntity element;
-  final CodegenRegistry registry;
-  final GlobalTypeInferenceResults _globalInferenceResults;
-
-  KernelCodegenWorkItem(this._backend, this._closedWorld,
-      this._globalInferenceResults, this.element)
-      : registry =
-            new CodegenRegistry(_closedWorld.elementEnvironment, element);
-
-  @override
-  WorldImpact run() {
-    return _backend.codegen(this, _closedWorld, _globalInferenceResults);
-  }
-}
-
-/// Task for building SSA from kernel IR loaded from .dill.
-class KernelSsaBuilder implements SsaBuilder {
-  final CompilerTask task;
-  final Compiler _compiler;
-  final KernelToElementMapForBuilding _elementMap;
-  final GlobalLocalsMap _globalLocalsMap;
-
-  KernelSsaBuilder(
-      this.task, this._compiler, this._elementMap, this._globalLocalsMap);
-
-  @override
-  HGraph build(CodegenWorkItem work, JClosedWorld closedWorld,
-      GlobalTypeInferenceResults results) {
-    return task.measure(() {
-      KernelSsaGraphBuilder builder = new KernelSsaGraphBuilder(
-          work.element,
-          _elementMap.getMemberThisType(work.element),
-          _compiler,
-          _elementMap,
-          results,
-          _globalLocalsMap,
-          closedWorld,
-          _compiler.codegenWorldBuilder,
-          work.registry,
-          _compiler.backendStrategy.closureDataLookup,
-          _compiler.backend.emitter.nativeEmitter,
-          _compiler.backend.sourceInformationStrategy);
-      return builder.build();
-    });
-  }
-}
-
-class KernelToTypeInferenceMapImpl implements KernelToTypeInferenceMap {
-  final GlobalTypeInferenceResults _globalInferenceResults;
-  GlobalTypeInferenceMemberResult _targetResults;
-
-  KernelToTypeInferenceMapImpl(
-      MemberEntity target, this._globalInferenceResults) {
-    _targetResults = _resultOf(target);
-  }
-
-  GlobalTypeInferenceMemberResult _resultOf(MemberEntity e) =>
-      _globalInferenceResults
-          .resultOfMember(e is ConstructorBodyEntity ? e.constructor : e);
-
-  AbstractValue getReturnTypeOf(FunctionEntity function) {
-    return AbstractValueFactory.inferredReturnTypeForElement(
-        function, _globalInferenceResults);
-  }
-
-  AbstractValue receiverTypeOfInvocation(
-      ir.MethodInvocation node, AbstractValueDomain abstractValueDomain) {
-    return _targetResults.typeOfSend(node);
-  }
-
-  AbstractValue receiverTypeOfGet(ir.PropertyGet node) {
-    return _targetResults.typeOfSend(node);
-  }
-
-  AbstractValue receiverTypeOfDirectGet(ir.DirectPropertyGet node) {
-    return _targetResults.typeOfSend(node);
-  }
-
-  AbstractValue receiverTypeOfSet(
-      ir.PropertySet node, AbstractValueDomain abstractValueDomain) {
-    return _targetResults.typeOfSend(node);
-  }
-
-  AbstractValue typeOfListLiteral(MemberEntity owner,
-      ir.ListLiteral listLiteral, AbstractValueDomain abstractValueDomain) {
-    return _resultOf(owner).typeOfListLiteral(listLiteral) ??
-        abstractValueDomain.dynamicType;
-  }
-
-  AbstractValue typeOfIterator(ir.ForInStatement node) {
-    return _targetResults.typeOfIterator(node);
-  }
-
-  AbstractValue typeOfIteratorCurrent(ir.ForInStatement node) {
-    return _targetResults.typeOfIteratorCurrent(node);
-  }
-
-  AbstractValue typeOfIteratorMoveNext(ir.ForInStatement node) {
-    return _targetResults.typeOfIteratorMoveNext(node);
-  }
-
-  bool isJsIndexableIterator(
-      ir.ForInStatement node, AbstractValueDomain abstractValueDomain) {
-    AbstractValue mask = typeOfIterator(node);
-    return abstractValueDomain.isJsIndexableAndIterable(mask);
-  }
-
-  AbstractValue inferredIndexType(ir.ForInStatement node) {
-    return AbstractValueFactory.inferredTypeForSelector(
-        new Selector.index(), typeOfIterator(node), _globalInferenceResults);
-  }
-
-  AbstractValue getInferredTypeOf(MemberEntity member) {
-    return AbstractValueFactory.inferredTypeForMember(
-        member, _globalInferenceResults);
-  }
-
-  AbstractValue getInferredTypeOfParameter(Local parameter) {
-    return AbstractValueFactory.inferredTypeForParameter(
-        parameter, _globalInferenceResults);
-  }
-
-  AbstractValue selectorTypeOf(Selector selector, AbstractValue mask) {
-    return AbstractValueFactory.inferredTypeForSelector(
-        selector, mask, _globalInferenceResults);
-  }
-
-  AbstractValue typeFromNativeBehavior(
-      NativeBehavior nativeBehavior, JClosedWorld closedWorld) {
-    return AbstractValueFactory.fromNativeBehavior(nativeBehavior, closedWorld);
-  }
-}
-
-class KernelSorter implements Sorter {
-  final KernelToElementMapForBuilding elementMap;
-
-  KernelSorter(this.elementMap);
-
-  int _compareLibraries(LibraryEntity a, LibraryEntity b) {
-    return utils.compareLibrariesUris(a.canonicalUri, b.canonicalUri);
-  }
-
-  int _compareSourceSpans(Entity entity1, SourceSpan sourceSpan1,
-      Entity entity2, SourceSpan sourceSpan2) {
-    int r = utils.compareSourceUris(sourceSpan1.uri, sourceSpan2.uri);
-    if (r != 0) return r;
-    return utils.compareEntities(
-        entity1, sourceSpan1.begin, null, entity2, sourceSpan2.begin, null);
-  }
-
-  @override
-  Iterable<LibraryEntity> sortLibraries(Iterable<LibraryEntity> libraries) {
-    return libraries.toList()..sort(_compareLibraries);
-  }
-
-  @override
-  Iterable<T> sortMembers<T extends MemberEntity>(Iterable<T> members) {
-    return members.toList()..sort(compareMembersByLocation);
-  }
-
-  @override
-  Iterable<ClassEntity> sortClasses(Iterable<ClassEntity> classes) {
-    List<ClassEntity> regularClasses = <ClassEntity>[];
-    List<ClassEntity> unnamedMixins = <ClassEntity>[];
-    for (ClassEntity cls in classes) {
-      if (elementMap.elementEnvironment.isUnnamedMixinApplication(cls)) {
-        unnamedMixins.add(cls);
-      } else {
-        regularClasses.add(cls);
-      }
-    }
-    List<ClassEntity> sorted = <ClassEntity>[];
-    regularClasses.sort(compareClassesByLocation);
-    sorted.addAll(regularClasses);
-    unnamedMixins.sort((a, b) {
-      int result = _compareLibraries(a.library, b.library);
-      if (result != 0) return result;
-      result = a.name.compareTo(b.name);
-      assert(result != 0,
-          failedAt(a, "Multiple mixins named ${a.name}: $a vs $b."));
-      return result;
-    });
-    sorted.addAll(unnamedMixins);
-    return sorted;
-  }
-
-  @override
-  Iterable<TypedefEntity> sortTypedefs(Iterable<TypedefEntity> typedefs) {
-    // TODO(redemption): Support this.
-    assert(typedefs.isEmpty);
-    return typedefs;
-  }
-
-  @override
-  int compareLibrariesByLocation(LibraryEntity a, LibraryEntity b) {
-    return _compareLibraries(a, b);
-  }
-
-  @override
-  int compareClassesByLocation(ClassEntity a, ClassEntity b) {
-    int r = _compareLibraries(a.library, b.library);
-    if (r != 0) return r;
-    ClassDefinition definition1 = elementMap.getClassDefinition(a);
-    ClassDefinition definition2 = elementMap.getClassDefinition(b);
-    return _compareSourceSpans(
-        a, definition1.location, b, definition2.location);
-  }
-
-  @override
-  int compareTypedefsByLocation(TypedefEntity a, TypedefEntity b) {
-    // TODO(redemption): Support this.
-    failedAt(a, 'KernelSorter.compareTypedefsByLocation unimplemented');
-    return 0;
-  }
-
-  @override
-  int compareMembersByLocation(MemberEntity a, MemberEntity b) {
-    int r = _compareLibraries(a.library, b.library);
-    if (r != 0) return r;
-    MemberDefinition definition1 = elementMap.getMemberDefinition(a);
-    MemberDefinition definition2 = elementMap.getMemberDefinition(b);
-    return _compareSourceSpans(
-        a, definition1.location, b, definition2.location);
-  }
-}
diff --git a/pkg/compiler/lib/src/kernel/kernel_strategy.dart b/pkg/compiler/lib/src/kernel/kernel_strategy.dart
index ee4738f..6eca5ad 100644
--- a/pkg/compiler/lib/src/kernel/kernel_strategy.dart
+++ b/pkg/compiler/lib/src/kernel/kernel_strategy.dart
@@ -40,7 +40,7 @@
 class KernelFrontEndStrategy extends FrontendStrategyBase {
   CompilerOptions _options;
   CompilerTask _compilerTask;
-  KernelToElementMapForImpactImpl _elementMap;
+  KernelToElementMapImpl _elementMap;
   RuntimeTypesNeedBuilder _runtimeTypesNeedBuilder;
 
   KernelAnnotationProcessor _annotationProcesser;
@@ -51,8 +51,8 @@
   KernelFrontEndStrategy(this._compilerTask, this._options,
       DiagnosticReporter reporter, env.Environment environment) {
     assert(_compilerTask != null);
-    _elementMap = new KernelToElementMapForImpactImpl(
-        reporter, environment, this, _options);
+    _elementMap =
+        new KernelToElementMapImpl(reporter, environment, this, _options);
   }
 
   @override
@@ -68,7 +68,7 @@
 
   DartTypes get dartTypes => _elementMap.types;
 
-  KernelToElementMapForImpact get elementMap => _elementMap;
+  KernelToElementMap get elementMap => _elementMap;
 
   @override
   AnnotationProcessor get annotationProcesser => _annotationProcesser ??=
@@ -157,7 +157,7 @@
 
 class KernelWorkItemBuilder implements WorkItemBuilder {
   final CompilerTask _compilerTask;
-  final KernelToElementMapForImpactImpl _elementMap;
+  final KernelToElementMapImpl _elementMap;
   final ImpactTransformer _impactTransformer;
   final NativeMemberResolver _nativeMemberResolver;
   final Map<MemberEntity, ScopeModel> closureModels;
@@ -183,7 +183,7 @@
 
 class KernelWorkItem implements WorkItem {
   final CompilerTask _compilerTask;
-  final KernelToElementMapForImpactImpl _elementMap;
+  final KernelToElementMapImpl _elementMap;
   final ImpactTransformer _impactTransformer;
   final NativeMemberResolver _nativeMemberResolver;
   final MemberEntity element;
diff --git a/pkg/compiler/lib/src/kernel/native_basic_data.dart b/pkg/compiler/lib/src/kernel/native_basic_data.dart
index 7a05fc0..e0f5e9e 100644
--- a/pkg/compiler/lib/src/kernel/native_basic_data.dart
+++ b/pkg/compiler/lib/src/kernel/native_basic_data.dart
@@ -6,7 +6,7 @@
 part of dart2js.kernel.element_map;
 
 class KernelAnnotationProcessor implements AnnotationProcessor {
-  final KernelToElementMapForImpactImpl elementMap;
+  final KernelToElementMapImpl elementMap;
   final NativeBasicDataBuilder _nativeBasicDataBuilder;
 
   KernelAnnotationProcessor(this.elementMap, this._nativeBasicDataBuilder);
diff --git a/pkg/compiler/lib/src/kernel/no_such_method_resolver.dart b/pkg/compiler/lib/src/kernel/no_such_method_resolver.dart
index 29b4657..c57d9e1 100644
--- a/pkg/compiler/lib/src/kernel/no_such_method_resolver.dart
+++ b/pkg/compiler/lib/src/kernel/no_such_method_resolver.dart
@@ -5,7 +5,7 @@
 part of dart2js.kernel.element_map;
 
 class KernelNoSuchMethodResolver implements NoSuchMethodResolver {
-  final KernelToElementMapForImpactImpl elementMap;
+  final KernelToElementMapImpl elementMap;
 
   KernelNoSuchMethodResolver(this.elementMap);
 
diff --git a/pkg/compiler/lib/src/kernel/runtime_type_analysis.dart b/pkg/compiler/lib/src/kernel/runtime_type_analysis.dart
index 1edab46..b5da035 100644
--- a/pkg/compiler/lib/src/kernel/runtime_type_analysis.dart
+++ b/pkg/compiler/lib/src/kernel/runtime_type_analysis.dart
@@ -6,12 +6,13 @@
 
 import '../common/names.dart';
 import '../elements/types.dart';
-import '../kernel/element_map.dart';
+import '../ir/util.dart';
 import '../universe/feature.dart';
+import 'element_map.dart';
 
 /// Computes the [RuntimeTypeUse] corresponding to the `e.runtimeType` [node].
 RuntimeTypeUse computeRuntimeTypeUse(
-    KernelToElementMapForImpact elementMap, ir.PropertyGet node) {
+    KernelToElementMap elementMap, ir.PropertyGet node) {
   /// Returns `true` if [node] is of the form `e.runtimeType`.
   bool isGetRuntimeType(ir.TreeNode node) {
     return node is ir.PropertyGet && node.name.name == Identifiers.runtimeType_;
diff --git a/pkg/compiler/lib/src/library_loader.dart b/pkg/compiler/lib/src/library_loader.dart
index a941245..e4295e8 100644
--- a/pkg/compiler/lib/src/library_loader.dart
+++ b/pkg/compiler/lib/src/library_loader.dart
@@ -41,6 +41,8 @@
       : initializedCompilerState = _options.kernelInitializedCompilerState,
         super(measurer);
 
+  String get name => 'Library loader';
+
   /// Loads an entire Kernel [Component] from a file on disk.
   Future<LoadedLibraries> loadLibraries(Uri resolvedUri) {
     return measure(() async {
@@ -54,7 +56,7 @@
       } else {
         String targetName =
             _options.compileForServer ? "dart2js_server" : "dart2js";
-        String platform = '${targetName}_platform_strong.dill';
+        String platform = '${targetName}_platform.dill';
         initializedCompilerState = fe.initializeCompiler(
             initializedCompilerState,
             new Dart2jsTarget(targetName, new TargetFlags(strongMode: true)),
diff --git a/pkg/compiler/lib/src/native/enqueue.dart b/pkg/compiler/lib/src/native/enqueue.dart
index 968b7cf..a3a1dd2 100644
--- a/pkg/compiler/lib/src/native/enqueue.dart
+++ b/pkg/compiler/lib/src/native/enqueue.dart
@@ -121,9 +121,8 @@
         matchingClasses
             .addAll(_findUnusedClassesMatching((ClassEntity nativeClass) {
           InterfaceType nativeType =
-              _elementEnvironment.getThisType(nativeClass);
-          InterfaceType specType =
-              _elementEnvironment.getThisType(type.element);
+              _elementEnvironment.getRawType(nativeClass);
+          InterfaceType specType = _elementEnvironment.getRawType(type.element);
           return _dartTypes.isSubtype(nativeType, specType);
         }));
       } else if (type.isDynamic) {
diff --git a/pkg/compiler/lib/src/resolution/registry.dart b/pkg/compiler/lib/src/resolution/registry.dart
index b8f4879..18f373a 100644
--- a/pkg/compiler/lib/src/resolution/registry.dart
+++ b/pkg/compiler/lib/src/resolution/registry.dart
@@ -131,7 +131,7 @@
 
   String toString() {
     StringBuffer sb = new StringBuffer();
-    sb.write('_ResolutionWorldImpact($name)');
+    sb.write('ResolutionWorldImpactBuilder($name)');
     WorldImpact.printOn(sb, this);
     if (_features != null) {
       sb.write('\n features:');
diff --git a/pkg/compiler/lib/src/ssa/builder_kernel.dart b/pkg/compiler/lib/src/ssa/builder_kernel.dart
index efb6546..7305936 100644
--- a/pkg/compiler/lib/src/ssa/builder_kernel.dart
+++ b/pkg/compiler/lib/src/ssa/builder_kernel.dart
@@ -21,17 +21,19 @@
 import '../elements/jumps.dart';
 import '../elements/names.dart';
 import '../elements/types.dart';
+import '../ir/util.dart';
 import '../io/source_information.dart';
 import '../js/js.dart' as js;
 import '../js_backend/allocator_analysis.dart' show JAllocatorAnalysis;
-import '../js_backend/backend.dart' show JavaScriptBackend;
+import '../js_backend/backend.dart' show FunctionInlineCache, JavaScriptBackend;
 import '../js_backend/runtime_types.dart' show RuntimeTypesSubstitutions;
 import '../js_emitter/js_emitter.dart' show NativeEmitter;
 import '../js_model/locals.dart'
     show forEachOrderedParameter, GlobalLocalsMap, JumpVisitor;
 import '../js_model/elements.dart' show JGeneratorBody;
+import '../js_model/element_map.dart';
+import '../js_model/js_strategy.dart';
 import '../kernel/element_map.dart';
-import '../kernel/kernel_backend_strategy.dart';
 import '../native/native.dart' as native;
 import '../types/abstract_value_domain.dart';
 import '../types/types.dart';
@@ -98,7 +100,7 @@
   JavaScriptBackend get backend => compiler.backend;
 
   final SourceInformationStrategy _sourceInformationStrategy;
-  final KernelToElementMapForBuilding _elementMap;
+  final JsToElementMap _elementMap;
   final GlobalTypeInferenceResults globalInferenceResults;
   final GlobalLocalsMap _globalLocalsMap;
   LoopHandler loopHandler;
@@ -121,20 +123,23 @@
 
   StackFrame _currentFrame;
 
+  final FunctionInlineCache inlineCache;
+
   KernelSsaGraphBuilder(
-    this.initialTargetElement,
-    InterfaceType instanceType,
-    this.compiler,
-    this._elementMap,
-    this.globalInferenceResults,
-    this._globalLocalsMap,
-    this.closedWorld,
-    this._worldBuilder,
-    this.registry,
-    this.closureDataLookup,
-    this.nativeEmitter,
-    this._sourceInformationStrategy,
-  )   : this.targetElement = _effectiveTargetElementFor(initialTargetElement),
+      this.initialTargetElement,
+      InterfaceType instanceType,
+      this.compiler,
+      this._elementMap,
+      this.globalInferenceResults,
+      this._globalLocalsMap,
+      this.closedWorld,
+      this._worldBuilder,
+      this.registry,
+      this.closureDataLookup,
+      this.nativeEmitter,
+      this._sourceInformationStrategy,
+      this.inlineCache)
+      : this.targetElement = _effectiveTargetElementFor(initialTargetElement),
         _infoReporter = compiler.dumpInfoTask,
         _allocatorAnalysis = closedWorld.allocatorAnalysis {
     _enterFrame(targetElement, null);
@@ -1527,7 +1532,7 @@
     JumpTarget jumpTarget = localsMap.getJumpTargetForFor(node);
     loopHandler.handleLoop(
         node,
-        localsMap.getCapturedLoopScope(closureDataLookup, node),
+        closureDataLookup.getCapturedLoopScope(node),
         jumpTarget,
         buildInitializer,
         buildCondition,
@@ -1683,7 +1688,7 @@
 
     loopHandler.handleLoop(
         node,
-        localsMap.getCapturedLoopScope(closureDataLookup, node),
+        closureDataLookup.getCapturedLoopScope(node),
         localsMap.getJumpTargetForForIn(node),
         buildInitializer,
         buildCondition,
@@ -1750,7 +1755,7 @@
 
     loopHandler.handleLoop(
         node,
-        localsMap.getCapturedLoopScope(closureDataLookup, node),
+        closureDataLookup.getCapturedLoopScope(node),
         localsMap.getJumpTargetForForIn(node),
         buildInitializer,
         buildCondition,
@@ -1823,7 +1828,7 @@
     // Build fake try body:
     loopHandler.handleLoop(
         node,
-        localsMap.getCapturedLoopScope(closureDataLookup, node),
+        closureDataLookup.getCapturedLoopScope(node),
         localsMap.getJumpTargetForForIn(node),
         buildInitializer,
         buildCondition,
@@ -1876,7 +1881,7 @@
 
     loopHandler.handleLoop(
         node,
-        localsMap.getCapturedLoopScope(closureDataLookup, node),
+        closureDataLookup.getCapturedLoopScope(node),
         localsMap.getJumpTargetForWhile(node),
         () {},
         buildCondition,
@@ -1893,7 +1898,7 @@
     // LoopHandler.handleLoop with some tricks about when the "update" happens.
     LocalsHandler savedLocals = new LocalsHandler.from(localsHandler);
     CapturedLoopScope loopClosureInfo =
-        localsMap.getCapturedLoopScope(closureDataLookup, node);
+        closureDataLookup.getCapturedLoopScope(node);
     localsHandler.startLoop(loopClosureInfo, sourceInformation);
     JumpTarget target = localsMap.getJumpTargetForDo(node);
     JumpHandler jumpHandler = loopHandler.beginLoopHeader(node, target);
@@ -2461,7 +2466,7 @@
     void buildLoop() {
       loopHandler.handleLoop(
           switchStatement,
-          localsMap.getCapturedLoopScope(closureDataLookup, switchStatement),
+          closureDataLookup.getCapturedLoopScope(switchStatement),
           switchTarget,
           () {},
           buildCondition,
@@ -3293,7 +3298,7 @@
       return;
     }
 
-    if (function == _commonElements.extractTypeArguments &&
+    if (_commonElements.isExtractTypeArguments(function) &&
         handleExtractTypeArguments(node, sourceInformation)) {
       return;
     }
@@ -4336,7 +4341,7 @@
     SourceInformation sourceInformation =
         _sourceInformationBuilder.buildCreate(node);
     ClosureRepresentationInfo closureInfo =
-        localsMap.getClosureRepresentationInfo(closureDataLookup, node.parent);
+        closureDataLookup.getClosureInfo(node.parent);
     ClassEntity closureClassEntity = closureInfo.closureClassEntity;
 
     List<HInstruction> capturedVariables = <HInstruction>[];
@@ -4575,11 +4580,11 @@
     }
     List<DartType> typeArguments =
         _getStaticTypeArguments(member, node.arguments);
+
+    MemberDefinition targetDefinition = _elementMap.getMemberDefinition(member);
+    ir.Procedure target = targetDefinition.node;
     List<HInstruction> arguments = _visitArgumentsForStaticTarget(
-        node.interfaceTarget.function,
-        node.arguments,
-        typeArguments,
-        sourceInformation);
+        target.function, node.arguments, typeArguments, sourceInformation);
     _buildInvokeSuper(
         _elementMap.getSelector(node),
         _elementMap.getClass(_containingClass(node)),
@@ -4995,13 +5000,12 @@
         return InlineWeeder.canBeInlined(_elementMap, function, null,
             enableUserAssertions: options.enableUserAssertions);
       }
-      // TODO(sra): Measure if inlining would 'reduce' the size.  One desirable
-      // case we miss by doing nothing is inlining very simple constructors
-      // where all fields are initialized with values from the arguments at this
-      // call site.  The code is slightly larger (`new Foo(1)` vs `Foo$(1)`) but
-      // that usually means the factory constructor is left unused and not
-      // emitted.
-      // We at least inline bodies that are empty (and thus have a size of 1).
+      if (InlineReductiveWeeder.canBeInlined(
+          _elementMap, function, providedArguments.length,
+          enableUserAssertions: options.enableUserAssertions,
+          omitImplicitCasts: options.omitImplicitChecks)) {
+        return true;
+      }
       return doesNotContainCode();
     }
 
@@ -5594,8 +5598,8 @@
   static const INLINING_NODES_INSIDE_LOOP = 34;
   static const INLINING_NODES_INSIDE_LOOP_ARG_FACTOR = 4;
 
-  static bool canBeInlined(KernelToElementMapForBuilding elementMap,
-      FunctionEntity function, int maxInliningNodes,
+  static bool canBeInlined(
+      JsToElementMap elementMap, FunctionEntity function, int maxInliningNodes,
       {bool allowLoops: false, bool enableUserAssertions: null}) {
     return cannotBeInlinedReason(elementMap, function, maxInliningNodes,
             allowLoops: allowLoops,
@@ -5603,8 +5607,8 @@
         null;
   }
 
-  static String cannotBeInlinedReason(KernelToElementMapForBuilding elementMap,
-      FunctionEntity function, int maxInliningNodes,
+  static String cannotBeInlinedReason(
+      JsToElementMap elementMap, FunctionEntity function, int maxInliningNodes,
       {bool allowLoops: false, bool enableUserAssertions: null}) {
     InlineWeeder visitor =
         new InlineWeeder(maxInliningNodes, allowLoops, enableUserAssertions);
@@ -5775,6 +5779,329 @@
   }
 }
 
+/// Determines if inlining a function is very likely to reduce code size.
+class InlineReductiveWeeder extends ir.Visitor {
+  // We allow the body to be a single function call that does not have any more
+  // inputs than the inlinee.
+  //
+  // We allow the body to be the return of an 'eligible' constant. A constant is
+  // 'eligible' if it is not large (e.g. a long string).
+  //
+  // We skip 'e as{TypeError} T' when the checks are omitted.
+  //
+  //
+  // TODO(sra): Consider slightly expansive simple constructors where all we
+  // gain is a 'new' keyword, e.g. `new X.Foo(a)` vs `X.Foo$(a)`.
+  //
+  // TODO(25231): Make larger string constants eligible by sharing references.
+
+  static bool canBeInlined(
+      JsToElementMap elementMap, FunctionEntity function, int argumentCount,
+      {bool enableUserAssertions: null, bool omitImplicitCasts: null}) {
+    return cannotBeInlinedReason(elementMap, function, argumentCount,
+            enableUserAssertions: enableUserAssertions,
+            omitImplicitCasts: omitImplicitCasts) ==
+        null;
+  }
+
+  static String cannotBeInlinedReason(
+      JsToElementMap elementMap, FunctionEntity function, int argumentCount,
+      {bool enableUserAssertions: null, bool omitImplicitCasts: null}) {
+    assert(enableUserAssertions != null);
+    assert(omitImplicitCasts != null);
+    var visitor = new InlineReductiveWeeder(
+        argumentCount, enableUserAssertions, omitImplicitCasts);
+    ir.FunctionNode node = getFunctionNode(elementMap, function);
+    if (function.isConstructor) {
+      return visitor.tooDifficultReason ??= 'constructor';
+    }
+    node.accept(visitor);
+    return visitor.tooDifficultReason;
+  }
+
+  final int argumentCount;
+  final bool enableUserAssertions;
+  final bool omitImplicitCasts;
+  final int maxInliningNodes;
+
+  bool seenReturn = false;
+  int nodeCount = 0;
+  int callCount = 0;
+  String tooDifficultReason;
+  bool get tooDifficult => tooDifficultReason != null;
+
+  InlineReductiveWeeder(
+      this.argumentCount, this.enableUserAssertions, this.omitImplicitCasts)
+      :
+        // Node budget that covers one call and the passed-in arguments.
+        // The +1 also allows a top-level zero-argument to be inlined if it
+        // returns a constant.
+        maxInliningNodes = argumentCount + 1;
+
+  bool registerNode() {
+    if (++nodeCount > maxInliningNodes) {
+      tooDifficultReason ??= 'too many nodes';
+      return false;
+    }
+    return true;
+  }
+
+  bool registerCall() {
+    if (++callCount > 1) {
+      tooDifficultReason ??= 'too many calls';
+      return false;
+    }
+    return true;
+  }
+
+  @override
+  defaultNode(ir.Node node) {
+    if (tooDifficult) return;
+    if (seenReturn) {
+      tooDifficultReason ??= 'code after return';
+      return;
+    }
+    if (!registerNode()) return;
+    node.visitChildren(this);
+  }
+
+  @override
+  visitReturnStatement(ir.ReturnStatement node) {
+    if (seenReturn) {
+      tooDifficultReason ??= 'code after return';
+      return;
+    }
+    node.visitChildren(this);
+    seenReturn = true;
+  }
+
+  @override
+  visitThrow(ir.Throw node) {
+    tooDifficultReason ??= 'throw';
+  }
+
+  @override
+  visitEmptyStatement(ir.EmptyStatement node) {}
+
+  @override
+  visitExpressionStatement(ir.ExpressionStatement node) {
+    node.visitChildren(this);
+  }
+
+  @override
+  visitBlock(ir.Block node) {
+    node.visitChildren(this);
+  }
+
+  @override
+  visitStringLiteral(ir.StringLiteral node) {
+    registerNode();
+    // Avoid copying long strings into call site.
+    if (node.value.length > 14) tooDifficultReason ??= 'long string';
+  }
+
+  @override
+  visitPropertyGet(ir.PropertyGet node) {
+    if (!registerCall()) return;
+    if (!registerNode()) return;
+    node.receiver.accept(this);
+  }
+
+  @override
+  visitDirectPropertyGet(ir.DirectPropertyGet node) {
+    if (!registerCall()) return;
+    if (!registerNode()) return;
+    node.receiver.accept(this);
+  }
+
+  @override
+  visitPropertySet(ir.PropertySet node) {
+    if (!registerCall()) return;
+    if (!registerNode()) return;
+    node.receiver.accept(this);
+    node.value.accept(this);
+  }
+
+  @override
+  visitDirectPropertySet(ir.DirectPropertySet node) {
+    if (!registerCall()) return;
+    if (!registerNode()) return;
+    node.receiver.accept(this);
+    node.value.accept(this);
+  }
+
+  @override
+  visitVariableGet(ir.VariableGet node) {
+    registerNode();
+  }
+
+  @override
+  visitThisExpression(ir.ThisExpression node) {
+    registerNode();
+  }
+
+  @override
+  visitStaticGet(ir.StaticGet node) {
+    // Assume lazy-init static, loaded via a call: `$.$get$foo()`.
+    if (!registerCall()) return;
+    registerNode();
+  }
+
+  @override
+  visitConstructorInvocation(ir.ConstructorInvocation node) {
+    if (node.isConst) {
+      // A const constructor call compiles to a constant pool reference.
+      registerNode();
+      return;
+    }
+    if (!registerCall()) return;
+    if (!registerNode()) return;
+    _processArguments(node.arguments, node.target?.function);
+  }
+
+  @override
+  visitStaticInvocation(ir.StaticInvocation node) {
+    if (node.isConst) {
+      tooDifficultReason ??= 'external const constructor';
+      return;
+    }
+    if (!registerCall()) return;
+    if (!registerNode()) return;
+    _processArguments(node.arguments, node.target?.function);
+  }
+
+  @override
+  visitMethodInvocation(ir.MethodInvocation node) {
+    if (!registerCall()) return;
+    if (!registerNode()) return;
+    node.receiver.accept(this);
+    _processArguments(node.arguments, null);
+  }
+
+  _processArguments(ir.Arguments arguments, ir.FunctionNode target) {
+    if (arguments.types.isNotEmpty) {
+      tooDifficultReason ??= 'type arguments';
+      return;
+    }
+    int count = arguments.positional.length + arguments.named.length;
+    if (count > argumentCount) {
+      tooDifficultReason ??= 'increasing arguments';
+      return;
+    }
+
+    if (target != null) {
+      // Disallow defaulted optional arguments since they will be passed
+      // explicitly.
+      if (target.positionalParameters.length + target.namedParameters.length >
+          count) {
+        tooDifficultReason ??= 'argument defaulting';
+        return;
+      }
+    }
+
+    for (var e in arguments.positional) {
+      e.accept(this);
+      if (tooDifficult) return;
+    }
+    for (var e in arguments.named) {
+      e.value.accept(this);
+      if (tooDifficult) return;
+    }
+  }
+
+  @override
+  visitAsExpression(ir.AsExpression node) {
+    if (node.isTypeError && omitImplicitCasts) {
+      node.operand.accept(this);
+      return;
+    }
+    tooDifficultReason ??= 'cast';
+  }
+
+  @override
+  visitVariableDeclaration(ir.VariableDeclaration node) {
+    // A local variable is an alias for the initializer expression.
+    if (node.initializer != null) {
+      --nodeCount; // discount one reference to the variable.
+      node.initializer.accept(this);
+      return;
+    }
+  }
+
+  @override
+  visitForStatement(ir.ForStatement node) {
+    tooDifficultReason ??= 'loop';
+  }
+
+  @override
+  visitForInStatement(ir.ForInStatement node) {
+    tooDifficultReason ??= 'loop';
+  }
+
+  @override
+  visitWhileStatement(ir.WhileStatement node) {
+    tooDifficultReason ??= 'loop';
+  }
+
+  @override
+  visitDoStatement(ir.DoStatement node) {
+    tooDifficultReason ??= 'loop';
+  }
+
+  @override
+  visitTryCatch(ir.TryCatch node) {
+    tooDifficultReason ??= 'try';
+  }
+
+  @override
+  visitTryFinally(ir.TryFinally node) {
+    tooDifficultReason ??= 'try';
+  }
+
+  @override
+  visitIfStatement(ir.IfStatement node) {
+    tooDifficultReason ??= 'if';
+  }
+
+  @override
+  visitFunctionExpression(ir.FunctionExpression node) {
+    tooDifficultReason ??= 'closure';
+  }
+
+  @override
+  visitFunctionDeclaration(ir.FunctionDeclaration node) {
+    tooDifficultReason ??= 'closure';
+  }
+
+  @override
+  visitFunctionNode(ir.FunctionNode node) {
+    if (node.asyncMarker != ir.AsyncMarker.Sync) {
+      tooDifficultReason ??= 'async/await';
+      return;
+    }
+    // TODO(sra): Cost of parameter checking?
+    node.body.accept(this);
+  }
+
+  @override
+  visitConditionalExpression(ir.ConditionalExpression node) {
+    if (!registerNode()) return;
+    node.visitChildren(this);
+  }
+
+  @override
+  visitAssertInitializer(ir.AssertInitializer node) {
+    if (!enableUserAssertions) return;
+    node.visitChildren(this);
+  }
+
+  @override
+  visitAssertStatement(ir.AssertStatement node) {
+    if (!enableUserAssertions) return;
+    defaultNode(node);
+  }
+}
+
 /// Class in charge of building try, catch and/or finally blocks. This handles
 /// the instructions that need to be output and the dominator calculation of
 /// this sequence of code.
@@ -6019,7 +6346,7 @@
 }
 
 class KernelTypeBuilder extends TypeBuilder {
-  KernelToElementMapForBuilding _elementMap;
+  JsToElementMap _elementMap;
   GlobalLocalsMap _globalLocalsMap;
 
   KernelTypeBuilder(
diff --git a/pkg/compiler/lib/src/ssa/codegen_helpers.dart b/pkg/compiler/lib/src/ssa/codegen_helpers.dart
index ca08263..6608085 100644
--- a/pkg/compiler/lib/src/ssa/codegen_helpers.dart
+++ b/pkg/compiler/lib/src/ssa/codegen_helpers.dart
@@ -82,18 +82,36 @@
     return node;
   }
 
+  /// Returns the single JavaScript comparison (`==` or `===`) if that
+  /// implements `identical(left, right)`, or returns `null` if a more complex
+  /// expression is needed.
   String simpleOp(HInstruction left, HInstruction right) {
-    // Returns the single identity comparison (== or ===) or null if a more
-    // complex expression is required.
     AbstractValue leftType = left.instructionType;
     AbstractValue rightType = right.instructionType;
     if (_abstractValueDomain.canBeNull(leftType) &&
         _abstractValueDomain.canBeNull(rightType)) {
-      if (left.isConstantNull() ||
-          right.isConstantNull() ||
-          (left.isPrimitive(_abstractValueDomain) && leftType == rightType)) {
+      // Can't use `===` on Dart `null` since it is implemented by JavaScript
+      // `null` and `undefined`.
+      if (left.isConstantNull() || right.isConstantNull()) {
         return '==';
       }
+      if (_abstractValueDomain.isNumberOrNull(leftType) &&
+          _abstractValueDomain.isNumberOrNull(rightType)) {
+        return '==';
+      }
+      if (_abstractValueDomain.isStringOrNull(leftType) &&
+          _abstractValueDomain.isStringOrNull(rightType)) {
+        return '==';
+      }
+      if (_abstractValueDomain.isBooleanOrNull(leftType) &&
+          _abstractValueDomain.isBooleanOrNull(rightType)) {
+        return '==';
+      }
+
+      // TODO(34439): There are more cases that can compile to `==` without
+      // triggering a conversion in the JavaScript evaluation. `==` will work
+      // for most Dart objects, but we have to ensure neither side can be a
+      // JavaScript Number, String, Symbol or Boolean.
       return null;
     }
     return '===';
diff --git a/pkg/compiler/lib/src/ssa/graph_builder.dart b/pkg/compiler/lib/src/ssa/graph_builder.dart
index 4468833..d004ddb 100644
--- a/pkg/compiler/lib/src/ssa/graph_builder.dart
+++ b/pkg/compiler/lib/src/ssa/graph_builder.dart
@@ -88,8 +88,6 @@
 
   RuntimeTypesEncoder get rtiEncoder => backend.rtiEncoder;
 
-  FunctionInlineCache get inlineCache => backend.inlineCache;
-
   JsInteropAnalysis get jsInteropAnalysis => backend.jsInteropAnalysis;
 
   InferredData get inferredData => globalInferenceResults.inferredData;
diff --git a/pkg/compiler/lib/src/ssa/kernel_impact.dart b/pkg/compiler/lib/src/ssa/kernel_impact.dart
index f55d302..c88565b 100644
--- a/pkg/compiler/lib/src/ssa/kernel_impact.dart
+++ b/pkg/compiler/lib/src/ssa/kernel_impact.dart
@@ -13,6 +13,8 @@
 import '../constants/values.dart';
 import '../elements/entities.dart';
 import '../elements/types.dart';
+import '../ir/util.dart';
+import '../js_backend/native_data.dart';
 import '../kernel/element_map.dart';
 import '../kernel/runtime_type_analysis.dart';
 import '../options.dart';
@@ -25,7 +27,7 @@
 
 ResolutionImpact buildKernelImpact(
     ir.Member member,
-    KernelToElementMapForImpact elementMap,
+    KernelToElementMap elementMap,
     DiagnosticReporter reporter,
     CompilerOptions options) {
   KernelImpactBuilder builder = new KernelImpactBuilder(
@@ -42,7 +44,7 @@
 
 class KernelImpactBuilder extends ir.Visitor {
   final ResolutionWorldImpactBuilder impactBuilder;
-  final KernelToElementMapForImpact elementMap;
+  final KernelToElementMap elementMap;
   final DiagnosticReporter reporter;
   final CompilerOptions _options;
   final MemberEntity currentMember;
@@ -51,12 +53,14 @@
   KernelImpactBuilder(
       this.elementMap, this.currentMember, this.reporter, this._options)
       : this.impactBuilder =
-            new ResolutionWorldImpactBuilder('${currentMember.name}') {
+            new ResolutionWorldImpactBuilder('${currentMember}') {
     this.classEnsurer = new _ClassEnsurer(this, this.elementMap.types);
   }
 
   CommonElements get commonElements => elementMap.commonElements;
 
+  NativeBasicData get _nativeBasicData => elementMap.nativeBasicData;
+
   /// Add a checked-mode type use of [type] if it is not `dynamic`.
   DartType checkType(ir.DartType irType, TypeUseKind kind) {
     DartType type = elementMap.getDartType(irType);
@@ -116,7 +120,7 @@
     if (field.isInstanceMember &&
         elementMap.isNativeClass(field.enclosingClass)) {
       MemberEntity member = elementMap.getMember(field);
-      bool isJsInterop = elementMap.nativeBasicData.isJsInteropMember(member);
+      bool isJsInterop = _nativeBasicData.isJsInteropMember(member);
       impactBuilder.registerNativeData(elementMap
           .getNativeBehaviorForFieldLoad(field, isJsInterop: isJsInterop));
       impactBuilder
@@ -131,7 +135,7 @@
     visitNode(constructor.function.body);
     MemberEntity member = elementMap.getMember(constructor);
     if (constructor.isExternal && !commonElements.isForeignHelper(member)) {
-      bool isJsInterop = elementMap.nativeBasicData.isJsInteropMember(member);
+      bool isJsInterop = _nativeBasicData.isJsInteropMember(member);
       impactBuilder.registerNativeData(elementMap
           .getNativeBehaviorForMethod(constructor, isJsInterop: isJsInterop));
     }
@@ -186,7 +190,7 @@
     handleAsyncMarker(procedure.function);
     MemberEntity member = elementMap.getMember(procedure);
     if (procedure.isExternal && !commonElements.isForeignHelper(member)) {
-      bool isJsInterop = elementMap.nativeBasicData.isJsInteropMember(member);
+      bool isJsInterop = _nativeBasicData.isJsInteropMember(member);
       impactBuilder.registerNativeData(elementMap
           .getNativeBehaviorForMethod(procedure, isJsInterop: isJsInterop));
     }
@@ -316,7 +320,8 @@
         constructor.isFromEnvironmentConstructor &&
         !isConst) {
       impactBuilder.registerFeature(Feature.THROW_UNSUPPORTED_ERROR);
-      return;
+      // We need to register the external constructor as live below, so don't
+      // return here.
     }
 
     InterfaceType type = elementMap.createInterfaceType(
@@ -388,7 +393,7 @@
     } else {
       FunctionEntity target = elementMap.getMethod(node.target);
       List<DartType> typeArguments = _visitArguments(node.arguments);
-      if (target == commonElements.extractTypeArguments) {
+      if (commonElements.isExtractTypeArguments(target)) {
         _handleExtractTypeArguments(node, target, typeArguments);
         return;
       }
@@ -487,14 +492,12 @@
   @override
   void visitDirectMethodInvocation(ir.DirectMethodInvocation node) {
     List<DartType> typeArguments = _visitArguments(node.arguments);
+    MemberEntity member = elementMap.getMember(node.target);
     // TODO(johnniwinther): Restrict the dynamic use to only match the known
     // target.
-    Object constraint;
-    MemberEntity member = elementMap.getMember(node.target);
-    if (useStrongModeWorldStrategy) {
-      // TODO(johnniwinther): Restrict this to subclasses?
-      constraint = new StrongModeConstraint(member.enclosingClass);
-    }
+    // TODO(johnniwinther): Restrict this to subclasses?
+    Object constraint = new StrongModeConstraint(
+        commonElements, _nativeBasicData, member.enclosingClass);
     impactBuilder.registerDynamicUse(new ConstrainedDynamicUse(
         new Selector.call(
             member.memberName, elementMap.getCallStructure(node.arguments)),
@@ -592,28 +595,48 @@
           new ConstrainedDynamicUse(selector, null, typeArguments));
     } else {
       visitNode(node.receiver);
-      Object constraint;
-      if (useStrongModeWorldStrategy) {
-        DartType receiverType = elementMap.getStaticType(node.receiver);
-        if (receiverType is InterfaceType) {
-          constraint = new StrongModeConstraint(receiverType.element);
-        }
-      }
-
-      impactBuilder.registerDynamicUse(
-          new ConstrainedDynamicUse(selector, constraint, typeArguments));
 
       ir.Member interfaceTarget = node.interfaceTarget;
-      if (operatorFromString(node.name.name) == null) {
-        if (interfaceTarget == null ||
-            interfaceTarget is ir.Field ||
-            interfaceTarget is ir.Procedure &&
-                interfaceTarget.kind == ir.ProcedureKind.Getter) {
-          // An `o.foo()` invocation is (potentially) an `o.foo.call()`
-          // invocation.
+      if (interfaceTarget == null) {
+        // TODO(johnniwinther): Avoid treating a known function call as a
+        // dynamic call when CFE provides a way to distinguish the two.
+        impactBuilder.registerDynamicUse(
+            new ConstrainedDynamicUse(selector, null, typeArguments));
+        if (operatorFromString(node.name.name) == null) {
           impactBuilder.registerDynamicUse(new ConstrainedDynamicUse(
               selector.toCallSelector(), null, typeArguments));
         }
+      } else {
+        Object constraint;
+        DartType receiverType = elementMap.getStaticType(node.receiver);
+        if (receiverType is InterfaceType) {
+          constraint = new StrongModeConstraint(
+              commonElements, _nativeBasicData, receiverType.element);
+        }
+
+        if (interfaceTarget is ir.Field ||
+            interfaceTarget is ir.Procedure &&
+                interfaceTarget.kind == ir.ProcedureKind.Getter) {
+          impactBuilder.registerDynamicUse(
+              new ConstrainedDynamicUse(selector, constraint, typeArguments));
+          // An `o.foo()` invocation is (potentially) an `o.foo.call()`
+          // invocation.
+          Object getterConstraint;
+          if (interfaceTarget != null) {
+            DartType receiverType =
+                elementMap.getDartType(interfaceTarget.getterType);
+            if (receiverType is InterfaceType) {
+              getterConstraint = new StrongModeConstraint(
+                  commonElements, _nativeBasicData, receiverType.element);
+            }
+          }
+
+          impactBuilder.registerDynamicUse(new ConstrainedDynamicUse(
+              selector.toCallSelector(), getterConstraint, typeArguments));
+        } else {
+          impactBuilder.registerDynamicUse(
+              new ConstrainedDynamicUse(selector, constraint, typeArguments));
+        }
       }
     }
   }
@@ -622,11 +645,10 @@
   void visitPropertyGet(ir.PropertyGet node) {
     visitNode(node.receiver);
     Object constraint;
-    if (useStrongModeWorldStrategy) {
-      DartType receiverType = elementMap.getStaticType(node.receiver);
-      if (receiverType is InterfaceType) {
-        constraint = new StrongModeConstraint(receiverType.element);
-      }
+    DartType receiverType = elementMap.getStaticType(node.receiver);
+    if (receiverType is InterfaceType) {
+      constraint = new StrongModeConstraint(
+          commonElements, _nativeBasicData, receiverType.element);
     }
     impactBuilder.registerDynamicUse(new ConstrainedDynamicUse(
         new Selector.getter(elementMap.getName(node.name)),
@@ -663,11 +685,10 @@
     visitNode(node.receiver);
     visitNode(node.value);
     Object constraint;
-    if (useStrongModeWorldStrategy) {
-      DartType receiverType = elementMap.getStaticType(node.receiver);
-      if (receiverType is InterfaceType) {
-        constraint = new StrongModeConstraint(receiverType.element);
-      }
+    DartType receiverType = elementMap.getStaticType(node.receiver);
+    if (receiverType is InterfaceType) {
+      constraint = new StrongModeConstraint(
+          commonElements, _nativeBasicData, receiverType.element);
     }
     impactBuilder.registerDynamicUse(new ConstrainedDynamicUse(
         new Selector.setter(elementMap.getName(node.name)),
@@ -799,6 +820,13 @@
   void visitTypeLiteral(ir.TypeLiteral node) {
     impactBuilder.registerTypeUse(
         new TypeUse.typeLiteral(elementMap.getDartType(node.type)));
+    if (node.type is ir.FunctionType) {
+      ir.FunctionType functionType = node.type;
+      assert(functionType.typedef != null);
+      // TODO(johnniwinther): Can we avoid the typedef type altogether?
+      // We need to ensure that the typedef is live.
+      elementMap.getTypedefType(functionType.typedef);
+    }
   }
 
   @override
diff --git a/pkg/compiler/lib/src/ssa/types.dart b/pkg/compiler/lib/src/ssa/types.dart
index c7dd084..39fd61c 100644
--- a/pkg/compiler/lib/src/ssa/types.dart
+++ b/pkg/compiler/lib/src/ssa/types.dart
@@ -64,7 +64,8 @@
 
     AbstractValue result =
         abstractValueDomain.unionOfMany(typesReturned.map(fromNativeType));
-    assert(!abstractValueDomain.isEmpty(result));
+    assert(!abstractValueDomain.isEmpty(result),
+        "Unexpected empty return value for $nativeBehavior.");
     return result;
   }
 }
diff --git a/pkg/compiler/lib/src/types/types.dart b/pkg/compiler/lib/src/types/types.dart
index 83c2bee..497aa27 100644
--- a/pkg/compiler/lib/src/types/types.dart
+++ b/pkg/compiler/lib/src/types/types.dart
@@ -5,7 +5,7 @@
 library types;
 
 import 'package:kernel/ast.dart' as ir;
-import '../common.dart' show failedAt;
+import '../common.dart' show failedAt, retainDataForTesting;
 import '../common/names.dart';
 import '../common/tasks.dart' show CompilerTask;
 import '../compiler.dart' show Compiler;
@@ -149,7 +149,9 @@
         results = typesInferrerInternal.analyzeMain(mainElement);
       }
       closedWorld.noSuchMethodData.categorizeComplexImplementations(results);
-      resultsForTesting = results;
+      if (retainDataForTesting) {
+        resultsForTesting = results;
+      }
       return results;
     });
   }
diff --git a/pkg/compiler/lib/src/universe/class_hierarchy.dart b/pkg/compiler/lib/src/universe/class_hierarchy.dart
index cc91490..c351f1e 100644
--- a/pkg/compiler/lib/src/universe/class_hierarchy.dart
+++ b/pkg/compiler/lib/src/universe/class_hierarchy.dart
@@ -625,32 +625,112 @@
     return classSet.hasSubtype(classHierarchyNode);
   }
 
+  Map<ClassEntity, _InheritedCache> _inheritedCacheMap = {};
+
   bool isInheritedInSubtypeOf(ClassEntity x, ClassEntity y) {
-    ClassSet classSet = classSets[x];
-    assert(classSet != null,
-        failedAt(x, "No ClassSet for $x (${x.runtimeType}): ${classSets}"));
+    _InheritedCache cache = _inheritedCacheMap[x] ??= new _InheritedCache();
+    return cache.isInheritedInSubtypeOf(this, x, y);
+  }
+}
 
-    if (_isSubtypeOf(x, y)) {
+/// A cache object used for [ClassHierarchyBuilder.isInheritedInSubtypeOf].
+class _InheritedCache {
+  Map<ClassEntity, _InheritingSet> _map;
+
+  /// Returns whether a live class currently known to inherit from [x] and
+  /// implement [y].
+  bool isInheritedInSubtypeOf(
+      ClassHierarchyBuilder builder, ClassEntity x, ClassEntity y) {
+    _InheritingSet set;
+    if (_map == null) {
+      _map = {};
+    } else {
+      set = _map[y];
+    }
+    if (set == null) {
+      set = _map[y] = _computeInheritingSet(builder, x, y);
+    }
+    return set.hasLiveClass(builder);
+  }
+
+  /// Creates an [_InheritingSet] of classes that inherit members of a class [x]
+  /// while implementing class [y].
+  _InheritingSet _computeInheritingSet(
+      ClassHierarchyBuilder builder, ClassEntity x, ClassEntity y) {
+    ClassSet classSet = builder.classSets[x];
+
+    assert(
+        classSet != null,
+        failedAt(
+            x, "No ClassSet for $x (${x.runtimeType}): ${builder.classSets}"));
+
+    Set<ClassEntity> classes = new Set<ClassEntity>();
+
+    if (builder._isSubtypeOf(x, y)) {
       // [x] implements [y] itself, possible through supertypes.
-      return true;
+      classes.add(x);
     }
 
-    /// Returns `true` if any live subclass of [node] implements [y].
-    bool subclassImplements(ClassHierarchyNode node, {bool strict}) {
-      return node.anySubclass((ClassEntity z) => _isSubtypeOf(z, y),
-          ClassHierarchyNode.INSTANTIATED,
-          strict: strict);
+    /// Add subclasses of [node] that implement [y].
+    void subclassImplements(ClassHierarchyNode node, {bool strict}) {
+      node.forEachSubclass((ClassEntity z) {
+        if (builder._isSubtypeOf(z, y)) {
+          classes.add(z);
+        }
+      }, ClassHierarchyNode.ALL, strict: strict);
     }
 
-    if (subclassImplements(classSet.node, strict: true)) {
-      // A subclass of [x] implements [y].
-      return true;
-    }
+    // A subclasses of [x] that implement [y].
+    subclassImplements(classSet.node, strict: true);
 
     for (ClassHierarchyNode mixinApplication
         in classSet.mixinApplicationNodes) {
-      if (subclassImplements(mixinApplication, strict: false)) {
-        // A subclass of [mixinApplication] implements [y].
+      // A subclass of [mixinApplication] implements [y].
+      subclassImplements(mixinApplication, strict: false);
+    }
+
+    return new _InheritingSet(classes);
+  }
+}
+
+/// A set of classes that inherit members of a class 'x' while implementing
+/// class 'y'.
+///
+/// The set is used [ClassHierarchyBuilder.isInheritedInSubtypeOf] to determine
+/// when members of a class is live.
+class _InheritingSet {
+  /// If `true` the set of classes is known to contain a live class. In this
+  /// case [_classes] is `null`. If `false` the set of classes is empty and
+  /// therefore known never to contain live classes. In this case [_classes]
+  /// is `null`. If `null` [_classes] is a non-empty set containing classes
+  /// that are not yet known to be live.
+  bool _result;
+  Set<ClassEntity> _classes;
+
+  _InheritingSet(Set<ClassEntity> classes)
+      : _result = classes.isEmpty ? false : null,
+        _classes = classes.isNotEmpty ? classes : null;
+
+  /// Returns whether the set of classes is currently known to contain a live
+  /// classes.
+  ///
+  /// The result of this method changes during the closed world computation.
+  /// Initially, we haven't seen any live classes so we will return `false` even
+  /// for a non-empty set of classes. As more classes are marked as
+  /// instantiated, during tree-shaking, the result might change to `true` if
+  /// one of the [_classes] has been marked as live.
+  ///
+  /// The result of this method _is_ monotone, though; when we have returned
+  /// `true` (because at least one class is known to be live) we will continue
+  /// to return `true`.
+  bool hasLiveClass(ClassHierarchyBuilder builder) {
+    if (_result != null) return _result;
+    for (ClassEntity cls in _classes) {
+      if (builder.classHierarchyNodes[cls].isInstantiated) {
+        // We now know this set contains a live class and done need to remember
+        // that set of classes anymore.
+        _result = true;
+        _classes = null;
         return true;
       }
     }
diff --git a/pkg/compiler/lib/src/universe/resolution_world_builder.dart b/pkg/compiler/lib/src/universe/resolution_world_builder.dart
index 3b77119..b203dc9 100644
--- a/pkg/compiler/lib/src/universe/resolution_world_builder.dart
+++ b/pkg/compiler/lib/src/universe/resolution_world_builder.dart
@@ -390,7 +390,7 @@
 
   bool get isClosed => _closed;
 
-  final KernelToElementMapForImpactImpl _elementMap;
+  final KernelToElementMapImpl _elementMap;
 
   ResolutionWorldBuilderImpl(
       this._options,
@@ -851,7 +851,7 @@
       memberUsed(usage.entity, useSet);
       return usage;
     });
-    if (!newUsage) {
+    if (!usage.fullyUsed && !newUsage) {
       EnumSet<MemberUse> useSet = new EnumSet<MemberUse>();
       if (!usage.hasRead && _hasInvokedGetter(member)) {
         useSet.addAll(usage.read());
@@ -945,8 +945,6 @@
   bool isInheritedInSubtypeOf(MemberEntity member, ClassEntity type) {
     // TODO(johnniwinther): Use the [member] itself to avoid enqueueing members
     // that are overridden.
-    _classHierarchyBuilder.registerClass(member.enclosingClass);
-    _classHierarchyBuilder.registerClass(type);
     return _classHierarchyBuilder.isInheritedInSubtypeOf(
         member.enclosingClass, type);
   }
@@ -968,16 +966,11 @@
   }
 
   @override
-  KClosedWorld closeWorld() {
+  KClosedWorld closeWorld(DiagnosticReporter reporter) {
     Map<ClassEntity, Set<ClassEntity>> typesImplementedBySubclasses =
         populateHierarchyNodes();
 
-    var backendUsage = _backendUsageBuilder.close();
-    backendUsage.helperClassesUsed
-        .forEach(_classHierarchyBuilder.registerClass);
-    _nativeResolutionEnqueuer.liveNativeClasses
-        .forEach(_classHierarchyBuilder.registerClass);
-
+    BackendUsage backendUsage = _backendUsageBuilder.close();
     _closed = true;
     assert(
         _classHierarchyBuilder.classHierarchyNodes.length ==
@@ -985,14 +978,18 @@
         "ClassHierarchyNode/ClassSet mismatch: "
         "${_classHierarchyBuilder.classHierarchyNodes} vs "
         "${_classHierarchyBuilder.classSets}");
-    return _closedWorldCache = new KClosedWorldImpl(_elementMap,
+
+    AnnotationsData annotationsData = processAnnotations(
+        reporter, _commonElements, _elementEnvironment, _processedMembers);
+
+    KClosedWorld closedWorld = new KClosedWorldImpl(_elementMap,
         options: _options,
         elementEnvironment: _elementEnvironment,
         dartTypes: _dartTypes,
         commonElements: _commonElements,
         nativeData: _nativeDataBuilder.close(),
         interceptorData: _interceptorDataBuilder.close(),
-        backendUsage: _backendUsageBuilder.close(),
+        backendUsage: backendUsage,
         noSuchMethodData: _noSuchMethodRegistry.close(),
         resolutionWorldBuilder: this,
         rtiNeedBuilder: _rtiNeedBuilder,
@@ -1005,7 +1002,12 @@
         mixinUses: _classHierarchyBuilder.mixinUses,
         typesImplementedBySubclasses: typesImplementedBySubclasses,
         classHierarchyNodes: _classHierarchyBuilder.classHierarchyNodes,
-        classSets: _classHierarchyBuilder.classSets);
+        classSets: _classHierarchyBuilder.classSets,
+        annotationsData: annotationsData);
+    if (retainDataForTesting) {
+      _closedWorldCache = closedWorld;
+    }
+    return closedWorld;
   }
 
   @override
diff --git a/pkg/compiler/lib/src/universe/use.dart b/pkg/compiler/lib/src/universe/use.dart
index c573eb7..3b2239c 100644
--- a/pkg/compiler/lib/src/universe/use.dart
+++ b/pkg/compiler/lib/src/universe/use.dart
@@ -24,6 +24,7 @@
 import '../util/util.dart' show equalElements, Hashing;
 import 'call_structure.dart' show CallStructure;
 import 'selector.dart' show Selector;
+import 'world_builder.dart' show StrongModeConstraint;
 
 enum DynamicUseKind {
   INVOKE,
@@ -42,6 +43,15 @@
   /// Short textual representation use for testing.
   String get shortText {
     StringBuffer sb = new StringBuffer();
+    if (receiverConstraint != null) {
+      var constraint = receiverConstraint;
+      if (constraint is StrongModeConstraint) {
+        sb.write(constraint.cls.name);
+      } else {
+        sb.write(constraint);
+      }
+      sb.write('.');
+    }
     sb.write(selector.name);
     if (typeArguments != null && typeArguments.isNotEmpty) {
       sb.write('<');
diff --git a/pkg/compiler/lib/src/universe/world_builder.dart b/pkg/compiler/lib/src/universe/world_builder.dart
index 2417fd3..84aa6d3 100644
--- a/pkg/compiler/lib/src/universe/world_builder.dart
+++ b/pkg/compiler/lib/src/universe/world_builder.dart
@@ -12,13 +12,16 @@
 import '../constants/values.dart';
 import '../elements/entities.dart';
 import '../elements/types.dart';
+import '../js_backend/annotations.dart';
 import '../js_backend/allocator_analysis.dart' show KAllocatorAnalysis;
-import '../js_backend/backend_usage.dart' show BackendUsageBuilder;
+import '../js_backend/backend_usage.dart'
+    show BackendUsage, BackendUsageBuilder;
 import '../js_backend/interceptor_data.dart' show InterceptorDataBuilder;
 import '../js_backend/native_data.dart' show NativeBasicData, NativeDataBuilder;
 import '../js_backend/no_such_method_registry.dart';
 import '../js_backend/runtime_types.dart';
 import '../js_model/locals.dart';
+import '../js_model/element_map_impl.dart';
 import '../js_model/elements.dart' show JSignatureMethod;
 import '../kernel/element_map_impl.dart';
 import '../kernel/kelements.dart';
@@ -112,47 +115,6 @@
   bool appliedUnnamed(DynamicUse dynamicUse, MemberEntity member, World world);
 }
 
-class OpenWorldStrategy implements SelectorConstraintsStrategy {
-  const OpenWorldStrategy();
-
-  OpenWorldConstraints createSelectorConstraints(Selector selector) {
-    return new OpenWorldConstraints();
-  }
-
-  @override
-  bool appliedUnnamed(DynamicUse dynamicUse, MemberEntity member, World world) {
-    Selector selector = dynamicUse.selector;
-    return selector.appliesUnnamed(member);
-  }
-}
-
-class OpenWorldConstraints extends UniverseSelectorConstraints {
-  bool isAll = false;
-
-  @override
-  bool applies(MemberEntity element, Selector selector, World world) => isAll;
-
-  @override
-  bool needsNoSuchMethodHandling(Selector selector, World world) => isAll;
-
-  @override
-  bool addReceiverConstraint(Object constraint) {
-    if (isAll) return false;
-    isAll = true;
-    return true;
-  }
-
-  String toString() {
-    if (isAll) {
-      return '<all>';
-    } else {
-      return '<none>';
-    }
-  }
-}
-
-bool useStrongModeWorldStrategy = false;
-
 /// Open world strategy that constrains instance member access to subtypes of
 /// the static type of the receiver.
 ///
@@ -231,7 +193,17 @@
 class StrongModeConstraint {
   final ClassEntity cls;
 
-  const StrongModeConstraint(this.cls);
+  factory StrongModeConstraint(CommonElements commonElements,
+      NativeBasicData nativeBasicData, ClassEntity cls) {
+    if (nativeBasicData.isJsInteropClass(cls)) {
+      // We can not tell js-interop classes apart, so we just assume the
+      // receiver could be any js-interop class.
+      cls = commonElements.jsJavaScriptObjectClass;
+    }
+    return new StrongModeConstraint.internal(cls);
+  }
+
+  const StrongModeConstraint.internal(this.cls);
 
   bool needsNoSuchMethodHandling(Selector selector, World world) => true;
 
diff --git a/pkg/compiler/lib/src/world.dart b/pkg/compiler/lib/src/world.dart
index 3fa6e2e..9685e13 100644
--- a/pkg/compiler/lib/src/world.dart
+++ b/pkg/compiler/lib/src/world.dart
@@ -10,8 +10,10 @@
 import 'common/names.dart';
 import 'common_elements.dart' show CommonElements, ElementEnvironment;
 import 'constants/constant_system.dart';
+import 'diagnostics/diagnostic_listener.dart';
 import 'elements/entities.dart';
 import 'elements/types.dart';
+import 'js_backend/annotations.dart';
 import 'js_backend/allocator_analysis.dart'
     show JAllocatorAnalysis, KAllocatorAnalysis;
 import 'js_backend/backend_usage.dart' show BackendUsage;
@@ -71,6 +73,8 @@
 
   ClassHierarchy get classHierarchy;
 
+  AnnotationsData get annotationsData;
+
   /// Returns `true` if [cls] is implemented by an instantiated class.
   bool isImplemented(ClassEntity cls);
 
@@ -198,7 +202,7 @@
 abstract class OpenWorld implements World {
   void registerUsedElement(MemberEntity element);
 
-  KClosedWorld closeWorld();
+  KClosedWorld closeWorld(DiagnosticReporter reporter);
 
   /// Returns an iterable over all mixin applications that mixin [cls].
   Iterable<ClassEntity> allMixinUsesOf(ClassEntity cls);
@@ -631,4 +635,6 @@
   Iterable<MemberEntity> get processedMembers;
   RuntimeTypesNeed get rtiNeed;
   NoSuchMethodData get noSuchMethodData;
+
+  AnnotationsData get annotationsData;
 }
diff --git a/pkg/dart_messages/analysis_options.yaml b/pkg/dart_messages/analysis_options.yaml
deleted file mode 100644
index a10d4c5..0000000
--- a/pkg/dart_messages/analysis_options.yaml
+++ /dev/null
@@ -1,2 +0,0 @@
-analyzer:
-  strong-mode: true
diff --git a/pkg/dart_messages/bin/message_id.dart b/pkg/dart_messages/bin/message_id.dart
deleted file mode 100644
index a708e60..0000000
--- a/pkg/dart_messages/bin/message_id.dart
+++ /dev/null
@@ -1,35 +0,0 @@
-// 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.
-
-import 'dart:math' as math;
-
-import 'package:dart_messages/shared_messages.dart' as shared_messages;
-
-math.Random random = new math.Random();
-
-const idLength = 6;
-final $A = "A".codeUnitAt(0);
-final $Z = "Z".codeUnitAt(0);
-
-String computeId() {
-  List<int> charCodes = [];
-  for (int i = 0; i < idLength; i++) {
-    charCodes.add($A + random.nextInt($Z - $A));
-  }
-  return new String.fromCharCodes(charCodes);
-}
-
-/// Computes a random message ID that hasn't been used before.
-void main() {
-  var usedIds =
-      shared_messages.MESSAGES.values.map((entry) => entry.id).toSet();
-
-  print("${usedIds.length} existing ids");
-
-  var newId;
-  do {
-    newId = computeId();
-  } while (usedIds.contains(newId));
-  print("Available id: $newId");
-}
diff --git a/pkg/dart_messages/bin/publish.dart b/pkg/dart_messages/bin/publish.dart
deleted file mode 100644
index 60bc818..0000000
--- a/pkg/dart_messages/bin/publish.dart
+++ /dev/null
@@ -1,251 +0,0 @@
-// 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.
-
-import 'dart:convert';
-import 'dart:io' as io;
-
-import 'package:dart_messages/shared_messages.dart';
-
-const String jsonPath = '../lib/generated/shared_messages.json';
-const String dart2jsPath =
-    '../../compiler/lib/src/diagnostics/generated/shared_messages.dart';
-const String analyzerPath =
-    '../../analyzer/lib/src/generated/generated/shared_messages.dart';
-
-final String dontEditWarning = """
-/*
-DON'T EDIT. GENERATED. DON'T EDIT.
-This file has been generated by 'publish.dart' in the dart_messages package.
-
-Messages are maintained in `lib/shared_messages.dart` of that same package.
-After any change to that file, run `bin/publish.dart` to generate a new version
-of the json, dart2js and analyzer representations.
-*/""";
-
-const String copyrightHeader = '''
-// 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.''';
-
-void markAsReadonly(String path) {
-  // TODO(15078): mark as read-only. Currently not possible:
-  // http://dartbug.com/15078.
-}
-
-void emitJson() {
-  var input = MESSAGES;
-  var outPath = io.Platform.script.resolve(jsonPath).toFilePath();
-  print("Emitting JSON:");
-  print("  Input: ${input.length} entries");
-  print("  Output: $outPath");
-  new io.File(outPath).writeAsStringSync(messagesAsJson);
-  print("Emitting JSON done.");
-}
-
-/// Escapes the given string [str].
-///
-/// The parameter [str] may be `null` in which case the result is "null".
-String escapeString(String str) {
-  return jsonEncode(str);
-}
-
-/// Emits the messages in dart2js format.
-///
-/// The dart2js-format consists of two entities:
-///   1. the `MessageKind` enum, and
-///   2. the MessageKind-to-Template map `TEMPLATES`.
-///
-/// The template is an instance of MessageTemplate:
-///
-///     const MessageTemplate(
-///        this.kind,
-///        this.template,
-///        {this.howToFix,
-///         this.examples,
-///         this.options: const <String>[]});
-///
-/// A sample output thus looks as follows:
-///
-///     enum MessageKind {
-///       EXAMPLE_MESSAGE,
-///     }
-///
-///     const Map<MessageKind, MessageTemplate> {
-///       EXAMPLE_MESSAGE: const MessageTemplate(
-///         EXAMPLE_MESSAGE,
-///         "Don't use #foo with #bar",
-///         howToFix: "Just don't do it",
-///         options: const ['--some-flag']),
-///         examples: const ['''
-///     some example with bad code;'''],
-///     };
-void emitDart2js() {
-  var input = MESSAGES;
-  var outPath = io.Platform.script.resolve(dart2jsPath).toFilePath();
-  print("Emitting dart2js:");
-  print("  Input: ${input.length} entries");
-  print("  Output: $outPath");
-
-  StringBuffer out = new StringBuffer();
-  out.writeln(copyrightHeader);
-  out.writeln(dontEditWarning);
-  out.writeln("import '../messages.dart' show MessageKind, MessageTemplate;");
-  out.writeln();
-  out.writeln("const Map<MessageKind, MessageTemplate> TEMPLATES = "
-      "const <MessageKind, MessageTemplate>{ ");
-  input.forEach((name, message) {
-    if (!message.usedBy.contains(Platform.dart2js)) return;
-
-    out.writeln("  MessageKind.$name: const MessageTemplate(");
-    // TODO(floitsch): include id.
-    out.writeln("    MessageKind.$name,");
-    out.write("    ");
-    out.write(escapeString(message.template));
-    if (message.howToFix != null) {
-      out.write(",\n    howToFix: ${escapeString(message.howToFix)}");
-    }
-    if (message.options != null) {
-      out.write(",\n    options: const [");
-      out.write(message.options.map(escapeString).join(","));
-      out.writeln("]");
-    }
-    if (message.examples != null) {
-      out.writeln(",\n    examples: const [");
-
-      String escapeExampleContent(String content) {
-        if (content.contains("\n") || content.contains('"')) {
-          return 'r"""\n$content"""';
-        } else if (content.contains("\\")) {
-          return 'r"$content"';
-        }
-        return '"$content"';
-      }
-
-      for (var example in message.examples) {
-        if (example is String) {
-          out.write("      ");
-          out.write(escapeExampleContent(example));
-        } else if (example is Map) {
-          out.writeln("      const {");
-          example.forEach((fileName, content) {
-            out.writeln("      '$fileName': ");
-            out.write(escapeExampleContent(content));
-            out.writeln(",");
-          });
-          out.write("      }");
-        }
-        out.writeln(",");
-      }
-      out.writeln("    ]");
-    }
-    out.writeln("  ),  // Generated. Don't edit.");
-  });
-  out.writeln("};");
-
-  new io.File(outPath).writeAsStringSync(out.toString());
-  print("Emitting dart2js done.");
-}
-
-String convertToAnalyzerTemplate(String template, holeOrder) {
-  var holeMap;
-  if (holeOrder != null) {
-    holeMap = {};
-    for (int i = 0; i < holeOrder.length; i++) {
-      holeMap[holeOrder[i]] = i;
-    }
-  }
-  int seenHoles = 0;
-  return template.replaceAllMapped(new RegExp(r"#\w+|#{\w+}"), (Match match) {
-    if (holeMap != null) {
-      String matchedString = match[0];
-      String holeName = matchedString.startsWith("#{")
-          ? matchedString.substring(2, matchedString.length - 1)
-          : matchedString.substring(1);
-      int index = holeMap[holeName];
-      if (index == null) {
-        throw "Couldn't find hole-position for $holeName $holeMap";
-      }
-      return "{$index}";
-    } else {
-      return "{${seenHoles++}}";
-    }
-  });
-}
-
-String camlToAllCaps(String input) {
-  StringBuffer out = new StringBuffer();
-  for (int i = 0; i < input.length; i++) {
-    String c = input[i];
-    if (c.toUpperCase() == c) {
-      out.write("_$c");
-    } else {
-      out.write(c.toUpperCase());
-    }
-  }
-  return out.toString();
-}
-
-/// Emits the messages in analyzer format.
-///
-/// Messages are encoded as instances of `ErrorCode` classes where the
-/// corresponding class is given by the `category` field of the Message.
-///
-/// All instances are stored as top-level const variables.
-///
-/// A sample output looks as follows:
-///
-///     const FooCategoryErrorCode EXAMPLE_MESSAGE = const FooCategoryErrorCode(
-///         "EXAMPLE_MESSAGE",
-///         "Don't use {0} with {1}",
-///         "Just don't do it");
-void emitAnalyzer() {
-  var input = MESSAGES;
-  var outPath = io.Platform.script.resolve(analyzerPath).toFilePath();
-  print("Emitting analyzer:");
-  print("  Input: ${input.length} entries");
-  print("  Output: $outPath");
-
-  StringBuffer out = new StringBuffer();
-  out.writeln(copyrightHeader);
-  out.writeln(dontEditWarning);
-  out.writeln("import 'package:analyzer/src/generated/error.dart';");
-  out.writeln("import 'package:analyzer/src/generated/parser.dart' "
-      "show ParserErrorCode;");
-  input.forEach((name, message) {
-    if (!message.usedBy.contains(Platform.analyzer)) return;
-    List<Category> categories = message.categories;
-    bool hasMultipleCategories = categories.length != 1;
-    for (Category category in categories) {
-      String className = category.name + "Code";
-      String analyzerName =
-          hasMultipleCategories ? "$name${camlToAllCaps(category.name)}" : name;
-      out.writeln();
-      out.writeln("const $className $analyzerName = const $className(");
-      out.writeln("    '$name',");
-
-      String template = message.template;
-      List holeOrder = message.templateHoleOrder;
-      String analyzerTemplate = convertToAnalyzerTemplate(template, holeOrder);
-      out.write("    ");
-      out.write(escapeString(analyzerTemplate));
-      out.write(",\n    ");
-      out.write(escapeString(message.howToFix));
-      out.writeln(");  // Generated. Don't edit.");
-    }
-  });
-
-  new io.File(outPath).writeAsStringSync(out.toString());
-  print("Emitting analyzer done.");
-}
-
-/// Translates the shared messages in `../lib/shared_messages.dart` to JSON,
-/// dart2js, and analyzer formats.
-///
-/// Emits the json-output to [jsonPath], the dart2js-output to [dart2jsPath],
-/// and the analyzer-output to [analyzerPath].
-void main() {
-  emitJson();
-  emitDart2js();
-  emitAnalyzer();
-}
diff --git a/pkg/dart_messages/lib/generated/shared_messages.json b/pkg/dart_messages/lib/generated/shared_messages.json
deleted file mode 100644
index d0e6532..0000000
--- a/pkg/dart_messages/lib/generated/shared_messages.json
+++ /dev/null
@@ -1,687 +0,0 @@
-{
-  "exampleMessage": {
-    "id": "use an Id generated by bin/message_id.dart",
-    "subId": 0,
-    "categories": [
-      "AnalysisOptionsError"
-    ],
-    "template": "#use #named #arguments",
-    "templateHoleOrder": [
-      "arguments",
-      "named",
-      "use"
-    ],
-    "howToFix": "an explanation on how to fix things",
-    "options": null,
-    "usedBy": [],
-    "examples": [
-      "      Some multiline example;\n      That generates the bug.",
-      {
-        "fileA.dart": "        or a map from file to content.\n        again multiline",
-        "fileB.dart": "        with possibly multiple files.\n        muliline too"
-      }
-    ]
-  },
-  "CONST_CONSTRUCTOR_WITH_BODY": {
-    "id": "LGJGHW",
-    "subId": 0,
-    "categories": [
-      "ParserError"
-    ],
-    "template": "Const constructor can't have a body.",
-    "templateHoleOrder": null,
-    "howToFix": "Try removing the 'const' keyword or the body.",
-    "options": null,
-    "usedBy": [
-      "Platform.analyzer",
-      "Platform.dart2js"
-    ],
-    "examples": [
-      "         class C {\n           const C() {}\n         }\n\n         main() => new C();"
-    ]
-  },
-  "CONST_FACTORY": {
-    "id": "LGJGHW",
-    "subId": 1,
-    "categories": [
-      "ParserError"
-    ],
-    "template": "Only redirecting factory constructors can be declared to be 'const'.",
-    "templateHoleOrder": null,
-    "howToFix": "Try removing the 'const' keyword or replacing the body with '=' followed by a valid target.",
-    "options": null,
-    "usedBy": [
-      "Platform.analyzer",
-      "Platform.dart2js"
-    ],
-    "examples": [
-      "         class C {\n           const factory C() {}\n         }\n\n         main() => new C();"
-    ]
-  },
-  "EXTRANEOUS_MODIFIER": {
-    "id": "GRKIQE",
-    "subId": 0,
-    "categories": [
-      "ParserError"
-    ],
-    "template": "Can't have modifier '#{modifier}' here.",
-    "templateHoleOrder": null,
-    "howToFix": "Try removing '#{modifier}'.",
-    "options": null,
-    "usedBy": [
-      "Platform.dart2js"
-    ],
-    "examples": [
-      "var String foo; main(){}",
-      "var set foo; main(){}",
-      "var final foo; main(){}",
-      "var var foo; main(){}",
-      "var const foo; main(){}",
-      "var abstract foo; main(){}",
-      "var static foo; main(){}",
-      "var external foo; main(){}",
-      "final var foo; main(){}",
-      "var var foo; main(){}",
-      "const var foo; main(){}",
-      "abstract var foo; main(){}",
-      "static var foo; main(){}",
-      "external var foo; main(){}"
-    ]
-  },
-  "EXTRANEOUS_MODIFIER_REPLACE": {
-    "id": "GRKIQE",
-    "subId": 1,
-    "categories": [
-      "ParserError"
-    ],
-    "template": "Can't have modifier '#{modifier}' here.",
-    "templateHoleOrder": null,
-    "howToFix": "Try replacing modifier '#{modifier}' with 'var', 'final', or a type.",
-    "options": null,
-    "usedBy": [
-      "Platform.dart2js"
-    ],
-    "examples": [
-      "set foo; main(){}",
-      "abstract foo; main(){}",
-      "static foo; main(){}",
-      "external foo; main(){}"
-    ]
-  },
-  "CONST_CLASS": {
-    "id": "GRKIQE",
-    "subId": 2,
-    "categories": [
-      "ParserError"
-    ],
-    "template": "Classes can't be declared to be 'const'.",
-    "templateHoleOrder": null,
-    "howToFix": "Try removing the 'const' keyword or moving to the class' constructor(s).",
-    "options": null,
-    "usedBy": [
-      "Platform.analyzer"
-    ],
-    "examples": [
-      "        const class C {}\n\n        main() => new C();\n        "
-    ]
-  },
-  "CONST_METHOD": {
-    "id": "GRKIQE",
-    "subId": 3,
-    "categories": [
-      "ParserError"
-    ],
-    "template": "Getters, setters and methods can't be declared to be 'const'.",
-    "templateHoleOrder": null,
-    "howToFix": "Try removing the 'const' keyword.",
-    "options": null,
-    "usedBy": [
-      "Platform.analyzer"
-    ],
-    "examples": [
-      "const int foo() => 499; main() {}",
-      "const int get foo => 499; main() {}",
-      "const set foo(v) => 499; main() {}",
-      "class A { const int foo() => 499; } main() { new A(); }",
-      "class A { const int get foo => 499; } main() { new A(); }",
-      "class A { const set foo(v) => 499; } main() { new A(); }"
-    ]
-  },
-  "CONST_ENUM": {
-    "id": "GRKIQE",
-    "subId": 4,
-    "categories": [
-      "ParserError"
-    ],
-    "template": "Enums can't be declared to be 'const'.",
-    "templateHoleOrder": null,
-    "howToFix": "Try removing the 'const' keyword.",
-    "options": null,
-    "usedBy": [
-      "Platform.analyzer"
-    ],
-    "examples": [
-      "const enum Foo { x } main() {}"
-    ]
-  },
-  "CONST_TYPEDEF": {
-    "id": "GRKIQE",
-    "subId": 5,
-    "categories": [
-      "ParserError"
-    ],
-    "template": "Type aliases can't be declared to be 'const'.",
-    "templateHoleOrder": null,
-    "howToFix": "Try removing the 'const' keyword.",
-    "options": null,
-    "usedBy": [
-      "Platform.analyzer"
-    ],
-    "examples": [
-      "const typedef void Foo(); main() {}"
-    ]
-  },
-  "CONST_AND_FINAL": {
-    "id": "GRKIQE",
-    "subId": 6,
-    "categories": [
-      "ParserError"
-    ],
-    "template": "Members can't be declared to be both 'const' and 'final'.",
-    "templateHoleOrder": null,
-    "howToFix": "Try removing either the 'const' or 'final' keyword.",
-    "options": null,
-    "usedBy": [
-      "Platform.analyzer"
-    ],
-    "examples": [
-      "final const int x = 499; main() {}",
-      "const final int x = 499; main() {}",
-      "class A { static final const int x = 499; } main() {}",
-      "class A { static const final int x = 499; } main() {}"
-    ]
-  },
-  "CONST_AND_VAR": {
-    "id": "GRKIQE",
-    "subId": 7,
-    "categories": [
-      "ParserError"
-    ],
-    "template": "Members can't be declared to be both 'const' and 'var'.",
-    "templateHoleOrder": null,
-    "howToFix": "Try removing either the 'const' or 'var' keyword.",
-    "options": null,
-    "usedBy": [
-      "Platform.analyzer"
-    ],
-    "examples": [
-      "var const x = 499; main() {}",
-      "const var x = 499; main() {}",
-      "class A { var const x = 499; } main() {}",
-      "class A { const var x = 499; } main() {}"
-    ]
-  },
-  "CLASS_IN_CLASS": {
-    "id": "DOTHQH",
-    "subId": 0,
-    "categories": [
-      "ParserError"
-    ],
-    "template": "Classes can't be declared inside other classes.",
-    "templateHoleOrder": null,
-    "howToFix": "Try moving the class to the top-level.",
-    "options": null,
-    "usedBy": [
-      "Platform.analyzer"
-    ],
-    "examples": [
-      "class A { class B {} } main() { new A(); }"
-    ]
-  },
-  "CONSTRUCTOR_WITH_RETURN_TYPE": {
-    "id": "VOJBWY",
-    "subId": 0,
-    "categories": [
-      "ParserError"
-    ],
-    "template": "Constructors can't have a return type.",
-    "templateHoleOrder": null,
-    "howToFix": "Try removing the return type.",
-    "options": null,
-    "usedBy": [
-      "Platform.analyzer",
-      "Platform.dart2js"
-    ],
-    "examples": [
-      "class A { int A() {} } main() { new A(); }"
-    ]
-  },
-  "MISSING_EXPRESSION_IN_THROW": {
-    "id": "FTGGMJ",
-    "subId": 0,
-    "categories": [
-      "ParserError"
-    ],
-    "template": "Missing expression after 'throw'.",
-    "templateHoleOrder": null,
-    "howToFix": "Did you mean 'rethrow'?",
-    "options": null,
-    "usedBy": [
-      "Platform.analyzer",
-      "Platform.dart2js"
-    ],
-    "examples": [
-      "main() { throw; }",
-      "main() { try { throw 0; } catch(e) { throw; } }"
-    ]
-  },
-  "RETHROW_OUTSIDE_CATCH": {
-    "id": "MWETLC",
-    "subId": 0,
-    "categories": [
-      "CompileTimeError"
-    ],
-    "template": "Rethrow must be inside of catch clause.",
-    "templateHoleOrder": null,
-    "howToFix": "Try moving the expression into a catch clause, or using a 'throw' expression.",
-    "options": null,
-    "usedBy": [
-      "Platform.analyzer",
-      "Platform.dart2js"
-    ],
-    "examples": [
-      "main() { rethrow; }"
-    ]
-  },
-  "RETURN_IN_GENERATIVE_CONSTRUCTOR": {
-    "id": "UOTDQH",
-    "subId": 0,
-    "categories": [
-      "CompileTimeError"
-    ],
-    "template": "Constructors can't return values.",
-    "templateHoleOrder": null,
-    "howToFix": "Try removing the return statement or using a factory constructor.",
-    "options": null,
-    "usedBy": [
-      "Platform.analyzer",
-      "Platform.dart2js"
-    ],
-    "examples": [
-      "        class C {\n          C() {\n            return 1;\n          }\n        }\n\n        main() => new C();"
-    ]
-  },
-  "RETURN_IN_GENERATOR": {
-    "id": "JRUTUQ",
-    "subId": 0,
-    "categories": [
-      "CompileTimeError"
-    ],
-    "template": "Can't return a value from a generator function (using the '#{modifier}' modifier).",
-    "templateHoleOrder": null,
-    "howToFix": "Try removing the value, replacing 'return' with 'yield' or changing the method body modifier.",
-    "options": null,
-    "usedBy": [
-      "Platform.analyzer",
-      "Platform.dart2js"
-    ],
-    "examples": [
-      "        foo() async* { return 0; }\n        main() => foo();\n        ",
-      "        foo() sync* { return 0; }\n        main() => foo();\n        "
-    ]
-  },
-  "NOT_ASSIGNABLE": {
-    "id": "FYQYXB",
-    "subId": 0,
-    "categories": [
-      "StaticTypeWarning"
-    ],
-    "template": "'#{fromType}' is not assignable to '#{toType}'.",
-    "templateHoleOrder": null,
-    "howToFix": null,
-    "options": null,
-    "usedBy": [
-      "Platform.dart2js"
-    ],
-    "examples": null
-  },
-  "FORIN_NOT_ASSIGNABLE": {
-    "id": "FYQYXB",
-    "subId": 1,
-    "categories": [
-      "Hint"
-    ],
-    "template": "The element type '#{currentType}' of '#{expressionType}' is not assignable to '#{elementType}'.",
-    "templateHoleOrder": null,
-    "howToFix": null,
-    "options": null,
-    "usedBy": [
-      "Platform.dart2js"
-    ],
-    "examples": [
-      "        main() {\n          List<int> list = <int>[1, 2];\n          for (String x in list) x;\n        }\n        "
-    ]
-  },
-  "RETURN_OF_INVALID_TYPE": {
-    "id": "FYQYXB",
-    "subId": 2,
-    "categories": [
-      "StaticTypeWarning"
-    ],
-    "template": "The return type '#{fromType}' is not a '#{toType}', as defined by the method '#{method}'.",
-    "templateHoleOrder": null,
-    "howToFix": null,
-    "options": null,
-    "usedBy": [
-      "Platform.analyzer"
-    ],
-    "examples": [
-      "int foo() => 'foo'; main() { foo(); }"
-    ]
-  },
-  "ARGUMENT_TYPE_NOT_ASSIGNABLE": {
-    "id": "FYQYXB",
-    "subId": 3,
-    "categories": [
-      "Hint",
-      "StaticWarning"
-    ],
-    "template": "The argument type '#{fromType}' cannot be assigned to the parameter type '#{toType}'.",
-    "templateHoleOrder": null,
-    "howToFix": null,
-    "options": null,
-    "usedBy": [
-      "Platform.analyzer"
-    ],
-    "examples": [
-      "foo(int x) => x; main() { foo('bar'); }"
-    ]
-  },
-  "CANNOT_RESOLVE": {
-    "id": "ERUSKD",
-    "subId": 0,
-    "categories": [
-      "StaticTypeWarning"
-    ],
-    "template": "Can't resolve '#{name}'.",
-    "templateHoleOrder": null,
-    "howToFix": null,
-    "options": null,
-    "usedBy": [
-      "Platform.dart2js"
-    ],
-    "examples": null
-  },
-  "UNDEFINED_METHOD": {
-    "id": "ERUSKD",
-    "subId": 1,
-    "categories": [
-      "StaticTypeWarning",
-      "Hint"
-    ],
-    "template": "The method '#{memberName}' is not defined for the class '#{className}'.",
-    "templateHoleOrder": null,
-    "howToFix": null,
-    "options": null,
-    "usedBy": [
-      "Platform.dart2js",
-      "Platform.analyzer"
-    ],
-    "examples": [
-      "        class A {\n          foo() { bar(); }\n        }\n        main() { new A().foo(); }\n        "
-    ]
-  },
-  "UNDEFINED_METHOD_WITH_CONSTRUCTOR": {
-    "id": "ERUSKD",
-    "subId": 2,
-    "categories": [
-      "StaticTypeWarning"
-    ],
-    "template": "The method '#{memberName}' is not defined for the class '#{className}', but a constructor with that name is defined.",
-    "templateHoleOrder": null,
-    "howToFix": "Try adding 'new' or 'const' to invoke the constructor, or change the method name.",
-    "options": null,
-    "usedBy": [
-      "Platform.analyzer"
-    ],
-    "examples": [
-      "        class A {\n          A.bar() {}\n        }\n        main() { A.bar(); }\n        "
-    ]
-  },
-  "UNDEFINED_GETTER": {
-    "id": "ERUSKD",
-    "subId": 3,
-    "categories": [
-      "StaticTypeWarning",
-      "StaticWarning",
-      "Hint"
-    ],
-    "template": "The getter '#{memberName}' is not defined for the class '#{className}'.",
-    "templateHoleOrder": null,
-    "howToFix": null,
-    "options": null,
-    "usedBy": [
-      "Platform.dart2js",
-      "Platform.analyzer"
-    ],
-    "examples": [
-      "class A {} main() { new A().x; }",
-      "class A {} main() { A.x; }"
-    ]
-  },
-  "UNDEFINED_ENUM_CONSTANT": {
-    "id": "ERUSKD",
-    "subId": 4,
-    "categories": [
-      "StaticTypeWarning"
-    ],
-    "template": "There is no constant named '#{memberName}' in '#{className}'.",
-    "templateHoleOrder": null,
-    "howToFix": null,
-    "options": null,
-    "usedBy": [
-      "Platform.analyzer"
-    ],
-    "examples": [
-      "        enum E { ONE }\n        E e() { return E.TWO; }\n        main() { e(); }\n       "
-    ]
-  },
-  "UNDEFINED_INSTANCE_GETTER_BUT_SETTER": {
-    "id": "ERUSKD",
-    "subId": 5,
-    "categories": [
-      "StaticTypeWarning"
-    ],
-    "template": "The setter '#{memberName}' in class '#{className}' can not be used as a getter.",
-    "templateHoleOrder": null,
-    "howToFix": null,
-    "options": null,
-    "usedBy": [
-      "Platform.dart2js"
-    ],
-    "examples": [
-      "class A { set x(y) {} } main() { new A().x; }"
-    ]
-  },
-  "UNDEFINED_OPERATOR": {
-    "id": "ERUSKD",
-    "subId": 6,
-    "categories": [
-      "StaticTypeWarning",
-      "Hint"
-    ],
-    "template": "The operator '#{memberName}' is not defined for the class '#{className}'.",
-    "templateHoleOrder": null,
-    "howToFix": null,
-    "options": null,
-    "usedBy": [
-      "Platform.dart2js",
-      "Platform.analyzer"
-    ],
-    "examples": [
-      "class A {} main() { new A() + 3; }"
-    ]
-  },
-  "UNDEFINED_SETTER": {
-    "id": "ERUSKD",
-    "subId": 7,
-    "categories": [
-      "StaticTypeWarning",
-      "StaticWarning",
-      "Hint"
-    ],
-    "template": "The setter '#{memberName}' is not defined for the class '#{className}'.",
-    "templateHoleOrder": null,
-    "howToFix": null,
-    "options": null,
-    "usedBy": [
-      "Platform.dart2js",
-      "Platform.analyzer"
-    ],
-    "examples": [
-      "class A {} main() { new A().x = 499; }"
-    ]
-  },
-  "NO_SUCH_SUPER_MEMBER": {
-    "id": "ERUSKD",
-    "subId": 8,
-    "categories": [
-      "StaticTypeWarning"
-    ],
-    "template": "Can't resolve '#{memberName}' in a superclass of '#{className}'.",
-    "templateHoleOrder": null,
-    "howToFix": null,
-    "options": null,
-    "usedBy": [
-      "Platform.dart2js"
-    ],
-    "examples": null
-  },
-  "UNDEFINED_SUPER_GETTER": {
-    "id": "ERUSKD",
-    "subId": 9,
-    "categories": [
-      "StaticTypeWarning",
-      "StaticWarning"
-    ],
-    "template": "The getter '#{memberName}' is not defined in a superclass of '#{className}'.",
-    "templateHoleOrder": null,
-    "howToFix": null,
-    "options": null,
-    "usedBy": [
-      "Platform.analyzer"
-    ],
-    "examples": [
-      "        class A {}\n        class B extends A {\n          foo() => super.x;\n        }\n        main() { new B().foo(); }\n        "
-    ]
-  },
-  "UNDEFINED_SUPER_METHOD": {
-    "id": "ERUSKD",
-    "subId": 10,
-    "categories": [
-      "StaticTypeWarning"
-    ],
-    "template": "The method '#{memberName}' is not defined in a superclass of '#{className}'.",
-    "templateHoleOrder": null,
-    "howToFix": null,
-    "options": null,
-    "usedBy": [
-      "Platform.analyzer"
-    ],
-    "examples": [
-      "        class A {}\n        class B extends A {\n          foo() => super.x();\n        }\n        main() { new B().foo(); }\n        "
-    ]
-  },
-  "UNDEFINED_SUPER_OPERATOR": {
-    "id": "ERUSKD",
-    "subId": 11,
-    "categories": [
-      "StaticTypeWarning"
-    ],
-    "template": "The operator '#{memberName}' is not defined in a superclass of '#{className}'.",
-    "templateHoleOrder": null,
-    "howToFix": null,
-    "options": null,
-    "usedBy": [
-      "Platform.analyzer"
-    ],
-    "examples": [
-      "        class A {}\n        class B extends A {\n          foo() => super + 499;\n        }\n        main() { new B().foo(); }\n        "
-    ]
-  },
-  "UNDEFINED_SUPER_SETTER": {
-    "id": "ERUSKD",
-    "subId": 12,
-    "categories": [
-      "StaticTypeWarning",
-      "StaticWarning"
-    ],
-    "template": "The setter '#{memberName}' is not defined in a superclass of '#{className}'.",
-    "templateHoleOrder": null,
-    "howToFix": null,
-    "options": null,
-    "usedBy": [
-      "Platform.analyzer",
-      "Platform.dart2js"
-    ],
-    "examples": [
-      "        class A {}\n        class B extends A {\n          foo() { super.x = 499; }\n        }\n        main() { new B().foo(); }\n        "
-    ]
-  },
-  "UNDEFINED_FUNCTION": {
-    "id": "ERUSKD",
-    "subId": 13,
-    "categories": [
-      "StaticTypeWarning"
-    ],
-    "template": "The function '#{memberName}' is not defined.",
-    "templateHoleOrder": null,
-    "howToFix": null,
-    "options": null,
-    "usedBy": [
-      "Platform.analyzer"
-    ],
-    "examples": [
-      "main() { foo(); }"
-    ]
-  },
-  "UNDEFINED_STATIC_GETTER_BUT_SETTER": {
-    "id": "ERUSKD",
-    "subId": 14,
-    "categories": [
-      "StaticTypeWarning"
-    ],
-    "template": "Cannot resolve getter '#{name}'.",
-    "templateHoleOrder": null,
-    "howToFix": null,
-    "options": null,
-    "usedBy": [
-      "Platform.dart2js"
-    ],
-    "examples": [
-      "set foo(x) {}  main() { foo; }"
-    ]
-  },
-  "UNDEFINED_STATIC_SETTER_BUT_GETTER": {
-    "id": "ERUSKD",
-    "subId": 15,
-    "categories": [
-      "StaticTypeWarning"
-    ],
-    "template": "Cannot resolve setter '#{name}'.",
-    "templateHoleOrder": null,
-    "howToFix": null,
-    "options": null,
-    "usedBy": [
-      "Platform.dart2js"
-    ],
-    "examples": [
-      "        main() {\n          final x = 1;\n          x = 2;\n        }",
-      "        main() {\n          const x = 1;\n          x = 2;\n        }\n        ",
-      "        final x = 1;\n        main() { x = 3; }\n        ",
-      "        const x = 1;\n        main() { x = 3; }\n        ",
-      "get foo => null  main() { foo = 5; }",
-      "const foo = 0  main() { foo = 5; }"
-    ]
-  }
-}
diff --git a/pkg/dart_messages/lib/shared_messages.dart b/pkg/dart_messages/lib/shared_messages.dart
deleted file mode 100644
index cadf550..0000000
--- a/pkg/dart_messages/lib/shared_messages.dart
+++ /dev/null
@@ -1,860 +0,0 @@
-// 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.
-
-/// An update to this file must be followed by regenerating the corresponding
-/// json, dart2js and analyzer file. Use `publish.dart` in the bin directory.
-///
-/// Every message in this file must have an id. Use `message_id.dart` in the
-/// bin directory to generate a fresh one.
-///
-/// The messages in this file should follow the [Guide for Writing
-/// Diagnostics](../../front_end/lib/src/fasta/diagnostics.md).
-import 'dart:convert';
-
-/// Encodes the category of the message.
-///
-/// This is currently only used in the analyzer.
-// TODO(floitsch): encode severity and type in the category, so we can generate
-// the corresponding ErrorCode subclasses.
-class Category {
-  static final analysisOptionsError = new Category("AnalysisOptionsError");
-
-  static final analysisOptionsWarning = new Category("AnalysisOptionsWarning");
-
-  static final checkedModeCompileTimeError =
-      new Category("CheckedModeCompileTimeError");
-
-  static final parserError = new Category("ParserError");
-
-  static final compileTimeError = new Category("CompileTimeError");
-
-  static final staticTypeWarning = new Category("StaticTypeWarning");
-
-  static final staticWarning = new Category("StaticWarning");
-
-  static final hint = new Category("Hint");
-
-  final String name;
-
-  Category(this.name);
-}
-
-enum Platform {
-  dart2js,
-  analyzer,
-}
-const dart2js = Platform.dart2js;
-const analyzer = Platform.analyzer;
-
-class Message {
-  /// Generic id for this message.
-  ///
-  /// This id should be shared by all errors that fall into the same category.
-  /// In particular, we want errors of the same category to share the same
-  /// explanation page, and want to disable warnings of the same category
-  /// with just one line.
-  final String id;
-
-  /// The sub-id of the error.
-  ///
-  /// This id just needs to be unique within the same [id].
-  final int subId;
-
-  /// The error of which this message is a specialization.
-  ///
-  /// For example, "Const is not allowed on getters" may be a specialization of
-  /// "The 'const' keyword is not allowed here".
-  ///
-  /// Examples of the specialized message, should trigger for the more generic
-  /// message, when the platform doesn't support the more specialized message.
-  ///
-  /// Specializations must have the same error-id (but not sub-id) as the more
-  /// generic message.
-  final String specializationOf;
-
-  /// The categories of this message.
-  ///
-  /// The same message can be used in multiple categories, for example, as
-  /// hint and warning.
-  final List<Category> categories;
-
-  final String template;
-  // The analyzer fills holes positionally (and not named). The following field
-  // overrides the order of the holes.
-  // For example the template "The argument #field in #cls is bad", could have
-  // the order `["cls", "field"]', which means that the analyzer would first
-  // provide the class `cls` and then only `field`.
-  // This list is generally `null`, but when it is provided it must contain all
-  // holes.
-  final List<String> templateHoleOrder;
-  final String howToFix;
-  final List<String> options;
-  final List examples;
-  final List<Platform> usedBy;
-
-  Message(
-      {this.id,
-      this.subId: 0,
-      this.specializationOf: null,
-      this.categories,
-      this.template,
-      this.templateHoleOrder,
-      this.howToFix,
-      this.options,
-      this.usedBy: const [],
-      this.examples});
-}
-
-String get messagesAsJson {
-  var jsonified = {};
-  MESSAGES.forEach((String name, Message message) {
-    jsonified[name] = {
-      'id': message.id,
-      'subId': message.subId,
-      'categories':
-          message.categories.map((category) => category.name).toList(),
-      'template': message.template,
-      'templateHoleOrder': message.templateHoleOrder,
-      'howToFix': message.howToFix,
-      'options': message.options,
-      'usedBy': message.usedBy.map((platform) => platform.toString()).toList(),
-      'examples': message.examples,
-    };
-  });
-  return new JsonEncoder.withIndent('  ').convert(jsonified);
-}
-
-final Map<String, Message> MESSAGES = {
-  'exampleMessage': new Message(
-      id: 'use an Id generated by bin/message_id.dart',
-      categories: [Category.analysisOptionsError],
-      template: "#use #named #arguments",
-      templateHoleOrder: ["arguments", "named", "use"],
-      howToFix: "an explanation on how to fix things",
-      examples: [
-        r'''
-      Some multiline example;
-      That generates the bug.''',
-        {
-          'fileA.dart': '''
-        or a map from file to content.
-        again multiline''',
-          'fileB.dart': '''
-        with possibly multiple files.
-        muliline too'''
-        }
-      ]),
-
-  // Const constructors may not have a body.
-  'CONST_CONSTRUCTOR_WITH_BODY': new Message(
-      id: 'LGJGHW',
-      subId: 0,
-      categories: [Category.parserError],
-      template: "Const constructor can't have a body.",
-      howToFix: "Try removing the 'const' keyword or the body.",
-      usedBy: [analyzer, dart2js],
-      examples: const [
-        r"""
-         class C {
-           const C() {}
-         }
-
-         main() => new C();"""
-      ]),
-  // Const constructor factories may only redirect (and must not have a body).
-  'CONST_FACTORY': new Message(
-      id: 'LGJGHW',
-      subId: 1,
-      categories: [Category.parserError],
-      template: "Only redirecting factory constructors can be declared to "
-          "be 'const'.",
-      howToFix: "Try removing the 'const' keyword or replacing the body with "
-          "'=' followed by a valid target.",
-      usedBy: [analyzer, dart2js],
-      examples: const [
-        r"""
-         class C {
-           const factory C() {}
-         }
-
-         main() => new C();"""
-      ]),
-
-  'EXTRANEOUS_MODIFIER': new Message(
-      id: 'GRKIQE',
-      subId: 0,
-      categories: [Category.parserError],
-      template: "Can't have modifier '#{modifier}' here.",
-      howToFix: "Try removing '#{modifier}'.",
-      usedBy: [dart2js],
-      examples: const [
-        "var String foo; main(){}",
-        // "var get foo; main(){}",
-        "var set foo; main(){}",
-        "var final foo; main(){}",
-        "var var foo; main(){}",
-        "var const foo; main(){}",
-        "var abstract foo; main(){}",
-        "var static foo; main(){}",
-        "var external foo; main(){}",
-        "final var foo; main(){}",
-        "var var foo; main(){}",
-        "const var foo; main(){}",
-        "abstract var foo; main(){}",
-        "static var foo; main(){}",
-        "external var foo; main(){}"
-      ]),
-
-  'EXTRANEOUS_MODIFIER_REPLACE': new Message(
-      id: 'GRKIQE',
-      subId: 1,
-      categories: [Category.parserError],
-      template: "Can't have modifier '#{modifier}' here.",
-      howToFix: "Try replacing modifier '#{modifier}' with 'var', 'final', "
-          "or a type.",
-      usedBy: [dart2js],
-      examples: const [
-        // "get foo; main(){}",
-        "set foo; main(){}",
-        "abstract foo; main(){}",
-        "static foo; main(){}",
-        "external foo; main(){}"
-      ]),
-
-  'CONST_CLASS': new Message(
-      id: 'GRKIQE',
-      subId: 2,
-      // The specialization could also be 'EXTRANEOUS_MODIFIER_REPLACE', but the
-      // example below triggers 'EXTRANEOUS_MODIFIER'.
-      specializationOf: 'EXTRANEOUS_MODIFIER',
-      categories: [Category.parserError],
-      template: "Classes can't be declared to be 'const'.",
-      howToFix: "Try removing the 'const' keyword or moving to the class'"
-          " constructor(s).",
-      usedBy: [analyzer],
-      examples: const [
-        r"""
-        const class C {}
-
-        main() => new C();
-        """
-      ]),
-
-  'CONST_METHOD': new Message(
-      id: 'GRKIQE',
-      subId: 3,
-      // The specialization could also be 'EXTRANEOUS_MODIFIER_REPLACE', but the
-      // example below triggers 'EXTRANEOUS_MODIFIER'.
-      specializationOf: 'EXTRANEOUS_MODIFIER',
-      categories: [Category.parserError],
-      template: "Getters, setters and methods can't be declared to be 'const'.",
-      howToFix: "Try removing the 'const' keyword.",
-      usedBy: [analyzer],
-      examples: const [
-        "const int foo() => 499; main() {}",
-        "const int get foo => 499; main() {}",
-        "const set foo(v) => 499; main() {}",
-        "class A { const int foo() => 499; } main() { new A(); }",
-        "class A { const int get foo => 499; } main() { new A(); }",
-        "class A { const set foo(v) => 499; } main() { new A(); }",
-      ]),
-
-  'CONST_ENUM': new Message(
-      id: 'GRKIQE',
-      subId: 4,
-      // The specialization could also be 'EXTRANEOUS_MODIFIER_REPLACE', but the
-      // example below triggers 'EXTRANEOUS_MODIFIER'.
-      specializationOf: 'EXTRANEOUS_MODIFIER',
-      categories: [Category.parserError],
-      template: "Enums can't be declared to be 'const'.",
-      howToFix: "Try removing the 'const' keyword.",
-      usedBy: [analyzer],
-      examples: const [
-        "const enum Foo { x } main() {}",
-      ]),
-
-  'CONST_TYPEDEF': new Message(
-      id: 'GRKIQE',
-      subId: 5,
-      // The specialization could also be 'EXTRANEOUS_MODIFIER_REPLACE', but the
-      // example below triggers 'EXTRANEOUS_MODIFIER'.
-      specializationOf: 'EXTRANEOUS_MODIFIER',
-      categories: [Category.parserError],
-      template: "Type aliases can't be declared to be 'const'.",
-      howToFix: "Try removing the 'const' keyword.",
-      usedBy: [analyzer],
-      examples: const [
-        "const typedef void Foo(); main() {}",
-      ]),
-
-  'CONST_AND_FINAL': new Message(
-      id: 'GRKIQE',
-      subId: 6,
-      // The specialization could also be 'EXTRANEOUS_MODIFIER_REPLACE', but the
-      // example below triggers 'EXTRANEOUS_MODIFIER'.
-      specializationOf: 'EXTRANEOUS_MODIFIER',
-      categories: [Category.parserError],
-      template: "Members can't be declared to be both 'const' and 'final'.",
-      howToFix: "Try removing either the 'const' or 'final' keyword.",
-      usedBy: [analyzer],
-      examples: const [
-        "final const int x = 499; main() {}",
-        "const final int x = 499; main() {}",
-        "class A { static final const int x = 499; } main() {}",
-        "class A { static const final int x = 499; } main() {}",
-      ]),
-
-  'CONST_AND_VAR': new Message(
-      id: 'GRKIQE',
-      subId: 7,
-      // The specialization could also be 'EXTRANEOUS_MODIFIER_REPLACE', but the
-      // example below triggers 'EXTRANEOUS_MODIFIER'.
-      specializationOf: 'EXTRANEOUS_MODIFIER',
-      categories: [Category.parserError],
-      template: "Members can't be declared to be both 'const' and 'var'.",
-      howToFix: "Try removing either the 'const' or 'var' keyword.",
-      usedBy: [analyzer],
-      examples: const [
-        "var const x = 499; main() {}",
-        "const var x = 499; main() {}",
-        "class A { var const x = 499; } main() {}",
-        "class A { const var x = 499; } main() {}",
-      ]),
-
-  'CLASS_IN_CLASS': new Message(
-      // Dart2js currently reports this as an EXTRANEOUS_MODIFIER error.
-      // TODO(floitsch): make dart2js use this error instead.
-      id: 'DOTHQH',
-      categories: [Category.parserError],
-      template: "Classes can't be declared inside other classes.",
-      howToFix: "Try moving the class to the top-level.",
-      usedBy: [analyzer],
-      examples: const [
-        "class A { class B {} } main() { new A(); }",
-      ]),
-
-  'CONSTRUCTOR_WITH_RETURN_TYPE': new Message(
-      id: 'VOJBWY',
-      categories: [Category.parserError],
-      template: "Constructors can't have a return type.",
-      howToFix: "Try removing the return type.",
-      usedBy: [analyzer, dart2js],
-      examples: const [
-        "class A { int A() {} } main() { new A(); }",
-      ]),
-
-  'MISSING_EXPRESSION_IN_THROW': new Message(
-      id: 'FTGGMJ',
-      subId: 0,
-      categories: [Category.parserError],
-      template: "Missing expression after 'throw'.",
-      howToFix: "Did you mean 'rethrow'?",
-      usedBy: [analyzer, dart2js],
-      examples: const [
-        'main() { throw; }',
-        'main() { try { throw 0; } catch(e) { throw; } }'
-      ]),
-
-  /**
-   * 12.8.1 Rethrow: It is a compile-time error if an expression of the form
-   * <i>rethrow;</i> is not enclosed within a on-catch clause.
-   */
-  'RETHROW_OUTSIDE_CATCH': new Message(
-      id: 'MWETLC',
-      categories: [Category.compileTimeError],
-      template: 'Rethrow must be inside of catch clause.',
-      howToFix: "Try moving the expression into a catch clause, or "
-          "using a 'throw' expression.",
-      usedBy: [analyzer, dart2js],
-      examples: const ["main() { rethrow; }"]),
-
-  /**
-   * 13.12 Return: It is a compile-time error if a return statement of the form
-   * <i>return e;</i> appears in a generative constructor.
-   */
-  'RETURN_IN_GENERATIVE_CONSTRUCTOR': new Message(
-      id: 'UOTDQH',
-      categories: [Category.compileTimeError],
-      template: "Constructors can't return values.",
-      howToFix:
-          "Try removing the return statement or using a factory constructor.",
-      usedBy: [analyzer, dart2js],
-      examples: const [
-        """
-        class C {
-          C() {
-            return 1;
-          }
-        }
-
-        main() => new C();"""
-      ]),
-
-  /**
-   * 13.12 Return: It is a compile-time error if a return statement of the form
-   * <i>return e;</i> appears in a generator function.
-   */
-  'RETURN_IN_GENERATOR': new Message(
-      id: 'JRUTUQ',
-      subId: 0,
-      categories: [Category.compileTimeError],
-      template: "Can't return a value from a generator function "
-          "(using the '#{modifier}' modifier).",
-      howToFix: "Try removing the value, replacing 'return' with 'yield' or"
-          " changing the method body modifier.",
-      usedBy: [analyzer, dart2js],
-      examples: const [
-        """
-        foo() async* { return 0; }
-        main() => foo();
-        """,
-        """
-        foo() sync* { return 0; }
-        main() => foo();
-        """
-      ]),
-
-  'NOT_ASSIGNABLE': new Message(
-      id: 'FYQYXB',
-      subId: 0,
-      categories: [Category.staticTypeWarning],
-      template: "'#{fromType}' is not assignable to '#{toType}'.",
-      usedBy: [dart2js]),
-
-  'FORIN_NOT_ASSIGNABLE': new Message(
-      id: 'FYQYXB',
-      subId: 1,
-      categories: [Category.hint],
-      template: "The element type '#{currentType}' of '#{expressionType}' "
-          "is not assignable to '#{elementType}'.",
-      usedBy: [dart2js],
-      examples: const [
-        """
-        main() {
-          List<int> list = <int>[1, 2];
-          for (String x in list) x;
-        }
-        """
-      ]),
-
-  /**
-   * 13.11 Return: It is a static type warning if the type of <i>e</i> may not
-   * be assigned to the declared return type of the immediately enclosing
-   * function.
-   */
-  'RETURN_OF_INVALID_TYPE': new Message(
-      id: 'FYQYXB',
-      subId: 2,
-      specializationOf: 'NOT_ASSIGNABLE',
-      categories: [Category.staticTypeWarning],
-      template: "The return type '#{fromType}' is not a '#{toType}', as "
-          "defined by the method '#{method}'.",
-      usedBy: [analyzer],
-      examples: const ["int foo() => 'foo'; main() { foo(); }"]),
-
-  /**
-   * 12.11.1 New: It is a static warning if the static type of <i>a<sub>i</sub>,
-   * 1 &lt;= i &lt;= n+ k</i> may not be assigned to the type of the
-   * corresponding formal parameter of the constructor <i>T.id</i> (respectively
-   * <i>T</i>).
-   *
-   * 12.11.2 Const: It is a static warning if the static type of
-   * <i>a<sub>i</sub>, 1 &lt;= i &lt;= n+ k</i> may not be assigned to the type
-   * of the corresponding formal parameter of the constructor <i>T.id</i>
-   * (respectively <i>T</i>).
-   *
-   * 12.14.2 Binding Actuals to Formals: Let <i>T<sub>i</sub></i> be the static
-   * type of <i>a<sub>i</sub></i>, let <i>S<sub>i</sub></i> be the type of
-   * <i>p<sub>i</sub>, 1 &lt;= i &lt;= n+k</i> and let <i>S<sub>q</sub></i> be
-   * the type of the named parameter <i>q</i> of <i>f</i>. It is a static
-   * warning if <i>T<sub>j</sub></i> may not be assigned to <i>S<sub>j</sub>, 1
-   * &lt;= j &lt;= m</i>.
-   *
-   * 12.14.2 Binding Actuals to Formals: Furthermore, each <i>q<sub>i</sub>, 1
-   * &lt;= i &lt;= l</i>, must have a corresponding named parameter in the set
-   * <i>{p<sub>n+1</sub>, &hellip; p<sub>n+k</sub>}</i> or a static warning
-   * occurs. It is a static warning if <i>T<sub>m+j</sub></i> may not be
-   * assigned to <i>S<sub>r</sub></i>, where <i>r = q<sub>j</sub>, 1 &lt;= j
-   * &lt;= l</i>.
-   */
-  'ARGUMENT_TYPE_NOT_ASSIGNABLE': new Message(
-      id: 'FYQYXB',
-      subId: 3,
-      specializationOf: 'NOT_ASSIGNABLE',
-      categories: [Category.hint, Category.staticWarning],
-      template: "The argument type '#{fromType}' cannot be assigned to the "
-          "parameter type '#{toType}'.",
-      usedBy: [analyzer],
-      // TODO(floitsch): support hint warnings and ways to specify which
-      // category an example should trigger for.
-      examples: const ["foo(int x) => x; main() { foo('bar'); }"]),
-
-  'CANNOT_RESOLVE': new Message(
-      id: 'ERUSKD',
-      subId: 0,
-      categories: [Category.staticTypeWarning],
-      template: "Can't resolve '#{name}'.",
-      usedBy: [dart2js]),
-
-  /**
-   * 12.15.1 Ordinary Invocation: Let <i>T</i> be the static type of <i>o</i>.
-   * It is a static type warning if <i>T</i> does not have an accessible
-   * instance member named <i>m</i>.
-   */
-  'UNDEFINED_METHOD': new Message(
-      id: 'ERUSKD',
-      subId: 1,
-      categories: [Category.staticTypeWarning, Category.hint],
-      template: "The method '#{memberName}' is not defined for the class"
-          " '#{className}'.",
-      usedBy: [dart2js, analyzer],
-      examples: const [
-        """
-        class A {
-          foo() { bar(); }
-        }
-        main() { new A().foo(); }
-        """,
-      ]),
-
-  /**
-   * 12.15.1 Ordinary Invocation: Let <i>T</i> be the static type of <i>o</i>.
-   * It is a static type warning if <i>T</i> does not have an accessible
-   * instance member named <i>m</i>.
-   */
-  'UNDEFINED_METHOD_WITH_CONSTRUCTOR': new Message(
-      id: 'ERUSKD',
-      subId: 2,
-      specializationOf: "UNDEFINED_METHOD",
-      categories: [Category.staticTypeWarning],
-      template: "The method '#{memberName}' is not defined for the class"
-          " '#{className}', but a constructor with that name is defined.",
-      howToFix: "Try adding 'new' or 'const' to invoke the constructor, or "
-          "change the method name.",
-      usedBy: [analyzer],
-      examples: const [
-        """
-        class A {
-          A.bar() {}
-        }
-        main() { A.bar(); }
-        """,
-      ]),
-
-  /**
-   * 12.17 Getter Invocation: Let <i>T</i> be the static type of <i>e</i>. It is
-   * a static type warning if <i>T</i> does not have a getter named <i>m</i>.
-   */
-  'UNDEFINED_GETTER': new Message(
-      id: 'ERUSKD',
-      subId: 3,
-      categories: [
-        Category.staticTypeWarning,
-        Category.staticWarning,
-        Category.hint
-      ],
-      template: "The getter '#{memberName}' is not defined for the "
-          "class '#{className}'.",
-      usedBy: [dart2js, analyzer],
-      examples: const [
-        "class A {} main() { new A().x; }",
-        "class A {} main() { A.x; }"
-      ]),
-
-  /**
-   * 12.17 Getter Invocation: It is a static warning if there is no class
-   * <i>C</i> in the enclosing lexical scope of <i>i</i>, or if <i>C</i> does
-   * not declare, implicitly or explicitly, a getter named <i>m</i>.
-   */
-  'UNDEFINED_ENUM_CONSTANT': new Message(
-      id: 'ERUSKD',
-      subId: 4,
-      specializationOf: 'UNDEFINED_GETTER',
-      categories: [Category.staticTypeWarning],
-      template: "There is no constant named '#{memberName}' in '#{className}'.",
-      usedBy: [analyzer],
-      examples: const [
-        """
-        enum E { ONE }
-        E e() { return E.TWO; }
-        main() { e(); }
-       """
-      ]),
-
-  'UNDEFINED_INSTANCE_GETTER_BUT_SETTER': new Message(
-      id: 'ERUSKD',
-      subId: 5,
-      specializationOf: 'UNDEFINED_GETTER',
-      categories: [
-        Category.staticTypeWarning,
-      ],
-      template: "The setter '#{memberName}' in class '#{className}' can"
-          " not be used as a getter.",
-      usedBy: [dart2js],
-      examples: const [
-        "class A { set x(y) {} } main() { new A().x; }",
-      ]),
-
-  /**
-   * 12.18 Assignment: Evaluation of an assignment of the form
-   * <i>e<sub>1</sub></i>[<i>e<sub>2</sub></i>] = <i>e<sub>3</sub></i> is
-   * equivalent to the evaluation of the expression (a, i, e){a.[]=(i, e);
-   * return e;} (<i>e<sub>1</sub></i>, <i>e<sub>2</sub></i>,
-   * <i>e<sub>2</sub></i>).
-   *
-   * 12.29 Assignable Expressions: An assignable expression of the form
-   * <i>e<sub>1</sub></i>[<i>e<sub>2</sub></i>] is evaluated as a method
-   * invocation of the operator method [] on <i>e<sub>1</sub></i> with argument
-   * <i>e<sub>2</sub></i>.
-   *
-   * 12.15.1 Ordinary Invocation: Let <i>T</i> be the static type of <i>o</i>.
-   * It is a static type warning if <i>T</i> does not have an accessible
-   * instance member named <i>m</i>.
-   */
-  'UNDEFINED_OPERATOR': new Message(
-      id: 'ERUSKD',
-      subId: 6,
-      categories: [Category.staticTypeWarning, Category.hint],
-      template: "The operator '#{memberName}' is not defined for the "
-          "class '#{className}'.",
-      usedBy: [dart2js, analyzer],
-      examples: const [
-        "class A {} main() { new A() + 3; }",
-      ]),
-
-  /**
-   * 12.18 Assignment: Let <i>T</i> be the static type of <i>e<sub>1</sub></i>.
-   * It is a static type warning if <i>T</i> does not have an accessible
-   * instance setter named <i>v=</i>.
-   *
-   * 12.18 Assignment: It is as static warning if an assignment of the form
-   * <i>v = e</i> occurs inside a top level or static function (be it function,
-   * method, getter, or setter) or variable initializer and there is no
-   * declaration <i>d</i> with name <i>v=</i> in the lexical scope enclosing the
-   * assignment.
-   *
-   * 12.18 Assignment: It is a static warning if there is no class <i>C</i> in
-   * the enclosing lexical scope of the assignment, or if <i>C</i> does not
-   * declare, implicitly or explicitly, a setter <i>v=</i>.
-   */
-  'UNDEFINED_SETTER': new Message(
-      id: 'ERUSKD',
-      subId: 7,
-      categories: [
-        Category.staticTypeWarning,
-        Category.staticWarning,
-        Category.hint
-      ],
-      template: "The setter '#{memberName}' is not defined for the "
-          "class '#{className}'.",
-      usedBy: [dart2js, analyzer],
-      // TODO(eernst): When this.x access is available, add examples here,
-      // e.g., "class A { var x; A(this.x) : x = 3; } main() => new A(2);"
-      examples: const [
-        "class A {} main() { new A().x = 499; }",
-      ]),
-
-  'NO_SUCH_SUPER_MEMBER': new Message(
-      id: 'ERUSKD',
-      subId: 8,
-      categories: [Category.staticTypeWarning],
-      template:
-          "Can't resolve '#{memberName}' in a superclass of '#{className}'.",
-      usedBy: [dart2js]),
-
-  /**
-   * 12.17 Getter Invocation: Let <i>T</i> be the static type of <i>e</i>. It is
-   * a static type warning if <i>T</i> does not have a getter named <i>m</i>.
-   *
-   * 12.17 Getter Invocation: It is a static warning if there is no class
-   * <i>C</i> in the enclosing lexical scope of <i>i</i>, or if <i>C</i> does
-   * not declare, implicitly or explicitly, a getter named <i>m</i>.
-   */
-  'UNDEFINED_SUPER_GETTER': new Message(
-      id: 'ERUSKD',
-      subId: 9,
-      specializationOf: 'NO_SUCH_SUPER_MEMBER',
-      categories: [Category.staticTypeWarning, Category.staticWarning],
-      template: "The getter '#{memberName}' is not defined in a superclass "
-          "of '#{className}'.",
-      usedBy: [analyzer],
-      examples: const [
-        """
-        class A {}
-        class B extends A {
-          foo() => super.x;
-        }
-        main() { new B().foo(); }
-        """
-      ]),
-
-  /**
-   * 12.15.4 Super Invocation: A super method invocation <i>i</i> has the form
-   * <i>super.m(a<sub>1</sub>, &hellip;, a<sub>n</sub>, x<sub>n+1</sub>:
-   * a<sub>n+1</sub>, &hellip; x<sub>n+k</sub>: a<sub>n+k</sub>)</i>. It is a
-   * static type warning if <i>S</i> does not have an accessible instance member
-   * named <i>m</i>.
-   */
-  'UNDEFINED_SUPER_METHOD': new Message(
-      id: 'ERUSKD',
-      subId: 10,
-      specializationOf: 'NO_SUCH_SUPER_MEMBER',
-      categories: [Category.staticTypeWarning],
-      template: "The method '#{memberName}' is not defined in a superclass "
-          "of '#{className}'.",
-      usedBy: [analyzer],
-      examples: const [
-        """
-        class A {}
-        class B extends A {
-          foo() => super.x();
-        }
-        main() { new B().foo(); }
-        """
-      ]),
-
-  /**
-   * 12.18 Assignment: Evaluation of an assignment of the form
-   * <i>e<sub>1</sub></i>[<i>e<sub>2</sub></i>] = <i>e<sub>3</sub></i> is
-   * equivalent to the evaluation of the expression (a, i, e){a.[]=(i, e);
-   * return e;} (<i>e<sub>1</sub></i>, <i>e<sub>2</sub></i>,
-   * <i>e<sub>2</sub></i>).
-   *
-   * 12.29 Assignable Expressions: An assignable expression of the form
-   * <i>e<sub>1</sub></i>[<i>e<sub>2</sub></i>] is evaluated as a method
-   * invocation of the operator method [] on <i>e<sub>1</sub></i> with argument
-   * <i>e<sub>2</sub></i>.
-   *
-   * 12.15.1 Ordinary Invocation: Let <i>T</i> be the static type of <i>o</i>.
-   * It is a static type warning if <i>T</i> does not have an accessible
-   * instance member named <i>m</i>.
-   */
-  'UNDEFINED_SUPER_OPERATOR': new Message(
-      id: 'ERUSKD',
-      subId: 11,
-      specializationOf: 'NO_SUCH_SUPER_MEMBER',
-      categories: [Category.staticTypeWarning],
-      template: "The operator '#{memberName}' is not defined in a superclass "
-          "of '#{className}'.",
-      usedBy: [analyzer],
-      examples: const [
-        """
-        class A {}
-        class B extends A {
-          foo() => super + 499;
-        }
-        main() { new B().foo(); }
-        """
-      ]),
-
-  /**
-   * 12.18 Assignment: Let <i>T</i> be the static type of <i>e<sub>1</sub></i>.
-   * It is a static type warning if <i>T</i> does not have an accessible
-   * instance setter named <i>v=</i>.
-   *
-   * 12.18 Assignment: It is as static warning if an assignment of the form
-   * <i>v = e</i> occurs inside a top level or static function (be it function,
-   * method, getter, or setter) or variable initializer and there is no
-   * declaration <i>d</i> with name <i>v=</i> in the lexical scope enclosing the
-   * assignment.
-   *
-   * 12.18 Assignment: It is a static warning if there is no class <i>C</i> in
-   * the enclosing lexical scope of the assignment, or if <i>C</i> does not
-   * declare, implicitly or explicitly, a setter <i>v=</i>.
-
-   */
-  'UNDEFINED_SUPER_SETTER': new Message(
-      id: 'ERUSKD',
-      subId: 12,
-      categories: [Category.staticTypeWarning, Category.staticWarning],
-      template: "The setter '#{memberName}' is not defined in a superclass "
-          "of '#{className}'.",
-      usedBy: [
-        analyzer,
-        dart2js,
-      ],
-      examples: const [
-        """
-        class A {}
-        class B extends A {
-          foo() { super.x = 499; }
-        }
-        main() { new B().foo(); }
-        """,
-        // TODO(floitsch): reenable this test.
-        /*
-        """
-        main() => new B().m();
-        class A {
-          get x => 1;
-        }
-        class B extends A {
-          m() { super.x = 2; }
-        }
-        """
-        */
-      ]),
-
-  /**
-   * 12.15.3 Unqualified Invocation: If there exists a lexically visible
-   * declaration named <i>id</i>, let <i>f<sub>id</sub></i> be the innermost
-   * such declaration. Then: [skip]. Otherwise, <i>f<sub>id</sub></i> is
-   * considered equivalent to the ordinary method invocation
-   * <b>this</b>.<i>id</i>(<i>a<sub>1</sub></i>, ..., <i>a<sub>n</sub></i>,
-   * <i>x<sub>n+1</sub></i> : <i>a<sub>n+1</sub></i>, ...,
-   * <i>x<sub>n+k</sub></i> : <i>a<sub>n+k</sub></i>).
-   */
-  'UNDEFINED_FUNCTION': new Message(
-      id: 'ERUSKD',
-      subId: 13,
-      specializationOf: 'CANNOT_RESOLVE',
-      categories: [Category.staticTypeWarning],
-      template: "The function '#{memberName}' is not defined.",
-      usedBy: [analyzer],
-      examples: const [
-        "main() { foo(); }",
-      ]),
-
-  'UNDEFINED_STATIC_GETTER_BUT_SETTER': new Message(
-      id: 'ERUSKD',
-      subId: 14,
-      specializationOf: 'CANNOT_RESOLVE',
-      categories: [Category.staticTypeWarning],
-      template: "Cannot resolve getter '#{name}'.",
-      usedBy: [dart2js],
-      examples: const [
-        "set foo(x) {}  main() { foo; }",
-      ]),
-
-  'UNDEFINED_STATIC_SETTER_BUT_GETTER': new Message(
-      id: 'ERUSKD',
-      subId: 15,
-      specializationOf: 'CANNOT_RESOLVE',
-      categories: [Category.staticTypeWarning],
-      template: "Cannot resolve setter '#{name}'.",
-      usedBy: [dart2js],
-      examples: const [
-        """
-        main() {
-          final x = 1;
-          x = 2;
-        }""",
-        """
-        main() {
-          const x = 1;
-          x = 2;
-        }
-        """,
-        """
-        final x = 1;
-        main() { x = 3; }
-        """,
-        """
-        const x = 1;
-        main() { x = 3; }
-        """,
-        "get foo => null  main() { foo = 5; }",
-        "const foo = 0  main() { foo = 5; }",
-      ]),
-};
diff --git a/pkg/dart_messages/pubspec.yaml b/pkg/dart_messages/pubspec.yaml
deleted file mode 100644
index 2df3361..0000000
--- a/pkg/dart_messages/pubspec.yaml
+++ /dev/null
@@ -1,4 +0,0 @@
-# This package is not intended to be published.
-name: dart_messages
-#version: do-not-upload
-dependencies:
diff --git a/pkg/dart_messages/test/dart_messages_test.dart b/pkg/dart_messages/test/dart_messages_test.dart
deleted file mode 100644
index c031857..0000000
--- a/pkg/dart_messages/test/dart_messages_test.dart
+++ /dev/null
@@ -1,57 +0,0 @@
-// 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.
-
-import 'dart:io' as io;
-
-import 'package:dart_messages/shared_messages.dart';
-
-void testJsonIsUpdated() {
-  var packageRoot = io.Platform.packageRoot;
-  if (packageRoot == null || packageRoot == "") {
-    throw new UnsupportedError("This test requires a package root.");
-  }
-  var jsonUri = Uri
-      .parse(packageRoot)
-      .resolve('dart_messages/generated/shared_messages.json');
-  var jsonPath = jsonUri.toFilePath();
-  var content = new io.File(jsonPath).readAsStringSync();
-  if (messagesAsJson != content) {
-    print("The content of the Dart messages and the corresponding JSON file");
-    print("is not the same.");
-    print("Please run bin/publish.dart to update the JSON file.");
-    throw "Content is not the same";
-  }
-}
-
-void testIdsAreUnique() {
-  var usedIds = new Set();
-  for (var entry in MESSAGES.values) {
-    var id = "${entry.id}-${entry.subId}";
-    if (!usedIds.add(id)) {
-      throw "Id appears twice: $id";
-    }
-  }
-}
-
-void testSpecializationsAreOfSameId() {
-  for (var entry in MESSAGES.values) {
-    var specializationOf = entry.specializationOf;
-    if (specializationOf == null) continue;
-    var generic = MESSAGES[specializationOf];
-    if (generic == null) {
-      throw "More generic message doesn't exist: $specializationOf";
-    }
-    if (generic.id != entry.id) {
-      var id = "${entry.id}-${entry.subId}";
-      var genericId = "${generic.id}-${generic.subId}";
-      throw "Specialization doesn't have same id: $id - $genericId";
-    }
-  }
-}
-
-void main() {
-  testJsonIsUpdated();
-  testIdsAreUnique();
-  testSpecializationsAreOfSameId();
-}
diff --git a/pkg/dev_compiler/lib/src/analyzer/code_generator.dart b/pkg/dev_compiler/lib/src/analyzer/code_generator.dart
index 7226e5a..cee5682 100644
--- a/pkg/dev_compiler/lib/src/analyzer/code_generator.dart
+++ b/pkg/dev_compiler/lib/src/analyzer/code_generator.dart
@@ -6,7 +6,6 @@
 import 'dart:math' show min, max;
 
 import 'package:analyzer/analyzer.dart' hide ConstantEvaluator;
-import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/ast/standard_ast_factory.dart';
 import 'package:analyzer/dart/ast/standard_resolution_map.dart';
 import 'package:analyzer/dart/ast/token.dart' show Token, TokenType;
@@ -972,7 +971,9 @@
     _emitVirtualFieldSymbols(classElem, body);
     _emitClassSignature(classElem, className, memberMap, body);
     _initExtensionSymbols(classElem);
-    _defineExtensionMembers(className, body);
+    if (!classElem.isMixin) {
+      _defineExtensionMembers(className, body);
+    }
     _emitClassMetadata(classNode.metadata, className, body);
 
     var classDef = JS.Statement.from(body);
@@ -1234,7 +1235,7 @@
 
   @override
   JS.Statement visitMixinDeclaration(MixinDeclaration node) {
-    throw new UnimplementedError();
+    return _emitClassDeclaration(node, node.declaredElement, node.members);
   }
 
   /// Wraps a possibly generic class in its type arguments.
@@ -1276,6 +1277,70 @@
     return js.statement('# = #;', [className, classExpr]);
   }
 
+  /// Like [_emitClassStatement] but emits a Dart 2.1 mixin represented by
+  /// [classElem].
+  ///
+  /// Mixins work similar to normal classes, but their instance methods close
+  /// over the actual superclass. Given a Dart class like:
+  ///
+  ///     mixin M on C {
+  ///       foo() => super.foo() + 42;
+  ///     }
+  ///
+  /// We generate a JS class like this:
+  ///
+  ///     lib.M = class M extends core.Object {}
+  ///     lib.M[dart.mixinOn] = (C) => class M extends C {
+  ///       foo() {
+  ///         return super.foo() + 42;
+  ///       }
+  ///     };
+  ///
+  /// The special `dart.mixinOn` symbolized property is used by the runtime
+  /// helper `dart.applyMixin`. The helper calls the function with the actual
+  /// base class, and then copies the resulting members to the destination
+  /// class.
+  ///
+  /// In the long run we may be able to improve this so we do not have the
+  /// unnecessary class, but for now, this lets us get the right semantics with
+  /// minimal compiler and runtime changes.
+  void _emitMixinStatement(
+      ClassElement classElem,
+      JS.Expression className,
+      JS.Expression heritage,
+      List<JS.Method> methods,
+      List<JS.Statement> body) {
+    assert(classElem.isMixin);
+
+    var staticMethods = methods.where((m) => m.isStatic).toList();
+    var instanceMethods = methods.where((m) => !m.isStatic).toList();
+    body.add(
+        _emitClassStatement(classElem, className, heritage, staticMethods));
+
+    var superclassId = JS.TemporaryId(
+        classElem.superclassConstraints.map((t) => t.name).join('_'));
+    var classId =
+        className is JS.Identifier ? className : JS.TemporaryId(classElem.name);
+
+    var mixinMemberClass =
+        JS.ClassExpression(classId, superclassId, instanceMethods);
+
+    JS.Node arrowFnBody = mixinMemberClass;
+    var extensionInit = <JS.Statement>[];
+    _defineExtensionMembers(classId, extensionInit);
+    if (extensionInit.isNotEmpty) {
+      extensionInit.insert(0, mixinMemberClass.toStatement());
+      extensionInit.add(classId.toReturn());
+      arrowFnBody = JS.Block(extensionInit);
+    }
+
+    body.add(js.statement('#[#.mixinOn] = #', [
+      className,
+      runtimeModule,
+      JS.ArrowFun([superclassId], arrowFnBody)
+    ]));
+  }
+
   void _defineClass(
       ClassElement classElem,
       JS.Expression className,
@@ -1306,7 +1371,9 @@
           if (t.typeArguments.any(defer)) return true;
           if (t is InterfaceType) {
             var e = t.element;
-            return e.mixins.any(defer) || defer(e.supertype);
+            if (e.mixins.any(defer)) return true;
+            var supertype = e.supertype;
+            return supertype != null && defer(supertype);
           }
         }
         return false;
@@ -1329,7 +1396,7 @@
       return base;
     }
 
-    var supertype = classElem.supertype;
+    var supertype = classElem.isMixin ? types.objectType : classElem.supertype;
     var hasUnnamedSuper = _hasUnnamedConstructor(supertype.element);
 
     void emitMixinConstructors(JS.Expression className, [InterfaceType mixin]) {
@@ -1386,7 +1453,7 @@
       var classExpr = deferMixin ? getBaseClass(0) : className;
 
       mixinBody
-          .add(runtimeStatement('mixinMembers(#, #)', [classExpr, mixinClass]));
+          .add(runtimeStatement('applyMixin(#, #)', [classExpr, mixinClass]));
 
       _topLevelClass = savedTopLevel;
 
@@ -1396,8 +1463,8 @@
         //
         // We do this with the following pattern:
         //
-        //     mixinMembers(C, class C$ extends M { <methods>  });
-        mixinBody.add(runtimeStatement('mixinMembers(#, #)', [
+        //     applyMixin(C, class C$ extends M { <methods>  });
+        mixinBody.add(runtimeStatement('applyMixin(#, #)', [
           classExpr,
           JS.ClassExpression(
               JS.TemporaryId(classElem.name), mixinClass, methods)
@@ -1429,11 +1496,11 @@
       hasUnnamedSuper = hasUnnamedSuper || _hasUnnamedConstructor(m.element);
 
       if (shouldDefer(m)) {
-        deferredSupertypes.add(runtimeStatement('mixinMembers(#, #)',
+        deferredSupertypes.add(runtimeStatement('applyMixin(#, #)',
             [getBaseClass(mixinLength - i), emitDeferredType(m)]));
       } else {
         body.add(
-            runtimeStatement('mixinMembers(#, #)', [mixinId, emitClassRef(m)]));
+            runtimeStatement('applyMixin(#, #)', [mixinId, emitClassRef(m)]));
       }
 
       baseClass = mixinId;
@@ -1441,7 +1508,14 @@
 
     _topLevelClass = savedTopLevel;
 
-    body.add(_emitClassStatement(classElem, className, baseClass, methods));
+    if (classElem.isMixin) {
+      // TODO(jmesserly): we could make this more efficient, as this creates
+      // an extra unnecessary class. But it's the easiest way to handle the
+      // current system.
+      _emitMixinStatement(classElem, className, baseClass, methods, body);
+    } else {
+      body.add(_emitClassStatement(classElem, className, baseClass, methods));
+    }
 
     if (classElem.isMixinApplication) emitMixinConstructors(className);
   }
@@ -2070,9 +2144,13 @@
   /// Emit the signature on the class recording the runtime type information
   void _emitClassSignature(ClassElement classElem, JS.Expression className,
       Map<Element, Declaration> annotatedMembers, List<JS.Statement> body) {
-    if (classElem.interfaces.isNotEmpty) {
+    if (classElem.interfaces.isNotEmpty ||
+        classElem.superclassConstraints.isNotEmpty) {
+      var interfaces = classElem.interfaces.toList()
+        ..addAll(classElem.superclassConstraints);
+
       body.add(js.statement('#[#.implements] = () => [#];',
-          [className, runtimeModule, classElem.interfaces.map(_emitType)]));
+          [className, runtimeModule, interfaces.map(_emitType)]));
     }
 
     void emitSignature(String name, List<JS.Property> elements) {
@@ -2364,7 +2442,9 @@
     // Get the supertype's unnamed constructor.
     superCtor ??= element.supertype?.element?.unnamedConstructor;
     if (superCtor == null) {
-      assert(element.type.isObject || options.unsafeForceCompile);
+      assert(element.type.isObject ||
+          element.isMixin ||
+          options.unsafeForceCompile);
       return null;
     }
 
@@ -2385,6 +2465,7 @@
 
   bool _hasUnnamedSuperConstructor(ClassElement e) {
     var supertype = e.supertype;
+    // Object or mixin declaration.
     if (supertype == null) return false;
     if (_hasUnnamedConstructor(supertype.element)) return true;
     for (var mixin in e.mixins) {
@@ -4636,10 +4717,12 @@
 
     if (jsTypeRep.binaryOperationIsPrimitive(leftType, rightType) ||
         leftType == types.stringType && op.type == TokenType.PLUS) {
-      // special cases where we inline the operation
-      // these values are assumed to be non-null (determined by the checker)
-      // TODO(jmesserly): it would be nice to just inline the method from core,
-      // instead of special cases here.
+      // Inline operations on primitive types where possible.
+      // TODO(jmesserly): inline these from dart:core instead of hardcoding
+      // the implementation details here.
+
+      /// Emits an inlined binary operation using the JS [code], adding null
+      /// checks if needed to ensure we throw the appropriate error.
       JS.Expression binary(String code) {
         return js.call(code, [notNull(left), notNull(right)])
           ..sourceInformation = _getLocation(node.operator.offset);
@@ -4649,6 +4732,16 @@
         return _coerceBitOperationResultToUnsigned(node, binary(code));
       }
 
+      /// Similar to [binary] but applies a boolean conversion to the right
+      /// operand, to match the boolean bitwise operators in dart:core.
+      ///
+      /// Short circuiting operators should not be used in [code], because the
+      /// null checks for both operands must happen unconditionally.
+      JS.Expression bitwiseBool(String code) {
+        return js.call(code, [notNull(left), _visitTest(right)])
+          ..sourceInformation = _getLocation(node.operator.offset);
+      }
+
       switch (op.type) {
         case TokenType.TILDE_SLASH:
           // `a ~/ b` is equivalent to `(a / b).truncate()`
@@ -4663,13 +4756,19 @@
           return operatorCall();
 
         case TokenType.AMPERSAND:
-          return bitwise('# & #');
+          return jsTypeRep.isBoolean(leftType)
+              ? bitwiseBool('!!(# & #)')
+              : bitwise('# & #');
 
         case TokenType.BAR:
-          return bitwise('# | #');
+          return jsTypeRep.isBoolean(leftType)
+              ? bitwiseBool('!!(# | #)')
+              : bitwise('# | #');
 
         case TokenType.CARET:
-          return bitwise('# ^ #');
+          return jsTypeRep.isBoolean(leftType)
+              ? bitwiseBool('# !== #')
+              : bitwise('# ^ #');
 
         case TokenType.GT_GT:
           int shiftCount = _asIntInRange(right, 0, 31);
diff --git a/pkg/dev_compiler/lib/src/analyzer/element_helpers.dart b/pkg/dev_compiler/lib/src/analyzer/element_helpers.dart
index 12bcbe5..9e7b9be 100644
--- a/pkg/dev_compiler/lib/src/analyzer/element_helpers.dart
+++ b/pkg/dev_compiler/lib/src/analyzer/element_helpers.dart
@@ -139,6 +139,7 @@
       if (mixin != null) result.add(mixin);
     }
     var supertype = cls.supertype;
+    // Object or mixin declaration.
     if (supertype == null) break;
 
     cls = supertype.element;
diff --git a/pkg/dev_compiler/lib/src/analyzer/extension_types.dart b/pkg/dev_compiler/lib/src/analyzer/extension_types.dart
index c3d65cb..513a3f3 100644
--- a/pkg/dev_compiler/lib/src/analyzer/extension_types.dart
+++ b/pkg/dev_compiler/lib/src/analyzer/extension_types.dart
@@ -103,7 +103,8 @@
     }
     element.interfaces.forEach(_addExtensionType);
     element.mixins.forEach(_addExtensionType);
-    _addExtensionType(element.supertype);
+    var supertype = element.supertype;
+    if (supertype != null) _addExtensionType(element.supertype);
   }
 
   void _addExtensionTypesForLibrary(String libraryUri, List<String> typeNames) {
diff --git a/pkg/dev_compiler/lib/src/analyzer/property_model.dart b/pkg/dev_compiler/lib/src/analyzer/property_model.dart
index b625554..a4c1146 100644
--- a/pkg/dev_compiler/lib/src/analyzer/property_model.dart
+++ b/pkg/dev_compiler/lib/src/analyzer/property_model.dart
@@ -264,7 +264,7 @@
     // mock methods encodes information about the number of arguments (and type
     // arguments) that D expects.
     var element = type.element;
-    if (!hasNoSuchMethod(element)) return;
+    if (element.isMixin || !hasNoSuchMethod(element)) return;
 
     // Collect all unimplemented members.
     //
@@ -409,7 +409,8 @@
     for (var i in element.interfaces) {
       _collectNativeMembers(i, members);
     }
-    if (!type.isObject) {
+    var supertype = element.supertype;
+    if (supertype != null) {
       _collectNativeMembers(element.supertype, members);
     }
     if (element.isEnum) {
diff --git a/pkg/dev_compiler/lib/src/analyzer/type_utilities.dart b/pkg/dev_compiler/lib/src/analyzer/type_utilities.dart
index f1bef3c..91978e7 100644
--- a/pkg/dev_compiler/lib/src/analyzer/type_utilities.dart
+++ b/pkg/dev_compiler/lib/src/analyzer/type_utilities.dart
@@ -18,15 +18,26 @@
     if (t is TypeParameterType) {
       result.add(t.element);
     } else if (t is FunctionType) {
-      // Visit type arguments of typedefs, because we use these when we're
-      // emitting the type.
       if (t.name != '' && t.name != null) {
+        // For a typedef type like `Foo<T>`, we only need to check if the
+        // type argument `T` has or is a free type parameter.
+        //
+        // For example, if `Foo` is a typedef type and `S` is a type parameter,
+        // then the type `Foo<List<S>>` has `S` as its free type parameter,
+        // regardless of what function is declared by the typedef.
+        //
+        // Also we need to find free type parameters whether or not they're
+        // actually used by the typedef's function type (for example,
+        // `typedef Foo<T> = int Function()` does not use `T`). So we must visit
+        // the type arguments, instead of the substituted parameter and return
+        // types.
         t.typeArguments.forEach(find);
+      } else {
+        find(t.returnType);
+        t.parameters.forEach((p) => find(p.type));
+        t.typeFormals.forEach((p) => find(p.bound));
+        t.typeFormals.forEach(result.remove);
       }
-      find(t.returnType);
-      t.parameters.forEach((p) => find(p.type));
-      t.typeFormals.forEach((p) => find(p.bound));
-      t.typeFormals.forEach(result.remove);
     } else if (t is InterfaceType) {
       t.typeArguments.forEach(find);
     }
diff --git a/pkg/dev_compiler/lib/src/compiler/js_typerep.dart b/pkg/dev_compiler/lib/src/compiler/js_typerep.dart
index dda2d29..a7bd241 100644
--- a/pkg/dev_compiler/lib/src/compiler/js_typerep.dart
+++ b/pkg/dev_compiler/lib/src/compiler/js_typerep.dart
@@ -89,6 +89,8 @@
 
   bool isNumber(DartType type) => typeFor(type) is JSNumber;
 
+  bool isBoolean(DartType type) => typeFor(type) is JSBoolean;
+
   /// Is this type known to be represented as Object or Null in JS.
   bool isObjectOrNull(DartType t) {
     var rep = typeFor(t);
diff --git a/pkg/dev_compiler/lib/src/js_ast/builder.dart b/pkg/dev_compiler/lib/src/js_ast/builder.dart
index f0e3a65..6640da0 100644
--- a/pkg/dev_compiler/lib/src/js_ast/builder.dart
+++ b/pkg/dev_compiler/lib/src/js_ast/builder.dart
@@ -621,8 +621,15 @@
   static final ARROW_TOKEN = '=>';
   static final ELLIPSIS_TOKEN = '...';
 
-  static final OPERATORS_THAT_LOOK_LIKE_IDENTIFIERS =
-      ['typeof', 'void', 'delete', 'in', 'instanceof', 'await'].toSet();
+  static final OPERATORS_THAT_LOOK_LIKE_IDENTIFIERS = [
+    'typeof',
+    'void',
+    'delete',
+    'in',
+    'instanceof',
+    'await',
+    'extends'
+  ].toSet();
 
   static int category(int code) {
     if (code >= CATEGORIES.length) return OTHER;
diff --git a/pkg/dev_compiler/lib/src/kernel/analyzer_to_kernel.dart b/pkg/dev_compiler/lib/src/kernel/analyzer_to_kernel.dart
new file mode 100644
index 0000000..55e1524
--- /dev/null
+++ b/pkg/dev_compiler/lib/src/kernel/analyzer_to_kernel.dart
@@ -0,0 +1,882 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHO@override S file
+// for 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:core' hide MapEntry;
+import 'dart:collection';
+import 'package:analyzer/analyzer.dart' as a;
+import 'package:analyzer/dart/element/element.dart' as a;
+import 'package:analyzer/dart/element/type.dart' as a;
+import 'package:analyzer/file_system/physical_file_system.dart' as a;
+import 'package:analyzer/src/context/context.dart' as a;
+import 'package:analyzer/src/dart/element/element.dart' as a;
+import 'package:analyzer/src/dart/element/member.dart' as a;
+import 'package:analyzer/src/dart/element/type.dart' as a;
+import 'package:analyzer/src/generated/constant.dart' as a;
+import 'package:analyzer/src/generated/engine.dart' as a;
+import 'package:analyzer/src/generated/source.dart' as a;
+import 'package:analyzer/src/generated/type_system.dart' as a;
+import 'package:analyzer/src/summary/idl.dart' as a;
+import 'package:analyzer/src/summary/package_bundle_reader.dart' as a;
+import 'package:analyzer/src/summary/summary_sdk.dart' as a;
+import 'package:analyzer/src/generated/resolver.dart' as a
+    show NamespaceBuilder, TypeProvider;
+import 'package:front_end/src/fasta/kernel/redirecting_factory_body.dart';
+import 'package:kernel/kernel.dart';
+import 'package:kernel/type_algebra.dart';
+
+import 'type_table.dart';
+
+/// Converts an Analyzer summary file to a Kernel [Component].
+///
+/// The first step is to use Analyzer's [a.StoreBasedSummaryResynthesizer] to
+/// deserialize the summary file into an [a.Element] model (that way we don't
+/// depend directly on the file format). Once we have elements, we visit them
+/// and construct the corresponding Kernel [Node]s.
+///
+/// The main entry points are [convertSdk] and [convertSummaries], which
+/// convert the SDK and input summaries, respectively.
+///
+/// Because we only need to convert summaries, we do not need to handle method
+/// bodies. This lets us avoid the complexity of converting Analyzer AST nodes
+/// (e.g. expressions, statements).
+///
+/// For constants we use Analyzer's constant evaluator compute the value from
+/// the data in the summary, and then create the appropriate Kernel node to
+/// reconstruct the constant (e.g. ListLiteral, ConstructorInvocation, etc).
+/// See [_visitConstant] for more information.
+///
+/// When something refers to an element, we normally create the [Reference] but
+/// leave its corresponding [NamedNode] empty until that element is visited and
+/// creates the Kernel node. This takes care of cycles, and avoids recursing too
+/// deeply as we convert elements.
+///
+/// Sometimes we need to convert an element eagerly (e.g. if we need to call
+/// members on an [InterfaceType] or [Supertype], we need to create its [Class]
+/// node). In that case we handle cycles in the visit method (e.g.
+/// [visitClassElement]) by creating the node and linking it to its reference
+/// before visiting anything else that might recurse.
+///
+/// Special care must be taken to make sure we link up all [Reference]s with
+/// their corresponding [NamedNode]. If we don't do this [verifyReferences]
+/// will throw an error. The fix is to figure out why we didn't visit the
+/// element for that reference (often this is due to Analyzer's synthetic
+/// fields/accessor elements; care must be taken to always reference the real
+/// element).
+///
+/// Because we're using Analyzer's summary resynthesizer, conversion is all or
+/// nothing: all summaries must be in Analyzer format, including the SDK.
+/// Now that we have this implementation, it may be possible to port code from
+/// Analyzer and modify it to resynthesize directly into Kernel trees, if we
+/// ever need to support a mix of Kernel and Analyzer summary files.
+class AnalyzerToKernel {
+  final a.StoreBasedSummaryResynthesizer _resynth;
+  final a.SummaryDataStore _summaryData;
+  final a.TypeProvider types;
+  final a.StrongTypeSystemImpl rules;
+
+  final _references = HashMap<a.Element, Reference>();
+  final _typeParams = HashMap<a.TypeParameterElement, TypeParameter>();
+  final _namespaceBuilder = a.NamespaceBuilder();
+
+  AnalyzerToKernel._(a.AnalysisContext context, this._summaryData)
+      : _resynth = a.StoreBasedSummaryResynthesizer(
+            context, context.sourceFactory, /*strongMode*/ true, _summaryData),
+        types = context.typeProvider,
+        rules = context.typeSystem as a.StrongTypeSystemImpl;
+
+  /// Create an Analyzer summary to Kernel tree converter, using the provided
+  /// [analyzerSdkSummary] and [summaryPaths].
+  ///
+  /// Once the converter is created, [convertSdk] should be called to convert
+  /// & return the SDK, followed by [convertSummaries] to convert & return the
+  /// converted summaries.
+  factory AnalyzerToKernel(
+      String analyzerSdkSummary, List<String> summaryPaths) {
+    var summaryData = a.SummaryDataStore(summaryPaths,
+        resourceProvider: a.PhysicalResourceProvider.INSTANCE,
+        disallowOverlappingSummaries: false);
+    var context = _createContextForSummaries(summaryData, analyzerSdkSummary);
+    return AnalyzerToKernel._(context, summaryData);
+  }
+
+  /// Converts the SDK summary to a Kernel component and returns it.
+  Component convertSdk() {
+    // _createContextForSummaries puts the SDK summary last in the summary data.
+    var sdkBundle = _summaryData.bundles.last;
+    assert(sdkBundle.linkedLibraryUris.every((u) => u.startsWith('dart:')));
+    var result = _toComponent(sdkBundle);
+    verifyReferences();
+    return result;
+  }
+
+  /// Converts the input summaries to Kernel components and return them.
+  ///
+  /// [convertSdk] must be called before this.
+  List<Component> convertSummaries() {
+    // Take all summaries except the SDK one, which is placed last in the list
+    // by _createContextForSummaries.
+    var bundles = _summaryData.bundles.take(_summaryData.bundles.length - 1);
+    var result = bundles.map(_toComponent).toList();
+    verifyReferences(); // assumption: convertSdk() is called first
+    return result;
+  }
+
+  /// Dispose the Analysis Context used for summary conversion.
+  void dispose() => _resynth.context.dispose();
+
+  void verifyReferences() {
+    _references.forEach((element, reference) {
+      // Ensure each reference has a corresponding node.
+      //
+      // If it's missing a node, CFE will fail and it is difficult to debug at
+      // that point because the name and element cannot be accessed.
+      //
+      // Typically this error means:
+      // - we didn't visit an element.
+      // - we didn't set the `reference: _reference(e)` for the Kernel node.
+      // - we referenced a synthetic element by mistake, such as referencing the
+      //   synthetic getter/setter, when we should've used the field.
+      if (reference.node == null) {
+        throw StateError('missing node for reference, element was: $element' +
+            (element.isSynthetic ? ' (synthetic)' : ''));
+      }
+    });
+  }
+
+  Component _toComponent(a.PackageBundle bundle) {
+    var libraries = <Library>[];
+    var uriToSource = <Uri, Source>{};
+
+    void addCompilationUnit(a.CompilationUnitElement unit) {
+      uriToSource[unit.source.uri] = Source(unit.lineInfo.lineStarts, []);
+    }
+
+    for (var uri in bundle.unlinkedUnitUris) {
+      var unitInfo = _resynth.getUnlinkedSummary(uri);
+      if (unitInfo.isPartOf) {
+        // Library parts are handled by their corresponding library.
+        continue;
+      }
+
+      var element = _resynth.getLibraryElement(uri);
+      libraries.add(visitLibraryElement(element));
+      addCompilationUnit(element.definingCompilationUnit);
+      element.parts.forEach(addCompilationUnit);
+    }
+    return Component(libraries: libraries, uriToSource: uriToSource);
+  }
+
+  Class visitClassElement(a.ClassElement e, [Library library]) {
+    var ref = _reference(e);
+    if (ref.node != null) return ref.asClass;
+
+    // Construct the Class first and link the reference. This ensures the
+    // (not yet finished) Class node will be returned on the line above, if we
+    // happen to re-enter this visit method.
+    var class_ = Class(
+        name: e.name,
+        isAbstract: e.isAbstract,
+        fileUri: e.source.uri,
+        reference: ref);
+
+    // Classes can be visited before their library (e.g. because they're a
+    // supertype of another class), so make sure to visit the library now.
+    library ??= visitLibraryElement(e.library);
+    library.addClass(class_);
+
+    class_.typeParameters
+        .addAll(e.typeParameters.map(visitTypeParameterElement));
+
+    setParents(class_.typeParameters, class_);
+    class_.implementedTypes.addAll(e.interfaces.map(_typeToSupertype));
+
+    var fields = class_.fields;
+    var constructors = class_.constructors;
+    var procedures = class_.procedures;
+
+    fields.addAll(e.fields.where((f) => !f.isSynthetic).map(visitFieldElement));
+
+    var redirectingFactories = <Procedure>[];
+    for (var ctor in e.constructors) {
+      if (ctor.isFactory) {
+        var factory_ = _visitFactory(ctor);
+        procedures.add(factory_);
+        if (ctor.redirectedConstructor != null) {
+          redirectingFactories.add(factory_);
+        }
+      } else {
+        constructors.add(visitConstructorElement(ctor));
+      }
+    }
+    if (redirectingFactories.isNotEmpty) {
+      fields.add(_createRedirectingFactoryField(redirectingFactories, e));
+    }
+    procedures.addAll(e.methods.map(visitMethodElement));
+    procedures.addAll(e.accessors
+        .where((a) => !a.isSynthetic)
+        .map(visitPropertyAccessorElement));
+
+    setParents(fields, class_);
+    setParents(constructors, class_);
+    setParents(procedures, class_);
+
+    if (e.isMixinApplication) {
+      class_.mixedInType = _typeToSupertype(e.mixins.last);
+    }
+
+    var supertype = _typeToSupertype(e.supertype);
+    class_.supertype = _unrollMixinClasses(e, supertype, library);
+    _visitAnnotations(e.metadata, class_.addAnnotation);
+
+    // TODO(jmesserly): do we need covariance check stubs? We may be okay as
+    // since we're only handling dependencies here.
+    //
+    // But this may lead to redundant stubs (if CFE doesn't see one on a
+    // superclass) and/or break some assumptions in CFE.
+    return class_;
+  }
+
+  Supertype _unrollMixinClasses(
+      a.ClassElement e, Supertype supertype, Library library) {
+    // TODO(jmesserly): is this enough for mixin desugaring? It only does
+    // enough to create the intermediate classes.
+
+    // Documentation below assumes the given mixin application is in one of
+    // these forms:
+    //
+    //     class C extends S with M1, M2, M3;
+    //     class Named = S with M1, M2, M3;
+    //
+    // When we refer to the subclass, we mean `C` or `Named`.
+
+    /// The number of mixin classes to unroll.
+    ///
+    /// Named mixin applications have one less class. This can be illustrated
+    /// here:
+    ///
+    ///     class C extends S with M1, M2, M3 {}
+    ///     class Named = S with M1, M2, M3;
+    ///
+    /// For `C` we unroll 3 classes: _C&S&M1, _C&S&M1&M2, _C&S&M1&M2&M3.
+    /// For `Named` we unroll 2 classes: _Named&S&M1, _Named&S&M1&M2.
+    ///
+    /// The classes themselves will be generated as:
+    ///
+    ///     class C extends _C&S&M1&M2&M3 {}
+    ///     class Named = _Named&S&M1&M2 with M3;
+    ///
+    var unrollLength = e.mixins.length;
+    if (e.isMixinApplication) unrollLength--;
+    if (unrollLength <= 0) return supertype;
+
+    /// The mixin application's synthetic name.
+    ///
+    /// The full name of the mixin application is obtained by prepending the
+    /// name of the subclass (`C` or `Named` in the above examples) to the
+    /// running name. For the example `C`, that leads to these names:
+    ///
+    /// 1. `_C&S&M1`
+    /// 2. `_C&S&M1&M2`
+    /// 3. `_C&S&M1&M2&M3`.
+    var runningName = '_${e.name}&${e.supertype.name}';
+
+    /// The type variables used in the current supertype and mixin, or null
+    /// if this class doesn't have any type parameters.
+    var usedTypeVars = e.typeParameters.isNotEmpty
+        ? freeTypeParameters(supertype.asInterfaceType)
+        : null;
+
+    for (int i = 0; i < unrollLength; i++) {
+      var mixin = e.mixins[i];
+      runningName += "&${mixin.name}";
+
+      var mixedInType = _typeToSupertype(mixin);
+      List<TypeParameter> typeParameters;
+      if (usedTypeVars != null) {
+        // Any type params used by superclasses will continue to be used, plus
+        // anything additional that this mixin uses.
+        usedTypeVars.addAll(freeTypeParameters(mixedInType.asInterfaceType));
+        if (usedTypeVars.isNotEmpty) {
+          // Make fresh type parameters for this class, and then substitute them
+          // into supertype and mixin type arguments (if any).
+          var fresh = getFreshTypeParameters(usedTypeVars.toList());
+          typeParameters = fresh.freshTypeParameters;
+          supertype = fresh.substituteSuper(supertype);
+          mixedInType = fresh.substituteSuper(mixedInType);
+        }
+      }
+
+      var c = Class(
+          name: runningName,
+          isAbstract: e.isAbstract,
+          mixedInType: mixedInType,
+          supertype: supertype,
+          typeParameters: typeParameters,
+          fileUri: e.source.uri);
+
+      library.addClass(c);
+
+      // Compute the superclass to use for the next iteration of this loop.
+      //
+      // Any type arguments are in terms of the original class type parameters.
+      // This allows us to perform consistent subsititions and have the correct
+      // type arguments for the final supertype (that we return).
+      supertype = Supertype(
+          c,
+          typeParameters != null
+              ? List.of(usedTypeVars.map((t) => TypeParameterType(t)))
+              : []);
+    }
+
+    return supertype;
+  }
+
+  Constructor visitConstructorElement(a.ConstructorElement e) {
+    assert(!e.isFactory);
+    var ref = _reference(e);
+    if (ref.node != null) return ref.asConstructor;
+    // By convention, instance constructors return `void` in Kernel.
+    var function = _createFunction(e)..returnType = const VoidType();
+    var result = Constructor(function,
+        name: _getName(e),
+        isConst: e.isConst,
+        isExternal: e.isExternal,
+        isSynthetic: e.isSynthetic,
+        fileUri: e.source.uri,
+        reference: ref);
+    if (!result.isSynthetic) {
+      // TODO(jmesserly): CFE does not respect the synthetic bit on constructors
+      // so we set a bogus offset. This causes CFE to treat it as not synthetic.
+      //
+      // (The bug is in DillMemberBuilder.isSythetic. Sythetic constructors have
+      // different semantics/optimizations in some cases, so it is important
+      // that the constructor is correctly marked.)
+      result.fileOffset = 1;
+    }
+    _visitAnnotations(e.metadata, result.addAnnotation);
+    return result;
+  }
+
+  Procedure _visitFactory(a.ConstructorElement e) {
+    var ref = _reference(e);
+    if (ref.node != null) return ref.asProcedure;
+
+    var result = Procedure.byReference(_getName(e), ProcedureKind.Factory, null,
+        isExternal: e.isExternal,
+        isConst: e.isConst,
+        isStatic: true,
+        fileUri: e.source.uri,
+        reference: ref);
+
+    _visitAnnotations(e.metadata, result.addAnnotation);
+
+    // Since the factory is static, we need to create fresh type parameters that
+    // match the ones in the enclosing class.
+    FreshTypeParameters fresh;
+    DartType Function(a.DartType) visitType;
+
+    if (e.enclosingElement.typeParameters.isNotEmpty) {
+      fresh = getFreshTypeParameters(
+          visitClassElement(e.enclosingElement).typeParameters);
+      visitType = (t) => fresh.substitute(_visitDartType(t, ensureNode: true));
+    } else {
+      visitType = _visitDartType;
+    }
+
+    result.function = _createFunction(e, fresh?.freshTypeParameters, visitType);
+    result.function.parent = result;
+
+    var redirect = e.redirectedConstructor;
+    if (redirect == null) return result;
+
+    // Get the raw constructor element before the type is applied.
+    var rawRedirect =
+        redirect is a.ConstructorMember ? redirect.baseElement : redirect;
+
+    // TODO(jmesserly): conceptually we only need a reference here, but
+    // RedirectingFactoryBody requires the complete node.
+    var ctor = rawRedirect.isFactory
+        ? _visitFactory(rawRedirect)
+        : visitConstructorElement(rawRedirect);
+
+    var redirectedType = redirect.type.returnType as a.InterfaceType;
+    var typeArgs = redirectedType.typeArguments.map(visitType).toList();
+    result.function.body = RedirectingFactoryBody(ctor, typeArgs);
+    return result;
+  }
+
+  Field _createRedirectingFactoryField(
+      List<Procedure> factories, a.ClassElement c) {
+    return Field(_getName(c, "_redirecting#"),
+        isStatic: true,
+        initializer: ListLiteral(List.of(factories.map((f) => StaticGet(f)))),
+        fileUri: c.source.uri);
+  }
+
+  LibraryDependency visitExportElement(a.ExportElement e) =>
+      LibraryDependency.byReference(
+          LibraryDependency.ExportFlag,
+          const [],
+          _reference(e.exportedLibrary),
+          null,
+          e.combinators.map(_visitCombinator).toList());
+
+  Field visitFieldElement(a.FieldElement e) {
+    var result = Field(_getName(e),
+        type: _visitDartType(e.type),
+        initializer: null,
+        isFinal: e.isFinal,
+        isConst: e.isConst,
+        isStatic: e.isStatic,
+        fileUri: e.source.uri,
+        reference: _reference(e));
+    if (!e.isFinal && !e.isConst) {
+      var class_ = e.enclosingElement;
+      if (class_.typeParameters.isNotEmpty) {
+        result.isGenericCovariantImpl = _isGenericCovariant(class_, e.type);
+      }
+    }
+    _visitAnnotations(e.metadata, result.addAnnotation);
+    return result;
+  }
+
+  Procedure visitFunctionElement(a.FunctionElement e) {
+    var result = Procedure.byReference(
+        _getName(e), ProcedureKind.Method, _createFunction(e),
+        isExternal: e.isExternal,
+        fileUri: e.source.uri,
+        isStatic: true,
+        reference: _reference(e));
+    _visitAnnotations(e.metadata, result.addAnnotation);
+    return result;
+  }
+
+  Typedef visitFunctionTypeAliasElement(a.FunctionTypeAliasElement e,
+      [Library library]) {
+    var ref = _reference(e);
+    if (ref.node != null) return ref.asTypedef;
+
+    var t = Typedef(e.name, null, reference: ref, fileUri: e.source.uri);
+    library ??= visitLibraryElement(e.library);
+    library.addTypedef(t);
+
+    a.FunctionType type;
+    var typeParams = e.typeParameters;
+    if (e is a.GenericTypeAliasElement) {
+      type = e.function.type;
+    } else {
+      type = e.type;
+      if (typeParams.isNotEmpty) {
+        // Skip past the type formals, we'll add them back below, so these
+        // type parameter names will end up in scope in the generated JS.
+        type = type.instantiate(typeParams.map((f) => f.type).toList());
+      }
+    }
+    t.typeParameters.addAll(typeParams.map(visitTypeParameterElement));
+    setParents(t.typeParameters, t);
+    t.type = _visitDartType(type);
+    _visitAnnotations(e.metadata, t.addAnnotation);
+    return t;
+  }
+
+  LibraryDependency visitImportElement(a.ImportElement e) =>
+      LibraryDependency.byReference(0, const [], _reference(e.importedLibrary),
+          null, e.combinators.map(_visitCombinator).toList());
+
+  Library visitLibraryElement(a.LibraryElement e) {
+    var ref = _reference(e);
+    if (ref.node != null) return ref.asLibrary;
+
+    var library = Library(e.source.uri,
+        name: e.name,
+        fileUri: e.definingCompilationUnit.source.uri,
+        reference: ref);
+    library.fileOffset = 0;
+
+    _visitAnnotations(e.metadata, library.addAnnotation);
+    e.imports.map(visitImportElement).forEach(library.addDependency);
+    e.exports.map(visitExportElement).forEach(library.addDependency);
+    e.parts.map((p) => LibraryPart(const [], p.uri)).forEach(library.addPart);
+
+    _visitUnit(a.CompilationUnitElement u) {
+      for (var t in u.types) {
+        visitClassElement(t, library);
+      }
+      for (var t in u.functionTypeAliases) {
+        visitFunctionTypeAliasElement(t, library);
+      }
+      u.functions.map(visitFunctionElement).forEach(library.addMember);
+      u.accessors
+          .where((a) => !a.isSynthetic)
+          .map(visitPropertyAccessorElement)
+          .forEach(library.addMember);
+      u.topLevelVariables
+          .map(visitTopLevelVariableElement)
+          .forEach(library.addMember);
+    }
+
+    _visitUnit(e.definingCompilationUnit);
+    e.parts.forEach(_visitUnit);
+
+    var libraryImpl = e as a.LibraryElementImpl;
+    libraryImpl.publicNamespace ??=
+        _namespaceBuilder.createPublicNamespaceForLibrary(e);
+    libraryImpl.exportNamespace ??=
+        _namespaceBuilder.createExportNamespaceForLibrary(e);
+    var publicNames = libraryImpl.publicNamespace.definedNames;
+    var exportNames = libraryImpl.exportNamespace.definedNames;
+    exportNames.forEach((name, value) {
+      if (!publicNames.containsKey(name)) {
+        value = value is a.PropertyAccessorElement && value.isSynthetic
+            ? value.variable
+            : value;
+        library.additionalExports.add(_reference(value));
+      }
+    });
+    return library;
+  }
+
+  Procedure visitMethodElement(a.MethodElement e) {
+    var result = Procedure.byReference(
+        _getName(e),
+        e.isOperator ? ProcedureKind.Operator : ProcedureKind.Method,
+        _createFunction(e),
+        isAbstract: e.isAbstract,
+        isStatic: e.isStatic,
+        isExternal: e.isExternal,
+        fileUri: e.source.uri,
+        reference: _reference(e));
+    _visitAnnotations(e.metadata, result.addAnnotation);
+    return result;
+  }
+
+  Procedure visitPropertyAccessorElement(a.PropertyAccessorElement e) {
+    var result = Procedure.byReference(
+        _getName(e, e.variable.name),
+        e.isGetter ? ProcedureKind.Getter : ProcedureKind.Setter,
+        _createFunction(e),
+        isAbstract: e.isAbstract,
+        isStatic: e.isStatic,
+        isExternal: e.isExternal,
+        fileUri: e.source.uri,
+        reference: _reference(e));
+    _visitAnnotations(e.metadata, result.addAnnotation);
+    return result;
+  }
+
+  Field visitTopLevelVariableElement(a.TopLevelVariableElement e) {
+    var result = Field(_getName(e),
+        type: _visitDartType(e.type),
+        initializer: null,
+        isFinal: e.isFinal,
+        isConst: e.isConst,
+        isStatic: e.isStatic,
+        fileUri: e.source.uri,
+        reference: _reference(e));
+    _visitAnnotations(e.metadata, result.addAnnotation);
+    return result;
+  }
+
+  TypeParameter visitTypeParameterElement(a.TypeParameterElement e) {
+    var t = _typeParams[e];
+    if (t != null) return t;
+    _typeParams[e] = t = TypeParameter(e.name);
+
+    var hasBound = e.bound != null;
+    t.bound =
+        hasBound ? _visitDartType(e.bound) : _visitDartType(types.objectType);
+    t.defaultType = hasBound ? t.bound : const DynamicType();
+
+    var enclosingElement = e.enclosingElement;
+    if (hasBound && enclosingElement is a.ClassMemberElement) {
+      var class_ = enclosingElement.enclosingElement;
+      if (class_ != null && class_.typeParameters.isNotEmpty) {
+        t.isGenericCovariantImpl = _isGenericCovariant(class_, e.bound);
+      }
+    }
+    return t;
+  }
+
+  Name _getName(a.Element e, [String name]) {
+    name ??= e.name;
+    return Name.byReference(
+        name, name.startsWith('_') ? _reference(e.library) : null);
+  }
+
+  /// Converts an Analyzer [type] to a Kernel type.
+  ///
+  /// If [ensureNode] is set, the reference to the [Class] or [Typedef] will
+  /// populated with the node (creating it if needed). Many members on
+  /// [InterfaceType] and [TypedefType] rely on having a node present, so this
+  /// enables the use of those members if they're needed by the converter.
+  DartType _visitDartType(a.DartType type, {bool ensureNode = false}) {
+    if (type.isVoid) {
+      return const VoidType();
+    } else if (type.isDynamic) {
+      return const DynamicType();
+    } else if (type.isBottom) {
+      return const BottomType();
+    } else if (type is a.TypeParameterType) {
+      return TypeParameterType(visitTypeParameterElement(type.element));
+    }
+
+    visit(a.DartType t) => _visitDartType(t, ensureNode: ensureNode);
+
+    if (type is a.InterfaceType) {
+      var ref = ensureNode
+          ? visitClassElement(type.element).reference
+          : _reference(type.element);
+      var typeArgs = type.typeArguments;
+      var newTypeArgs = typeArgs.isNotEmpty
+          ? typeArgs.map(visit).toList()
+          : const <DartType>[];
+      return InterfaceType.byReference(ref, newTypeArgs);
+    }
+
+    var f = type as a.FunctionType;
+    if (f.name != null && f.name != '') {
+      var ref = ensureNode
+          ? visitFunctionTypeAliasElement(f.element).reference
+          : _reference(f.element);
+      return TypedefType.byReference(ref, f.typeArguments.map(visit).toList());
+    }
+    var params = f.parameters;
+    var positional = f.normalParameterTypes.map(visit).toList();
+    positional.addAll(f.optionalParameterTypes.map(visit));
+
+    var named = <NamedType>[];
+    f.namedParameterTypes.forEach((name, type) {
+      named.add(NamedType(name, visit(type)));
+    });
+
+    return FunctionType(positional, visit(f.returnType),
+        typeParameters: f.typeFormals.map(visitTypeParameterElement).toList(),
+        namedParameters: named,
+        requiredParameterCount: params.where((p) => !p.isOptional).length);
+  }
+
+  Supertype _typeToSupertype(a.InterfaceType t) {
+    if (t == null) return null;
+    return Supertype(
+        visitClassElement(t.element),
+        t.typeArguments
+            .map((a) => _visitDartType(a, ensureNode: true))
+            .toList());
+  }
+
+  Combinator _visitCombinator(a.NamespaceCombinator combinator) {
+    bool isShow;
+    List<String> names;
+    if (combinator is a.ShowElementCombinator) {
+      isShow = true;
+      names = combinator.shownNames;
+    } else {
+      isShow = false;
+      names = (combinator as a.HideElementCombinator).hiddenNames;
+    }
+    return Combinator(isShow, names);
+  }
+
+  /// Creates a function node for the executable element [e], optionally using
+  /// the supplied [typeParameters] and calling [visitType] so it can perform
+  /// any necessary substitutions.
+  FunctionNode _createFunction(a.ExecutableElement e,
+      [List<TypeParameter> typeParameters,
+      DartType Function(a.DartType) visitType]) {
+    visitType ??= _visitDartType;
+
+    var enclosingElement = e.enclosingElement;
+    var class_ = enclosingElement is a.ClassElement ? enclosingElement : null;
+
+    visitParameter(a.ParameterElement e) {
+      var result = VariableDeclaration(e.name,
+          type: visitType(e.type),
+          isFinal: e.isFinal,
+          isFieldFormal: e.isInitializingFormal,
+          isCovariant: e.isCovariant,
+          initializer:
+              e.isOptional ? _visitConstant(e.computeConstantValue()) : null);
+      if (class_ != null && class_.typeParameters.isNotEmpty) {
+        result.isGenericCovariantImpl = _isGenericCovariant(class_, e.type);
+      }
+      return result;
+    }
+
+    var params = e.parameters;
+    var asyncMarker = _getAsyncMarker(e);
+    return FunctionNode(null,
+        typeParameters: typeParameters ??
+            e.typeParameters.map(visitTypeParameterElement).toList(),
+        positionalParameters:
+            params.where((p) => !p.isNamed).map(visitParameter).toList(),
+        namedParameters:
+            params.where((p) => p.isNamed).map(visitParameter).toList(),
+        requiredParameterCount: params.where((p) => !p.isOptional).length,
+        returnType: visitType(e.returnType),
+        asyncMarker: asyncMarker,
+        dartAsyncMarker: asyncMarker);
+  }
+
+  Reference _reference(a.Element e) {
+    if (e == null) throw ArgumentError('null element');
+    return _references.putIfAbsent(e, () => Reference());
+  }
+
+  bool _isGenericCovariant(a.ClassElement c, a.DartType type) {
+    var classUpperBound = rules.instantiateToBounds(c.type) as a.InterfaceType;
+    var typeUpperBound = type.substitute2(classUpperBound.typeArguments,
+        a.TypeParameterTypeImpl.getTypes(classUpperBound.typeParameters));
+    // Is it safe to assign the upper bound of the field/parameter to it?
+    // If not then we'll need a runtime check.
+    return !rules.isSubtypeOf(typeUpperBound, type);
+  }
+
+  /// Transforms a metadata annotation from Analyzer to Kernel format.
+  ///
+  /// If needed this uses Analyzer's constant evaluation to evaluate the AST,
+  /// and then converts the resulting constant value into a Kernel tree.
+  /// By first computing the expression's constant value, we avoid having to
+  /// convert a bunch of Analyzer ASTs nodes. Instead we can convert the more
+  /// limited set of constant values allowed in Dart (see [_visitConstant]).
+  void _visitAnnotations(List<a.ElementAnnotation> metadata,
+      void Function(Expression) addAnnotation) {
+    if (metadata.isEmpty) return;
+
+    for (a.ElementAnnotationImpl annotation in metadata) {
+      var ast = annotation.annotationAst;
+      var arguments = ast.arguments;
+      if (arguments == null) {
+        var e = ast.element;
+        e = e is a.PropertyAccessorElement && e.isSynthetic ? e.variable : e;
+        addAnnotation(StaticGet.byReference(_reference(e)));
+      } else {
+        // Use Analyzer's constant evaluation to produce the constant, then
+        // emit the resulting value. We do this to avoid handling all of the
+        // AST nodes that might be needed for constant evaluation. Instead we
+        // just serialize the resulting value to a Kernel expression that will
+        // reproduce it.
+        addAnnotation(_visitConstant(annotation.computeConstantValue()));
+      }
+    }
+  }
+
+  /// Converts an Analyzer constant value in [obj] to a Kernel expression
+  /// (usually a Literal or ConstructorInvocation) that will recreate that
+  /// constant value.
+  Expression _visitConstant(a.DartObject obj) {
+    if (obj == null || obj.isNull || !obj.hasKnownValue) return NullLiteral();
+
+    var type = obj.type;
+    if (identical(type, types.boolType)) {
+      var value = obj.toBoolValue();
+      return value != null ? BoolLiteral(value) : NullLiteral();
+    }
+    if (identical(type, types.intType)) {
+      return IntLiteral(obj.toIntValue());
+    }
+    if (identical(type, types.doubleType)) {
+      return DoubleLiteral(obj.toDoubleValue());
+    }
+    if (identical(type, types.stringType)) {
+      return StringLiteral(obj.toStringValue());
+    }
+    if (identical(type, types.symbolType)) {
+      return SymbolLiteral(obj.toSymbolValue());
+    }
+    if (identical(type, types.typeType)) {
+      return TypeLiteral(_visitDartType(obj.toTypeValue()));
+    }
+    if (type is a.InterfaceType) {
+      if (type.element == types.listType.element) {
+        return ListLiteral(obj.toListValue().map(_visitConstant).toList(),
+            typeArgument: _visitDartType(type.typeArguments[0]), isConst: true);
+      }
+      if (type.element == types.mapType.element) {
+        var entries = obj
+            .toMapValue()
+            .entries
+            .map(
+                (e) => MapEntry(_visitConstant(e.key), _visitConstant(e.value)))
+            .toList();
+        return MapLiteral(entries,
+            keyType: _visitDartType(type.typeArguments[0]),
+            valueType: _visitDartType(type.typeArguments[1]),
+            isConst: true);
+      }
+      if (obj is a.DartObjectImpl && obj.isUserDefinedObject) {
+        var classElem = type.element;
+        if (classElem.isEnum) {
+          // TODO(jmesserly): we should be able to use `getField('index')` but
+          // in some cases Analyzer uses the name of the static field that
+          // contains the enum, rather than the `index` field, due to a bug.
+          //
+          // So we just grab the one instance field, regardless of its name.
+          var index = obj.fields.values.single.toIntValue();
+          var field =
+              classElem.fields.where((f) => f.type == type).elementAt(index);
+          return StaticGet.byReference(_reference(field));
+        }
+        var invocation = obj.getInvocation();
+        var constructor = invocation.constructor;
+        // For a redirecting const factory, the constant constructor will be
+        // from the original one, but the `type` will match the redirected type.
+        //
+        // This leads to mismatch in how we call this constructor. So we need to
+        // find the redirected one.
+        for (var rc; (rc = constructor.redirectedConstructor) != null;) {
+          constructor = rc;
+        }
+        constructor = constructor is a.ConstructorMember
+            ? constructor.baseElement
+            : constructor;
+        return ConstructorInvocation.byReference(
+            _reference(constructor),
+            Arguments(
+                invocation.positionalArguments.map(_visitConstant).toList(),
+                named: invocation.namedArguments.entries
+                    .map((e) => NamedExpression(e.key, _visitConstant(e.value)))
+                    .toList(),
+                types: type.typeArguments.map(_visitDartType).toList()),
+            isConst: true);
+      }
+    }
+    if (obj is a.DartObjectImpl && type is a.FunctionType) {
+      var e = obj.toFunctionValue();
+      e = e is a.PropertyAccessorElement && e.isSynthetic ? e.variable : e;
+      // TODO(jmesserly): support generic tear-off implicit instantiation.
+      return StaticGet.byReference(_reference(e));
+    }
+    throw UnsupportedError('unknown constant type `$type`: $obj');
+  }
+}
+
+AsyncMarker _getAsyncMarker(a.ExecutableElement e) {
+  return e.isGenerator
+      ? (e.isAsynchronous ? AsyncMarker.AsyncStar : AsyncMarker.SyncStar)
+      : (e.isAsynchronous ? AsyncMarker.Async : AsyncMarker.Sync);
+}
+
+/// Creates a dummy Analyzer context so we can use summary resynthesizer.
+///
+/// This is similar to Analyzer's `LibraryContext._createResynthesizingContext`.
+a.AnalysisContext _createContextForSummaries(
+    a.SummaryDataStore summaryData, String dartSdkPath) {
+  var sdk = a.SummaryBasedDartSdk(dartSdkPath, true,
+      resourceProvider: a.PhysicalResourceProvider.INSTANCE);
+  var sdkSummaryBundle = sdk.getLinkedBundle();
+  if (sdkSummaryBundle != null) {
+    summaryData.addBundle(null, sdkSummaryBundle);
+  }
+
+  // TODO(jmesserly): can we avoid creating an analysis context entirely?
+  // It doesn't look like StoreBasedSummaryResynthesizer uses much of it.
+  var context = a.AnalysisEngine.instance.createAnalysisContext()
+      as a.AnalysisContextImpl;
+  context.sourceFactory = a.SourceFactory(
+      [a.DartUriResolver(sdk), a.InSummaryUriResolver(null, summaryData)]);
+  context.useSdkCachePartition = false;
+  // TODO(jmesserly): do we need to set analysisOptions or declaredVariables?
+  context.resultProvider = a.InputPackagesResultProvider(context, summaryData);
+  return context;
+}
diff --git a/pkg/dev_compiler/lib/src/kernel/command.dart b/pkg/dev_compiler/lib/src/kernel/command.dart
index 153ab71..728ed88 100644
--- a/pkg/dev_compiler/lib/src/kernel/command.dart
+++ b/pkg/dev_compiler/lib/src/kernel/command.dart
@@ -21,6 +21,8 @@
 import '../compiler/shared_command.dart';
 import '../js_ast/js_ast.dart' as JS;
 import '../js_ast/source_map_printer.dart' show SourceMapPrintingContext;
+
+import 'analyzer_to_kernel.dart';
 import 'compiler.dart';
 import 'target.dart';
 
@@ -129,12 +131,13 @@
 
   var options = SharedCompilerOptions.fromArguments(argResults);
   var ddcPath = path.dirname(path.dirname(path.fromUri(Platform.script)));
+  var summaryPaths = options.summaryModules.keys.toList();
   var summaryModules = Map.fromIterables(
-      options.summaryModules.keys.map(sourcePathToUri),
-      options.summaryModules.values);
-
-  var sdkSummaryPath =
-      argResults['dart-sdk-summary'] as String ?? defaultSdkSummaryPath;
+      summaryPaths.map(sourcePathToUri), options.summaryModules.values);
+  var useAnalyzer = summaryPaths.any((s) => !s.endsWith('.dill'));
+  var sdkSummaryPath = argResults['dart-sdk-summary'] as String ??
+      (useAnalyzer ? defaultAnalyzerSdkSummaryPath : defaultSdkSummaryPath);
+  useAnalyzer = useAnalyzer || !sdkSummaryPath.endsWith('.dill');
 
   var packageFile = argResults['packages'] as String ??
       path.absolute(ddcPath, '..', '..', '.packages');
@@ -156,6 +159,22 @@
       summaryModules.keys.toList(),
       DevCompilerTarget(),
       fileSystem: fileSystem);
+
+  var output = argResults['out'] as String;
+  // TODO(jmesserly): is there a cleaner way to do this?
+  //
+  // Ideally we'd manage our own batch compilation caching rather than rely on
+  // `initializeCompiler`. Also we should be able to pass down Components for
+  // SDK and summaries.
+  //
+  if (useAnalyzer && !identical(oldCompilerState, compilerState)) {
+    var opts = compilerState.processedOpts;
+    var converter = AnalyzerToKernel(sdkSummaryPath, summaryPaths);
+    opts.sdkSummaryComponent = converter.convertSdk();
+    opts.inputSummariesComponents = converter.convertSummaries();
+    converter.dispose();
+  }
+
   fe.DdcResult result = await fe.compile(compilerState, inputs, errorHandler);
   if (result == null || !succeeded) {
     return CompilerResult(compilerState, false);
@@ -166,7 +185,6 @@
     return CompilerResult(compilerState, false);
   }
 
-  String output = argResults['out'];
   var file = File(output);
   await file.parent.create(recursive: true);
 
@@ -193,7 +211,6 @@
     kernel.Printer(sink, showExternal: false).writeComponentFile(component);
     outFiles.add(sink.flush().then((_) => sink.close()));
   }
-
   var compiler = ProgramCompiler(component, options, declaredVariables);
   var jsModule =
       compiler.emitModule(component, result.inputSummaries, summaryModules);
@@ -307,6 +324,12 @@
     '_internal',
     'ddc_sdk.dill');
 
+final defaultAnalyzerSdkSummaryPath = path.join(
+    path.dirname(path.dirname(Platform.resolvedExecutable)),
+    'lib',
+    '_internal',
+    'ddc_sdk.sum');
+
 bool _checkForDartMirrorsImport(Component component) {
   for (var library in component.libraries) {
     if (library.isExternal) continue;
diff --git a/pkg/dev_compiler/lib/src/kernel/compiler.dart b/pkg/dev_compiler/lib/src/kernel/compiler.dart
index f9ce5c8..970cc7a 100644
--- a/pkg/dev_compiler/lib/src/kernel/compiler.dart
+++ b/pkg/dev_compiler/lib/src/kernel/compiler.dart
@@ -559,7 +559,9 @@
     _emitVirtualFieldSymbols(c, body);
     _emitClassSignature(c, className, body);
     _initExtensionSymbols(c);
-    _defineExtensionMembers(className, body);
+    if (!isMixinDeclaration(c)) {
+      _defineExtensionMembers(className, body);
+    }
     _emitClassMetadata(c.annotations, className, body);
 
     var classDef = JS.Statement.from(body);
@@ -619,6 +621,67 @@
     return js.statement('# = #;', [className, classExpr]);
   }
 
+  /// Like [_emitClassStatement] but emits a Dart 2.1 mixin represented by
+  /// [c].
+  ///
+  /// Mixins work similar to normal classes, but their instance methods close
+  /// over the actual superclass. Given a Dart class like:
+  ///
+  ///     mixin M on C {
+  ///       foo() => super.foo() + 42;
+  ///     }
+  ///
+  /// We generate a JS class like this:
+  ///
+  ///     lib.M = class M extends core.Object {}
+  ///     lib.M[dart.mixinOn] = (C) => class M extends C {
+  ///       foo() {
+  ///         return super.foo() + 42;
+  ///       }
+  ///     };
+  ///
+  /// The special `dart.mixinOn` symbolized property is used by the runtime
+  /// helper `dart.applyMixin`. The helper calls the function with the actual
+  /// base class, and then copies the resulting members to the destination
+  /// class.
+  ///
+  /// In the long run we may be able to improve this so we do not have the
+  /// unnecessary class, but for now, this lets us get the right semantics with
+  /// minimal compiler and runtime changes.
+  void _emitMixinStatement(
+      Class c,
+      JS.Expression className,
+      JS.Expression heritage,
+      List<JS.Method> methods,
+      List<JS.Statement> body) {
+    var staticMethods = methods.where((m) => m.isStatic).toList();
+    var instanceMethods = methods.where((m) => !m.isStatic).toList();
+
+    body.add(_emitClassStatement(c, className, heritage, staticMethods));
+    var superclassId = JS.TemporaryId(getLocalClassName(c.superclass));
+    var classId = className is JS.Identifier
+        ? className
+        : JS.TemporaryId(getLocalClassName(c));
+
+    var mixinMemberClass =
+        JS.ClassExpression(classId, superclassId, instanceMethods);
+
+    JS.Node arrowFnBody = mixinMemberClass;
+    var extensionInit = <JS.Statement>[];
+    _defineExtensionMembers(classId, extensionInit);
+    if (extensionInit.isNotEmpty) {
+      extensionInit.insert(0, mixinMemberClass.toStatement());
+      extensionInit.add(classId.toReturn());
+      arrowFnBody = JS.Block(extensionInit);
+    }
+
+    body.add(js.statement('#[#.mixinOn] = #', [
+      className,
+      runtimeModule,
+      JS.ArrowFun([superclassId], arrowFnBody)
+    ]));
+  }
+
   void _defineClass(Class c, JS.Expression className, List<JS.Method> methods,
       List<JS.Statement> body, List<JS.Statement> deferredSupertypes) {
     if (c == coreTypes.objectClass) {
@@ -746,7 +809,7 @@
       var classExpr = deferMixin ? getBaseClass(0) : className;
 
       mixinBody
-          .add(runtimeStatement('mixinMembers(#, #)', [classExpr, mixinClass]));
+          .add(runtimeStatement('applyMixin(#, #)', [classExpr, mixinClass]));
 
       if (methods.isNotEmpty) {
         // However we may need to add some methods to this class that call
@@ -754,8 +817,8 @@
         //
         // We do this with the following pattern:
         //
-        //     mixinMembers(C, class C$ extends M { <methods>  });
-        mixinBody.add(runtimeStatement('mixinMembers(#, #)', [
+        //     applyMixin(C, class C$ extends M { <methods>  });
+        mixinBody.add(runtimeStatement('applyMixin(#, #)', [
           classExpr,
           JS.ClassExpression(
               JS.TemporaryId(getLocalClassName(c)), mixinClass, methods)
@@ -790,17 +853,22 @@
       hasUnnamedSuper = hasUnnamedSuper || _hasUnnamedConstructor(m.classNode);
 
       if (shouldDefer(m)) {
-        deferredSupertypes.add(runtimeStatement('mixinMembers(#, #)',
+        deferredSupertypes.add(runtimeStatement('applyMixin(#, #)',
             [getBaseClass(mixins.length - i), emitDeferredType(m)]));
       } else {
         body.add(
-            runtimeStatement('mixinMembers(#, #)', [mixinId, emitClassRef(m)]));
+            runtimeStatement('applyMixin(#, #)', [mixinId, emitClassRef(m)]));
       }
 
       baseClass = mixinId;
     }
 
-    body.add(_emitClassStatement(c, className, baseClass, methods));
+    if (isMixinDeclaration(c)) {
+      _emitMixinStatement(c, className, baseClass, methods, body);
+    } else {
+      body.add(_emitClassStatement(c, className, baseClass, methods));
+    }
+
     _classEmittingExtends = savedTopLevelClass;
   }
 
@@ -1582,7 +1650,14 @@
 
     var savedUri = _currentUri;
     for (var m in c.procedures) {
-      _currentUri = m.fileUri ?? savedUri;
+      // For the Dart SDK, we use the member URI because it may be different
+      // from the class (because of patch files). User code does not need this.
+      //
+      // TODO(jmesserly): CFE has a bug(?) where nSM forwarders sometimes have a
+      // bogus file URI, that is mismatched compared to the offsets. This causes
+      // a crash when we look up the location. So for those forwarders, we just
+      // suppress source spans.
+      _currentUri = m.isNoSuchMethodForwarder ? null : (m.fileUri ?? savedUri);
       if (_isForwardingStub(m)) {
         // TODO(jmesserly): is there any other kind of forwarding stub?
         jsMethods.addAll(_emitCovarianceCheckStub(m));
@@ -4036,10 +4111,12 @@
 
       if (_typeRep.binaryOperationIsPrimitive(leftType, rightType) ||
           leftType == types.stringType && op == '+') {
-        // special cases where we inline the operation
-        // these values are assumed to be non-null (determined by the checker)
-        // TODO(jmesserly): it would be nice to just inline the method from core,
-        // instead of special cases here.
+        // Inline operations on primitive types where possible.
+        // TODO(jmesserly): inline these from dart:core instead of hardcoding
+        // the implementation details here.
+
+        /// Emits an inlined binary operation using the JS [code], adding null
+        /// checks if needed to ensure we throw the appropriate error.
         JS.Expression binary(String code) {
           return js.call(code, [notNull(left), notNull(right)]);
         }
@@ -4048,6 +4125,15 @@
           return _coerceBitOperationResultToUnsigned(node, binary(code));
         }
 
+        /// Similar to [binary] but applies a boolean conversion to the right
+        /// operand, to match the boolean bitwise operators in dart:core.
+        ///
+        /// Short circuiting operators should not be used in [code], because the
+        /// null checks for both operands must happen unconditionally.
+        JS.Expression bitwiseBool(String code) {
+          return js.call(code, [notNull(left), _visitTest(right)]);
+        }
+
         switch (op) {
           case '~/':
             // `a ~/ b` is equivalent to `(a / b).truncate()`
@@ -4063,13 +4149,19 @@
             return _emitOperatorCall(left, target, op, [right]);
 
           case '&':
-            return bitwise('# & #');
+            return _typeRep.isBoolean(leftType)
+                ? bitwiseBool('!!(# & #)')
+                : bitwise('# & #');
 
           case '|':
-            return bitwise('# | #');
+            return _typeRep.isBoolean(leftType)
+                ? bitwiseBool('!!(# | #)')
+                : bitwise('# | #');
 
           case '^':
-            return bitwise('# ^ #');
+            return _typeRep.isBoolean(leftType)
+                ? bitwiseBool('# !== #')
+                : bitwise('# ^ #');
 
           case '>>':
             int shiftCount = _asIntInRange(right, 0, 31);
@@ -4975,6 +5067,8 @@
   @override
   defaultConstant(Constant node) => _emitInvalidNode(node);
   @override
+  visitSymbolConstant(node) => defaultConstant(node);
+  @override
   visitMapConstant(node) => defaultConstant(node);
   @override
   visitListConstant(node) => defaultConstant(node);
diff --git a/pkg/dev_compiler/lib/src/kernel/constants.dart b/pkg/dev_compiler/lib/src/kernel/constants.dart
index 60a79c7..8838cae 100644
--- a/pkg/dev_compiler/lib/src/kernel/constants.dart
+++ b/pkg/dev_compiler/lib/src/kernel/constants.dart
@@ -304,14 +304,6 @@
       throw StateError('unreachable'); // DDC does not use VM native syntax
 
   @override
-  buildSymbolConstant(StringConstant value) {
-    return InstanceConstant(
-        coreTypes.internalSymbolClass.reference,
-        const <DartType>[],
-        <Reference, Constant>{symbolNameField.reference: value});
-  }
-
-  @override
   lowerMapConstant(constant) => constant;
 
   @override
diff --git a/pkg/dev_compiler/lib/src/kernel/kernel_helpers.dart b/pkg/dev_compiler/lib/src/kernel/kernel_helpers.dart
index 27b4e85..7d1beb2 100644
--- a/pkg/dev_compiler/lib/src/kernel/kernel_helpers.dart
+++ b/pkg/dev_compiler/lib/src/kernel/kernel_helpers.dart
@@ -234,3 +234,6 @@
   }
   return sc;
 }
+
+// TODO(jmesserly): replace with a flag on Class once Kernel supports it.
+bool isMixinDeclaration(Class c) => false;
diff --git a/pkg/dev_compiler/lib/src/kernel/target.dart b/pkg/dev_compiler/lib/src/kernel/target.dart
index ea955ac..170221c 100644
--- a/pkg/dev_compiler/lib/src/kernel/target.dart
+++ b/pkg/dev_compiler/lib/src/kernel/target.dart
@@ -12,6 +12,8 @@
 class DevCompilerTarget extends Target {
   bool get strongMode => true; // the only correct answer
 
+  bool get enableSuperMixins => true;
+
   String get name => 'dartdevc';
 
   List<String> get extraRequiredLibraries => const [
diff --git a/pkg/dev_compiler/tool/ddc b/pkg/dev_compiler/tool/ddc
index 09273e9b..bacfff7 100755
--- a/pkg/dev_compiler/tool/ddc
+++ b/pkg/dev_compiler/tool/ddc
@@ -75,7 +75,7 @@
   NODE_PATH=$GEN_DIR/kernel/common:$LIBROOT:$NODE_PATH
 
   $SDK_DIR/sdk/bin/dartdevk --modules=node \
-      --dart-sdk-summary=$GEN_DIR/kernel/ddc_sdk.dill \
+      --dart-sdk-summary=$GEN_DIR/ddc_sdk.sum \
       -o $LIBROOT/$BASENAME.js $*
 else
 
diff --git a/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/classes.dart b/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/classes.dart
index 0dd4e3e..c8b2e39 100644
--- a/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/classes.dart
+++ b/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/classes.dart
@@ -13,9 +13,7 @@
 part of dart._runtime;
 
 /// Returns a new type that mixes members from base and the mixin.
-///
-/// The mixin must be non-generic; generic mixins are handled by [genericMixin].
-void mixinMembers(to, from) {
+void applyMixin(to, from) {
   JS('', '#[#] = #', to, _mixin, from);
   var toProto = JS('', '#.prototype', to);
   var fromProto = JS('', '#.prototype', from);
@@ -24,6 +22,11 @@
   _mixinSignature(to, from, _fieldSig);
   _mixinSignature(to, from, _getterSig);
   _mixinSignature(to, from, _setterSig);
+  var mixinOnFn = JS('', '#[#]', from, mixinOn);
+  if (mixinOnFn != null) {
+    var proto = JS('', '#(#.__proto__).prototype', mixinOnFn, to);
+    _copyMembers(toProto, proto);
+  }
 }
 
 void _copyMembers(to, from) {
@@ -97,16 +100,18 @@
 getMixin(clazz) => JS('', 'Object.hasOwnProperty.call(#, #) ? #[#] : null',
     clazz, _mixin, clazz, _mixin);
 
+final mixinOn = JS('', 'Symbol("mixinOn")');
+
 @JSExportName('implements')
-final _implements = JS('', 'Symbol("implements")');
+final implements_ = JS('', 'Symbol("implements")');
 
 List Function() getImplements(clazz) => JS(
     '',
     'Object.hasOwnProperty.call(#, #) ? #[#] : null',
     clazz,
-    _implements,
+    implements_,
     clazz,
-    _implements);
+    implements_);
 
 /// The Symbol for storing type arguments on a specialized generic type.
 final _typeArguments = JS('', 'Symbol("typeArguments")');
diff --git a/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/operations.dart b/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/operations.dart
index 97e0d7f..09cf403 100644
--- a/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/operations.dart
+++ b/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/operations.dart
@@ -82,12 +82,14 @@
 ///
 /// We need to apply the type arguments both to the function, as well as its
 /// associated function type.
-gbind(f, @rest typeArgs) {
+gbind(f, @rest List typeArgs) {
+  GenericFunctionType type = JS('!', '#[#]', f, _runtimeType);
+  type.checkBounds(typeArgs);
+  // Create a JS wrapper function that will also pass the type arguments, and
+  // tag it with the instantiated function type.
   var result =
       JS('', '(...args) => #.apply(null, #.concat(args))', f, typeArgs);
-  var sig = JS('', '#[#].instantiate(#)', f, _runtimeType, typeArgs);
-  fn(result, sig);
-  return result;
+  return fn(result, type.instantiate(typeArgs));
 }
 
 dloadRepl(obj, field) => dload(obj, replNameLookup(obj, field), false);
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 7d4ab70..23d25f7 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
@@ -536,7 +536,13 @@
     return _typeFormals = _typeFormalsFromFunction(_instantiateTypeParts);
   }
 
-  checkBounds(List typeArgs) {
+  /// Checks that [typeArgs] satisfies the upper bounds of the [typeFormals],
+  /// and throws a [TypeError] if they do not.
+  void checkBounds(List typeArgs) {
+    // If we don't have explicit type parameter bounds, the bounds default to
+    // a top type, so there's nothing to check here.
+    if (_instantiateTypeBounds == null) return;
+
     var bounds = instantiateTypeBounds(typeArgs);
     var typeFormals = this.typeFormals;
     for (var i = 0; i < typeArgs.length; i++) {
@@ -554,11 +560,12 @@
     var boundsFn = _instantiateTypeBounds;
     if (boundsFn == null) {
       // The Dart 1 spec says omitted type parameters have an upper bound of
-      // Object. However strong mode assumes `dynamic` for all purposes
-      // (such as instantiate to bounds) so we use that here.
+      // Object. However Dart 2 uses `dynamic` for the purpose of instantiate to
+      // bounds, so we use that here.
       return List.filled(formalCount, _dynamic);
     }
-    // If bounds are recursive, we need to apply type formals and return them.
+    // Bounds can be recursive or depend on other type parameters, so we need to
+    // apply type arguments and return the resulting bounds.
     return JS('List', '#.apply(null, #)', boundsFn, typeArgs);
   }
 
@@ -738,10 +745,11 @@
 bool isType(obj) => JS('', '#[#] === #', obj, _runtimeType, Type);
 
 void checkTypeBound(type, bound, name) {
+  // TODO(jmesserly): we've optimized `is`/`as`/implicit type checks, it would
+  // be nice to have similar optimizations for the subtype relation.
   if (JS('!', '#', isSubtype(type, bound))) return;
 
-  throwTypeError('type `$type` does not extend `$bound`'
-      ' of `$name`.');
+  throwTypeError('type `$type` does not extend `$bound` of `$name`.');
 }
 
 String typeName(type) => JS('', '''(() => {
diff --git a/pkg/dev_compiler/tool/input_sdk/private/interceptors.dart b/pkg/dev_compiler/tool/input_sdk/private/interceptors.dart
index 4a9290a..de5ca6e 100644
--- a/pkg/dev_compiler/tool/input_sdk/private/interceptors.dart
+++ b/pkg/dev_compiler/tool/input_sdk/private/interceptors.dart
@@ -42,6 +42,15 @@
   @notNull
   int get hashCode => this ? (2 * 3 * 23 * 3761) : (269 * 811);
 
+  @notNull
+  bool operator &(@nullCheck bool other) => JS('bool', "# && #", other, this);
+
+  @notNull
+  bool operator |(@nullCheck bool other) => JS('bool', "# || #", other, this);
+
+  @notNull
+  bool operator ^(@nullCheck bool other) => !identical(this, other);
+
   Type get runtimeType => bool;
 }
 
diff --git a/pkg/expect/lib/expect.dart b/pkg/expect/lib/expect.dart
index 423242f..eff873d 100644
--- a/pkg/expect/lib/expect.dart
+++ b/pkg/expect/lib/expect.dart
@@ -543,7 +543,13 @@
       // A test failure doesn't count as throwing.
       if (e is ExpectException) rethrow;
       if (e is T && (check == null || check(e))) return;
-      _fail("Expect.throws$msg: Unexpected '$e'\n$s");
+      // Throws something unexpected.
+      String type = "";
+      if (T != dynamic && T != Object) {
+        type = "<$T>";
+      }
+      _fail("Expect.throws$type$msg: "
+          "Unexpected '${Error.safeToString(e)}'\n$s");
     }
     _fail('Expect.throws$msg fails: Did not throw');
   }
@@ -602,14 +608,40 @@
   static void type<T>(Object object, [String reason]) {
     if (object is T) return;
     String msg = _getMessage(reason);
-    _fail("Expect.type($object is $T$msg) fails, was ${object.runtimeType}");
+    _fail("Expect.type($object is $T$msg) fails "
+        "on ${Error.safeToString(object)}");
   }
 
   /// Checks that [object] does not have type [T].
   static void notType<T>(Object object, [String reason]) {
     if (object is! T) return;
     String msg = _getMessage(reason);
-    _fail("Expect.type($object is! $T$msg) fails, was ${object.runtimeType}");
+    _fail("Expect.type($object is! $T$msg) fails"
+        "on ${Error.safeToString(object)}");
+  }
+
+  /// Checks that `Sub` is a subtype of `Super` at compile time and run time.
+  static bool subtype<Sub extends Super, Super>() {
+    List<Super> list = <Sub>[];
+    _subtypeAtRuntime<Sub, Super>();
+  }
+
+  /// Checks that `Sub` is a subtype of `Super` at run time.
+  ///
+  /// This is similar to [subtype] but without the `Sub extends Super` generic
+  /// constraint, so a compiler is less likely to optimize away the `is` check
+  /// because the types appear to be unrelated.
+  static bool _subtypeAtRuntime<Sub, Super>() {
+    if (<Sub>[] is! List<Super>) {
+      fail("$Sub is not a subtype of $Super");
+    }
+  }
+
+  /// Checks that `Sub` is not a subtype of `Super` at run time.
+  static bool notSubtype<Sub, Super>() {
+    if (<Sub>[] is List<Super>) {
+      fail("$Sub is a subtype of $Super");
+    }
   }
 
   static String _getMessage(String reason) =>
diff --git a/pkg/front_end/analysis_options.yaml b/pkg/front_end/analysis_options.yaml
index acda1b5..39409d5 100644
--- a/pkg/front_end/analysis_options.yaml
+++ b/pkg/front_end/analysis_options.yaml
@@ -8,17 +8,9 @@
   exclude:
     - testcases/**
   errors:
-    # Omits warnings due to missing `@virtual`
-    # TODO(sigmund): enable once #28601 is fixed
-    strong_mode_invalid_field_override: ignore
-
     # Allow having TODOs in the code
     todo: ignore
 
     # Allow deprecated calls (although it would be nice to have a distinction
     # between internal and external deprecated calls).
     deprecated_member_use: ignore
-
-    # TODO(jmesserly): this hint was not working in many cases (#31237).
-    # The hint is now fixed, but the new hints need investigation by CFE folks.
-    missing_return: ignore
diff --git a/pkg/front_end/lib/src/api_prototype/compiler_options.dart b/pkg/front_end/lib/src/api_prototype/compiler_options.dart
index 4e13741..5c0624d 100644
--- a/pkg/front_end/lib/src/api_prototype/compiler_options.dart
+++ b/pkg/front_end/lib/src/api_prototype/compiler_options.dart
@@ -6,18 +6,24 @@
 
 import 'package:kernel/target/targets.dart' show Target;
 
-import 'byte_store.dart';
-import '../base/performance_logger.dart';
+import '../base/performance_logger.dart' show PerformanceLog;
 
 import '../fasta/fasta_codes.dart' show FormattedMessage;
+
 import '../fasta/severity.dart' show Severity;
 
-import 'compilation_message.dart';
-import 'file_system.dart';
-import 'standard_file_system.dart';
+import 'byte_store.dart' show ByteStore, NullByteStore;
+
+import 'compilation_message.dart' show CompilationMessage;
+
+import 'file_system.dart' show FileSystem;
+
+import 'standard_file_system.dart' show StandardFileSystem;
 
 export '../fasta/fasta_codes.dart' show FormattedMessage;
 
+export '../fasta/severity.dart' show Severity;
+
 /// Callback used to report errors encountered during compilation.
 typedef void ErrorHandler(CompilationMessage error);
 
diff --git a/pkg/front_end/lib/src/base/processed_options.dart b/pkg/front_end/lib/src/base/processed_options.dart
index 5c81b7b..89060a67 100644
--- a/pkg/front_end/lib/src/base/processed_options.dart
+++ b/pkg/front_end/lib/src/base/processed_options.dart
@@ -44,17 +44,15 @@
         messageInternalProblemProvidedBothCompileSdkAndSdkSummary,
         messageMissingInput,
         noLength,
-        templateCannotReadPackagesFile,
         templateCannotReadSdkSpecification,
+        templateCantReadFile,
         templateInputFileNotFound,
         templateInternalProblemUnsupported,
+        templatePackagesFileFormat,
         templateSdkRootNotFound,
         templateSdkSpecificationNotFound,
         templateSdkSummaryNotFound;
 
-// TODO(ahe): Remove this import.
-import '../fasta/fasta_codes.dart' show templateUnspecified;
-
 import '../fasta/messages.dart' show getLocation;
 
 import '../fasta/problems.dart' show DebugAbort, unimplemented;
@@ -257,21 +255,6 @@
       return false;
     }
 
-    for (var source in inputs) {
-      // Note: we don't translate Uris at this point because some of the
-      // validation further below must be done before we even construct an
-      // UriTranslator
-      // TODO(sigmund): consider validating dart/packages uri right after we
-      // build the uri translator.
-      if (source.scheme != 'dart' &&
-          source.scheme != 'package' &&
-          !await fileSystem.entityForUri(source).exists()) {
-        reportWithoutLocation(
-            templateInputFileNotFound.withArguments(source), Severity.error);
-        return false;
-      }
-    }
-
     if (_raw.sdkRoot != null &&
         !await fileSystem.entityForUri(sdkRoot).exists()) {
       reportWithoutLocation(
@@ -294,6 +277,8 @@
     }
 
     for (Uri source in _raw.linkedDependencies) {
+      // TODO(ahe): Remove this check, the compiler itself should handle and
+      // recover from this.
       if (!await fileSystem.entityForUri(source).exists()) {
         reportWithoutLocation(
             templateInputFileNotFound.withArguments(source), Severity.error);
@@ -361,6 +346,13 @@
     return _inputSummariesComponents;
   }
 
+  void set inputSummariesComponents(List<Component> components) {
+    if (_inputSummariesComponents != null) {
+      throw new StateError("inputSummariesComponents already loaded.");
+    }
+    _inputSummariesComponents = components;
+  }
+
   /// Load each of the [CompilerOptions.linkedDependencies] components.
   // TODO(sigmund): move, this doesn't feel like an "option".
   Future<List<Component>> loadLinkDependencies(CanonicalName nameRoot) async {
@@ -475,20 +467,32 @@
 
   /// Create a [Packages] given the Uri to a `.packages` file.
   Future<Packages> createPackagesFromFile(Uri file) async {
+    List<int> contents;
     try {
-      List<int> contents = await fileSystem.entityForUri(file).readAsBytes();
-      Map<String, Uri> map = package_config.parse(contents, file);
-      _packagesUri = file;
-      return new MapPackages(map);
-    } catch (e) {
-      _packagesUri = null;
-      report(
-          templateCannotReadPackagesFile
-              .withArguments("$e")
-              .withLocation(file, -1, noLength),
-          Severity.error);
-      return Packages.noPackages;
+      // TODO(ahe): We need to compute line endings for this file.
+      contents = await fileSystem.entityForUri(file).readAsBytes();
+    } on FileSystemException catch (e) {
+      reportWithoutLocation(
+          templateCantReadFile.withArguments(file, e.message), Severity.error);
     }
+    if (contents != null) {
+      _packagesUri = file;
+      try {
+        Map<String, Uri> map = package_config.parse(contents, file);
+        return new MapPackages(map);
+      } on FormatException catch (e) {
+        report(
+            templatePackagesFileFormat
+                .withArguments(e.message)
+                .withLocation(file, e.offset, noLength),
+            Severity.error);
+      } catch (e) {
+        reportWithoutLocation(
+            templateCantReadFile.withArguments(file, "$e"), Severity.error);
+      }
+    }
+    _packagesUri = null;
+    return Packages.noPackages;
   }
 
   /// Finds a package resolution strategy using a [FileSystem].
@@ -638,11 +642,8 @@
       return await file.readAsBytes();
     } on FileSystemException catch (error) {
       report(
-          // TODO(ahe): Change to templateCantReadFile.withArguments(error.uri,
-          // error.message) when CL 63144 has landed.
-          templateUnspecified
-              .withArguments(
-                  "Error when reading '${error.uri}': ${error.message}")
+          templateCantReadFile
+              .withArguments(error.uri, error.message)
               .withoutLocation(),
           Severity.error);
       return new Uint8List(0);
diff --git a/pkg/front_end/lib/src/fasta/builder/library_builder.dart b/pkg/front_end/lib/src/fasta/builder/library_builder.dart
index 2f29995..b1d0382 100644
--- a/pkg/front_end/lib/src/fasta/builder/library_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/library_builder.dart
@@ -53,6 +53,8 @@
         exportScopeBuilder = new ScopeBuilder(exportScope),
         super(null, -1, fileUri);
 
+  bool get isSynthetic => false;
+
   @override
   Declaration get parent => null;
 
@@ -187,7 +189,13 @@
     return 0;
   }
 
-  void becomeCoreLibrary(dynamicType);
+  void becomeCoreLibrary() {
+    if (scope.local["dynamic"] == null) {
+      addSyntheticDeclarationOfDynamic();
+    }
+  }
+
+  void addSyntheticDeclarationOfDynamic();
 
   void forEach(void f(String name, Declaration declaration)) {
     scope.forEach((String name, Declaration declaration) {
@@ -216,4 +224,6 @@
     if (!isPatch) return;
     unsupported("${runtimeType}.applyPatches", -1, fileUri);
   }
+
+  void recordAccess(int charOffset, int length, Uri fileUri) {}
 }
diff --git a/pkg/front_end/lib/src/fasta/dill/dill_library_builder.dart b/pkg/front_end/lib/src/fasta/dill/dill_library_builder.dart
index ba16545..2838eb7 100644
--- a/pkg/front_end/lib/src/fasta/dill/dill_library_builder.dart
+++ b/pkg/front_end/lib/src/fasta/dill/dill_library_builder.dart
@@ -10,6 +10,7 @@
     show
         Class,
         DartType,
+        DynamicType,
         Field,
         Library,
         ListLiteral,
@@ -72,14 +73,12 @@
   @override
   Library get target => library;
 
-  void becomeCoreLibrary(dynamicType) {
-    if (scope.local["dynamic"] == null) {
-      addBuilder(
-          "dynamic",
-          new DynamicTypeBuilder<KernelTypeBuilder, DartType>(
-              dynamicType, this, -1),
-          -1);
-    }
+  void addSyntheticDeclarationOfDynamic() {
+    addBuilder(
+        "dynamic",
+        new DynamicTypeBuilder<KernelTypeBuilder, DartType>(
+            const DynamicType(), this, -1),
+        -1);
   }
 
   void addClass(Class cls) {
diff --git a/pkg/front_end/lib/src/fasta/fasta_codes.dart b/pkg/front_end/lib/src/fasta/fasta_codes.dart
index f5c2da1..ce5d18a 100644
--- a/pkg/front_end/lib/src/fasta/fasta_codes.dart
+++ b/pkg/front_end/lib/src/fasta/fasta_codes.dart
@@ -21,6 +21,11 @@
 class Code<T> {
   final String name;
 
+  /// The unique positive integer associated with this code,
+  /// or `-1` if none. This index is used when translating
+  /// this error to its corresponding Analyzer error.
+  final int index;
+
   final Template<T> template;
 
   final String analyzerCode;
@@ -28,7 +33,8 @@
   final Severity severity;
 
   const Code(this.name, this.template,
-      {this.analyzerCode, this.severity: Severity.error});
+      {int index, this.analyzerCode, this.severity: Severity.error})
+      : this.index = index ?? -1;
 
   String toString() => name;
 }
@@ -59,11 +65,13 @@
   final String tip;
 
   const MessageCode(String name,
-      {String analyzerCode,
+      {int index,
+      String analyzerCode,
       Severity severity: Severity.error,
       this.message,
       this.tip})
-      : super(name, null, analyzerCode: analyzerCode, severity: severity);
+      : super(name, null,
+            index: index, analyzerCode: analyzerCode, severity: severity);
 
   Map<String, dynamic> get arguments => const <String, dynamic>{};
 
diff --git a/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart b/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart
index 4934ff9..2217a24 100644
--- a/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart
+++ b/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart
@@ -464,26 +464,6 @@
     message: r"""Can't assign to super.""");
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
-const Template<Message Function(String string)> templateCannotReadPackagesFile =
-    const Template<Message Function(String string)>(
-        messageTemplate: r"""Unable to read '.packages' file:
-  #string.""", withArguments: _withArgumentsCannotReadPackagesFile);
-
-// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
-const Code<Message Function(String string)> codeCannotReadPackagesFile =
-    const Code<Message Function(String string)>(
-  "CannotReadPackagesFile",
-  templateCannotReadPackagesFile,
-);
-
-// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
-Message _withArgumentsCannotReadPackagesFile(String string) {
-  return new Message(codeCannotReadPackagesFile,
-      message: """Unable to read '.packages' file:
-  ${string}.""", arguments: {'string': string});
-}
-
-// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const Template<Message Function(String string)>
     templateCannotReadSdkSpecification =
     const Template<Message Function(String string)>(
@@ -580,6 +560,26 @@
 }
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Template<Message Function(Uri uri_, String string)> templateCantReadFile =
+    const Template<Message Function(Uri uri_, String string)>(
+        messageTemplate: r"""Error when reading '#uri': #string""",
+        withArguments: _withArgumentsCantReadFile);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Message Function(Uri uri_, String string)> codeCantReadFile =
+    const Code<Message Function(Uri uri_, String string)>(
+        "CantReadFile", templateCantReadFile,
+        analyzerCode: "URI_DOES_NOT_EXIST");
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+Message _withArgumentsCantReadFile(Uri uri_, String string) {
+  String uri = relativizeUri(uri_);
+  return new Message(codeCantReadFile,
+      message: """Error when reading '${uri}': ${string}""",
+      arguments: {'uri': uri_, 'string': string});
+}
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const Template<
     Message Function(
         Token
@@ -677,6 +677,19 @@
         r"""No types are needed, the first is given by 'on', the second is always 'StackTrace'.""");
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Null> codeCatchSyntaxExtraParameters =
+    messageCatchSyntaxExtraParameters;
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const MessageCode messageCatchSyntaxExtraParameters = const MessageCode(
+    "CatchSyntaxExtraParameters",
+    analyzerCode: "CATCH_SYNTAX",
+    message:
+        r"""'catch' must be followed by '(identifier)' or '(identifier, identifier)'.""",
+    tip:
+        r"""No types are needed, the first is given by 'on', the second is always 'StackTrace'.""");
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const Code<Null> codeClassInClass = messageClassInClass;
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
@@ -965,6 +978,35 @@
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const Template<
     Message Function(
+        String
+            name)> templateConstEvalDeferredLibrary = const Template<
+        Message Function(String name)>(
+    messageTemplate:
+        r"""'#name' can't be used in a constant expression because it's marked as 'deferred' which means it isn't available until loaded.""",
+    tipTemplate:
+        r"""Try moving the constant from the deferred library, or removing 'deferred' from the import.
+""",
+    withArguments: _withArgumentsConstEvalDeferredLibrary);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Message Function(String name)> codeConstEvalDeferredLibrary =
+    const Code<Message Function(String name)>(
+        "ConstEvalDeferredLibrary", templateConstEvalDeferredLibrary,
+        analyzerCode: "NON_CONSTANT_DEFAULT_VALUE_FROM_DEFERRED_LIBRARY");
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+Message _withArgumentsConstEvalDeferredLibrary(String name) {
+  return new Message(codeConstEvalDeferredLibrary,
+      message:
+          """'${name}' can't be used in a constant expression because it's marked as 'deferred' which means it isn't available until loaded.""",
+      tip: """Try moving the constant from the deferred library, or removing 'deferred' from the import.
+""",
+      arguments: {'name': name});
+}
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Template<
+    Message Function(
         Constant
             _constant)> templateConstEvalDuplicateKey = const Template<
         Message Function(Constant _constant)>(
@@ -1505,7 +1547,7 @@
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const MessageCode messageContinueOutsideOfLoop = const MessageCode(
     "ContinueOutsideOfLoop",
-    analyzerCode: "CONTINUE_OUTSIDE_OF_LOOP",
+    index: 2,
     message:
         r"""A continue statement can't be used outside of a loop or switch statement.""",
     tip: r"""Try removing the continue statement.""");
@@ -1583,7 +1625,7 @@
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const MessageCode messageCovariantAfterVar = const MessageCode(
     "CovariantAfterVar",
-    analyzerCode: "COVARIANT_AFTER_VAR",
+    index: 8,
     message:
         r"""The modifier 'covariant' should be before the modifier 'var'.""",
     tip: r"""Try re-ordering the modifiers.""");
@@ -2300,7 +2342,7 @@
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const MessageCode messageEqualityCannotBeEqualityOperand = const MessageCode(
     "EqualityCannotBeEqualityOperand",
-    analyzerCode: "EQUALITY_CANNOT_BE_EQUALITY_OPERAND",
+    index: 1,
     message:
         r"""An equality expression can't be an operand of another equality expression.""",
     tip: r"""Try re-writing the expression.""");
@@ -2566,7 +2608,7 @@
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const MessageCode messageExpectedStatement = const MessageCode(
     "ExpectedStatement",
-    analyzerCode: "MISSING_STATEMENT",
+    index: 29,
     message: r"""Expected a statement.""");
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
@@ -2757,7 +2799,7 @@
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const MessageCode messageExternalClass = const MessageCode("ExternalClass",
-    analyzerCode: "EXTERNAL_CLASS",
+    index: 3,
     message: r"""Classes can't be declared to be 'external'.""",
     tip: r"""Try removing the keyword 'external'.""");
 
@@ -2790,7 +2832,7 @@
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const MessageCode messageExternalEnum = const MessageCode("ExternalEnum",
-    analyzerCode: "EXTERNAL_ENUM",
+    index: 5,
     message: r"""Enums can't be declared to be 'external'.""",
     tip: r"""Try removing the keyword 'external'.""");
 
@@ -3560,7 +3602,7 @@
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const MessageCode messageImportAfterPart = const MessageCode("ImportAfterPart",
-    analyzerCode: "IMPORT_DIRECTIVE_AFTER_PART_DIRECTIVE",
+    index: 10,
     message: r"""Import directives must preceed part directives.""",
     tip: r"""Try moving the import directives before the part directives.""");
 
@@ -4241,7 +4283,7 @@
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const MessageCode messageInvalidAwaitFor = const MessageCode("InvalidAwaitFor",
-    analyzerCode: "INVALID_AWAIT_IN_FOR",
+    index: 9,
     message:
         r"""The keyword 'await' isn't allowed for a normal 'for' statement.""",
     tip: r"""Try removing the keyword, or use a for-each statement.""");
@@ -4586,7 +4628,7 @@
     "InvalidHexEscape",
     analyzerCode: "INVALID_HEX_ESCAPE",
     message:
-        r"""An escape sequence starting with '\x' must be followed by 2 hexidecimal digits.""");
+        r"""An escape sequence starting with '\x' must be followed by 2 hexadecimal digits.""");
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const Code<Null> codeInvalidInitializer = messageInvalidInitializer;
@@ -4605,7 +4647,9 @@
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const MessageCode messageInvalidInlineFunctionType = const MessageCode(
     "InvalidInlineFunctionType",
-    message: r"""Invalid inline function type.""",
+    analyzerCode: "INVALID_INLINE_FUNCTION_TYPE",
+    message:
+        r"""Inline function types cannot be used for parameters in a generic function type.""",
     tip:
         r"""Try changing the inline function type (as in 'int f()') to a prefixed function type using the `Function` keyword (as in 'int Function() f').""");
 
@@ -4670,7 +4714,7 @@
     "InvalidUnicodeEscape",
     analyzerCode: "INVALID_UNICODE_ESCAPE",
     message:
-        r"""An escape sequence starting with '\u' must be followed by 4 hexidecimal digits or from 1 to 6 digits between '{' and '}'.""");
+        r"""An escape sequence starting with '\u' must be followed by 4 hexadecimal digits or from 1 to 6 digits between '{' and '}'.""");
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const Code<Null> codeInvalidUseOfNullAwareAccess =
@@ -4688,7 +4732,7 @@
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const MessageCode messageInvalidVoid = const MessageCode("InvalidVoid",
-    analyzerCode: "INVALID_USE_OF_VOID",
+    analyzerCode: "EXPECTED_TYPE_NAME",
     message:
         r"""Type 'void' can't be used here because it isn't a return type.""",
     tip:
@@ -5116,7 +5160,7 @@
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const MessageCode messageMissingPrefixInDeferredImport = const MessageCode(
     "MissingPrefixInDeferredImport",
-    analyzerCode: "MISSING_PREFIX_IN_DEFERRED_IMPORT",
+    index: 30,
     message: r"""Deferred imports should have a prefix.""",
     tip: r"""Try adding a prefix to the import.""");
 
@@ -5179,7 +5223,7 @@
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const MessageCode messageMultipleExtends = const MessageCode("MultipleExtends",
-    analyzerCode: "MULTIPLE_EXTENDS_CLAUSES",
+    index: 28,
     message: r"""Each class definition can have at most one extends clause.""",
     tip:
         r"""Try choosing one superclass and define your class to implement (or mix in) the others.""");
@@ -5203,7 +5247,7 @@
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const MessageCode messageMultipleLibraryDirectives = const MessageCode(
     "MultipleLibraryDirectives",
-    analyzerCode: "MULTIPLE_LIBRARY_DIRECTIVES",
+    index: 27,
     message: r"""Only one library directive may be declared in a file.""",
     tip: r"""Try removing all but one of the library directives.""");
 
@@ -5213,7 +5257,7 @@
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const MessageCode messageMultipleOnClauses = const MessageCode(
     "MultipleOnClauses",
-    analyzerCode: "MULTIPLE_ON_CLAUSES",
+    index: 26,
     message: r"""Each mixin definition can have at most one on clause.""",
     tip: r"""Try combining all of the on clauses into a single clause.""");
 
@@ -5222,7 +5266,7 @@
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const MessageCode messageMultipleWith = const MessageCode("MultipleWith",
-    analyzerCode: "MULTIPLE_WITH_CLAUSES",
+    index: 24,
     message: r"""Each class definition can have at most one with clause.""",
     tip: r"""Try combining all of the with clauses into a single clause.""");
 
@@ -5242,7 +5286,7 @@
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const MessageCode messageNativeClauseShouldBeAnnotation = const MessageCode(
     "NativeClauseShouldBeAnnotation",
-    analyzerCode: "NATIVE_CLAUSE_SHOULD_BE_ANNOTATION",
+    index: 23,
     message: r"""Native clause in this form is deprecated.""",
     tip:
         r"""Try removing this native clause and adding @native() or @native('native-name') before the declaration.""");
@@ -5634,7 +5678,7 @@
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const Template<Message Function(String name)> templateOverriddenMethodCause =
     const Template<Message Function(String name)>(
-        messageTemplate: r"""This is the overriden method ('#name').""",
+        messageTemplate: r"""This is the overridden method ('#name').""",
         withArguments: _withArgumentsOverriddenMethodCause);
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
@@ -5646,7 +5690,7 @@
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 Message _withArgumentsOverriddenMethodCause(String name) {
   return new Message(codeOverriddenMethodCause,
-      message: """This is the overriden method ('${name}').""",
+      message: """This is the overridden method ('${name}').""",
       arguments: {'name': name});
 }
 
@@ -5715,7 +5759,7 @@
             name3)> templateOverrideMismatchNamedParameter = const Template<
         Message Function(String name, String name2, String name3)>(
     messageTemplate:
-        r"""The method '#name' doesn't have the named parameter '#name2' of overriden method '#name3'.""",
+        r"""The method '#name' doesn't have the named parameter '#name2' of overridden method '#name3'.""",
     withArguments: _withArgumentsOverrideMismatchNamedParameter);
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
@@ -5732,7 +5776,7 @@
     String name, String name2, String name3) {
   return new Message(codeOverrideMismatchNamedParameter,
       message:
-          """The method '${name}' doesn't have the named parameter '${name2}' of overriden method '${name3}'.""",
+          """The method '${name}' doesn't have the named parameter '${name2}' of overridden method '${name3}'.""",
       arguments: {'name': name, 'name2': name2, 'name3': name3});
 }
 
@@ -5906,6 +5950,62 @@
 }
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Template<Message Function(String string)> templatePackagesFileFormat =
+    const Template<Message Function(String string)>(
+        messageTemplate: r"""Problem in packages configuration file: #string""",
+        withArguments: _withArgumentsPackagesFileFormat);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Message Function(String string)> codePackagesFileFormat =
+    const Code<Message Function(String string)>(
+  "PackagesFileFormat",
+  templatePackagesFileFormat,
+);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+Message _withArgumentsPackagesFileFormat(String string) {
+  return new Message(codePackagesFileFormat,
+      message: """Problem in packages configuration file: ${string}""",
+      arguments: {'string': string});
+}
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Null> codePartExport = messagePartExport;
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const MessageCode messagePartExport = const MessageCode("PartExport",
+    analyzerCode: "EXPORT_OF_NON_LIBRARY",
+    message:
+        r"""Can't export this file because it contains a 'part of' declaration.""");
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Null> codePartExportContext = messagePartExportContext;
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const MessageCode messagePartExportContext = const MessageCode(
+    "PartExportContext",
+    severity: Severity.context,
+    message: r"""This is the file that can't be exported.""");
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Null> codePartInPart = messagePartInPart;
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const MessageCode messagePartInPart = const MessageCode("PartInPart",
+    analyzerCode: "NON_PART_OF_DIRECTIVE_IN_PART",
+    message: r"""A file that's a part of a library can't have parts itself.""",
+    tip: r"""Try moving the 'part' declaration to the containing library.""");
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Null> codePartInPartLibraryContext = messagePartInPartLibraryContext;
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const MessageCode messagePartInPartLibraryContext = const MessageCode(
+    "PartInPartLibraryContext",
+    severity: Severity.context,
+    message: r"""This is the containing library.""");
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const Template<
     Message Function(Uri uri_)> templatePartOfInLibrary = const Template<
         Message Function(Uri uri_)>(
@@ -5975,7 +6075,7 @@
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const MessageCode messagePartOfTwice = const MessageCode("PartOfTwice",
-    analyzerCode: "MULTIPLE_PART_OF_DIRECTIVES",
+    index: 25,
     message: r"""Only one part-of directive may be declared in a file.""",
     tip: r"""Try removing all but one of the part-of directives.""");
 
@@ -6065,6 +6165,14 @@
 }
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Null> codePartOrphan = messagePartOrphan;
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const MessageCode messagePartOrphan = const MessageCode("PartOrphan",
+    message: r"""This part doesn't have a containing library.""",
+    tip: r"""Try removing the 'part of' declaration.""");
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const Template<Message Function(Uri uri_)> templatePartTwice =
     const Template<Message Function(Uri uri_)>(
         messageTemplate: r"""Can't use '#uri' as a part more than once.""",
@@ -6193,7 +6301,7 @@
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const MessageCode messagePrefixAfterCombinator = const MessageCode(
     "PrefixAfterCombinator",
-    analyzerCode: "PREFIX_AFTER_COMBINATOR",
+    index: 6,
     message:
         r"""The prefix ('as' clause) should come before any show/hide combinators.""",
     tip: r"""Try moving the prefix before the combinators.""");
@@ -6214,7 +6322,7 @@
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const MessageCode messageRedirectingConstructorWithBody = const MessageCode(
     "RedirectingConstructorWithBody",
-    analyzerCode: "REDIRECTING_CONSTRUCTOR_WITH_BODY",
+    index: 22,
     message: r"""Redirecting constructors can't have a body.""",
     tip:
         r"""Try removing the body, or not making this a redirecting constructor.""");
@@ -6225,7 +6333,7 @@
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const MessageCode messageRedirectionInNonFactory = const MessageCode(
     "RedirectionInNonFactory",
-    analyzerCode: "REDIRECTION_IN_NON_FACTORY_CONSTRUCTOR",
+    index: 21,
     message: r"""Only factory constructor can specify '=' redirection.""",
     tip:
         r"""Try making this a factory constructor, or remove the redirection.""");
@@ -6512,7 +6620,7 @@
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const MessageCode messageStaticAfterConst = const MessageCode(
     "StaticAfterConst",
-    analyzerCode: "STATIC_AFTER_CONST",
+    index: 20,
     message:
         r"""The modifier 'static' should be before the modifier 'const'.""",
     tip: r"""Try re-ordering the modifiers.""");
@@ -6523,7 +6631,7 @@
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const MessageCode messageStaticAfterFinal = const MessageCode(
     "StaticAfterFinal",
-    analyzerCode: "STATIC_AFTER_FINAL",
+    index: 19,
     message:
         r"""The modifier 'static' should be before the modifier 'final'.""",
     tip: r"""Try re-ordering the modifiers.""");
@@ -6533,7 +6641,7 @@
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const MessageCode messageStaticAfterVar = const MessageCode("StaticAfterVar",
-    analyzerCode: "STATIC_AFTER_VAR",
+    index: 18,
     message: r"""The modifier 'static' should be before the modifier 'var'.""",
     tip: r"""Try re-ordering the modifiers.""");
 
@@ -6543,7 +6651,7 @@
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const MessageCode messageStaticConstructor = const MessageCode(
     "StaticConstructor",
-    analyzerCode: "STATIC_CONSTRUCTOR",
+    index: 4,
     message: r"""Constructors can't be static.""",
     tip: r"""Try removing the keyword 'static'.""");
 
@@ -6552,7 +6660,7 @@
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const MessageCode messageStaticOperator = const MessageCode("StaticOperator",
-    analyzerCode: "STATIC_OPERATOR",
+    index: 17,
     message: r"""Operators can't be static.""",
     tip: r"""Try removing the keyword 'static'.""");
 
@@ -6816,7 +6924,7 @@
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const MessageCode messageSwitchHasCaseAfterDefault = const MessageCode(
     "SwitchHasCaseAfterDefault",
-    analyzerCode: "SWITCH_HAS_CASE_AFTER_DEFAULT_CASE",
+    index: 16,
     message:
         r"""The default case should be the last case in a switch statement.""",
     tip: r"""Try moving the default case after the other case clauses.""");
@@ -6828,7 +6936,7 @@
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const MessageCode messageSwitchHasMultipleDefaults = const MessageCode(
     "SwitchHasMultipleDefaults",
-    analyzerCode: "SWITCH_HAS_MULTIPLE_DEFAULT_CASES",
+    index: 15,
     message: r"""The 'default' case can only be declared once.""",
     tip: r"""Try removing all but one default case.""");
 
@@ -6954,7 +7062,7 @@
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const MessageCode messageTopLevelOperator = const MessageCode(
     "TopLevelOperator",
-    analyzerCode: "TOP_LEVEL_OPERATOR",
+    index: 14,
     message: r"""Operators must be declared within a class.""",
     tip:
         r"""Try removing the operator, moving it to a class, or converting it to be a function.""");
@@ -7001,8 +7109,7 @@
 const Code<Message Function(String name)> codeTypeArgumentsOnTypeVariable =
     const Code<Message Function(String name)>(
         "TypeArgumentsOnTypeVariable", templateTypeArgumentsOnTypeVariable,
-        analyzerCode: "TYPE_ARGUMENTS_ON_TYPE_VARIABLE",
-        severity: Severity.errorLegacyWarning);
+        index: 13, severity: Severity.errorLegacyWarning);
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 Message _withArgumentsTypeArgumentsOnTypeVariable(String name) {
@@ -7097,7 +7204,7 @@
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const MessageCode messageTypedefInClass = const MessageCode("TypedefInClass",
-    analyzerCode: "TYPEDEF_IN_CLASS",
+    index: 7,
     message: r"""Typedefs can't be declared inside classes.""",
     tip: r"""Try moving the typedef to the top-level.""");
 
@@ -7384,6 +7491,25 @@
     const MessageCode("UnterminatedToken", message: r"""Incomplete token.""");
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Template<Message Function(Uri uri_)> templateUntranslatableUri =
+    const Template<Message Function(Uri uri_)>(
+        messageTemplate: r"""Not found: '#uri'""",
+        withArguments: _withArgumentsUntranslatableUri);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Message Function(Uri uri_)> codeUntranslatableUri =
+    const Code<Message Function(Uri uri_)>(
+        "UntranslatableUri", templateUntranslatableUri,
+        analyzerCode: "URI_DOES_NOT_EXIST");
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+Message _withArgumentsUntranslatableUri(Uri uri_) {
+  String uri = relativizeUri(uri_);
+  return new Message(codeUntranslatableUri,
+      message: """Not found: '${uri}'""", arguments: {'uri': uri_});
+}
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const Template<Message Function(String name)>
     templateUseOfDeprecatedIdentifier =
     const Template<Message Function(String name)>(
@@ -7407,7 +7533,7 @@
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const MessageCode messageVarReturnType = const MessageCode("VarReturnType",
-    analyzerCode: "VAR_RETURN_TYPE",
+    index: 12,
     message: r"""The return type can't be 'var'.""",
     tip:
         r"""Try removing the keyword 'var', or replacing it with the name of the return type.""");
@@ -7457,21 +7583,11 @@
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const MessageCode messageWithBeforeExtends = const MessageCode(
     "WithBeforeExtends",
-    analyzerCode: "WITH_BEFORE_EXTENDS",
+    index: 11,
     message: r"""The extends clause must be before the with clause.""",
     tip: r"""Try moving the extends clause before the with clause.""");
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
-const Code<Null> codeWithWithoutExtends = messageWithWithoutExtends;
-
-// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
-const MessageCode messageWithWithoutExtends = const MessageCode(
-    "WithWithoutExtends",
-    analyzerCode: "WITH_WITHOUT_EXTENDS",
-    message: r"""The with clause can't be used without an extends clause.""",
-    tip: r"""Try adding an extends clause such as 'extends Object'.""");
-
-// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const Code<Null> codeYieldAsIdentifier = messageYieldAsIdentifier;
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
diff --git a/pkg/front_end/lib/src/fasta/identifiers.dart b/pkg/front_end/lib/src/fasta/identifiers.dart
index 64af67b..1be006a 100644
--- a/pkg/front_end/lib/src/fasta/identifiers.dart
+++ b/pkg/front_end/lib/src/fasta/identifiers.dart
@@ -134,7 +134,7 @@
   } else if (name is Identifier) {
     return name.name;
   } else {
-    unhandled("${name.runtimeType}", "flattenName", charOffset, fileUri);
+    return unhandled("${name.runtimeType}", "flattenName", charOffset, fileUri);
   }
 }
 
diff --git a/pkg/front_end/lib/src/fasta/ignored_parser_errors.dart b/pkg/front_end/lib/src/fasta/ignored_parser_errors.dart
new file mode 100644
index 0000000..7fa63c8
--- /dev/null
+++ b/pkg/front_end/lib/src/fasta/ignored_parser_errors.dart
@@ -0,0 +1,20 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for 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 fasta.ignored_parser_errors;
+
+import 'fasta_codes.dart' show Code, codeNonPartOfDirectiveInPart;
+
+import 'parser.dart' show optional;
+
+import 'scanner.dart' show Token;
+
+bool isIgnoredParserError(Code<Object> code, Token token) {
+  if (code == codeNonPartOfDirectiveInPart) {
+    // Ignored. This error is handled in the outline phase (part resolution).
+    return optional("part", token);
+  } else {
+    return false;
+  }
+}
diff --git a/pkg/front_end/lib/src/fasta/incremental_compiler.dart b/pkg/front_end/lib/src/fasta/incremental_compiler.dart
index f9a4ca8..b1ed5a3 100644
--- a/pkg/front_end/lib/src/fasta/incremental_compiler.dart
+++ b/pkg/front_end/lib/src/fasta/incremental_compiler.dart
@@ -490,7 +490,8 @@
     assert(dillLoadedData != null && userCode != null);
 
     return await context.runInContext((_) async {
-      LibraryBuilder library = userCode.loader.read(libraryUri, -1);
+      LibraryBuilder library =
+          userCode.loader.read(libraryUri, -1, accessor: userCode.loader.first);
 
       Class kernelClass;
       if (className != null) {
@@ -600,8 +601,8 @@
     List<Uri> invalidatedImportUris = <Uri>[];
 
     bool isInvalidated(Uri importUri, Uri fileUri) {
-      if (invalidatedUris.contains(importUri) ||
-          (importUri != fileUri && invalidatedUris.contains(fileUri))) {
+      if (invalidatedUris.contains(importUri)) return true;
+      if (importUri != fileUri && invalidatedUris.contains(fileUri)) {
         return true;
       }
       if (hasToCheckPackageUris &&
@@ -609,6 +610,7 @@
           uriTranslator.translate(importUri, false) != fileUri) {
         return true;
       }
+      if (builders[importUri]?.isSynthetic == true) return true;
       return false;
     }
 
diff --git a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
index 20d6978..fee5680 100644
--- a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
@@ -12,8 +12,6 @@
 
 import '../fasta_codes.dart' show LocatedMessage, Message, noLength, Template;
 
-import 'forest.dart' show Forest;
-
 import '../messages.dart' as messages show getLocationFromUri;
 
 import '../modifier.dart' show Modifier, constMask, covariantMask, finalMask;
@@ -33,11 +31,6 @@
         offsetForToken,
         optional;
 
-import '../parser/class_member_parser.dart' show ClassMemberParser;
-
-import '../parser/formal_parameter_kind.dart'
-    show isOptionalPositionalFormalParameterKind;
-
 import '../problems.dart'
     show internalProblem, unexpected, unhandled, unsupported;
 
@@ -58,16 +51,11 @@
 
 import '../severity.dart' show Severity;
 
-import '../source/outline_builder.dart' show OutlineBuilder;
-
 import '../source/scope_listener.dart'
     show JumpTargetKind, NullValue, ScopeListener;
 
 import '../type_inference/type_inferrer.dart' show TypeInferrer;
 
-import '../type_inference/type_inference_listener.dart'
-    show TypeInferenceTokensSaver;
-
 import '../type_inference/type_promotion.dart'
     show TypePromoter, TypePromotionFact, TypePromotionScope;
 
@@ -100,6 +88,8 @@
 
 import 'expression_generator_helper.dart' show ExpressionGeneratorHelper;
 
+import 'forest.dart' show Forest;
+
 import 'redirecting_factory_body.dart'
     show
         RedirectingFactoryBody,
@@ -164,8 +154,6 @@
   @override
   final TypePromoter typePromoter;
 
-  final TypeInferenceTokensSaver tokensSaver;
-
   /// Only used when [member] is a constructor. It tracks if an implicit super
   /// initializer is needed.
   ///
@@ -201,8 +189,6 @@
 
   int functionNestingLevel = 0;
 
-  Statement problemInTry;
-
   Statement problemInLoopOrSwitch;
 
   Scope switchScope;
@@ -211,7 +197,7 @@
 
   ConstantContext constantContext = ConstantContext.none;
 
-  DartType currentLocalVariableType;
+  UnresolvedType<KernelTypeBuilder> currentLocalVariableType;
 
   // Using non-null value to initialize this field based on performance advice
   // from VM engineers. TODO(ahe): Does this still apply?
@@ -247,7 +233,6 @@
         needsImplicitSuperInitializer =
             coreTypes?.objectClass != classBuilder?.cls,
         typePromoter = _typeInferrer?.typePromoter,
-        tokensSaver = _typeInferrer?.tokensSaver,
         super(enclosingScope);
 
   BodyBuilder.withParents(KernelFieldBuilder field, KernelLibraryBuilder part,
@@ -283,6 +268,9 @@
 
   @override
   void push(Object node) {
+    if (node is DartType) {
+      unhandled("DartType", "push", -1, uri);
+    }
     inInitializer = false;
     super.push(node);
   }
@@ -530,7 +518,16 @@
         }
       }
     }
-    pop(); // Type.
+    {
+      // TODO(ahe): The type we compute here may be different from what is
+      // computed in the outline phase. We should make sure that the outline
+      // phase computes the same type. See
+      // pkg/front_end/testcases/regress/issue_32200.dart for an example where
+      // not calling [buildDartType] leads to a missing compile-time
+      // error. Also, notice that the type of the problematic field isn't
+      // `invalid-type`.
+      buildDartType(pop()); // Type.
+    }
     List<Expression> annotations = pop();
     if (annotations != null) {
       _typeInferrer.inferMetadata(this, annotations);
@@ -678,29 +675,26 @@
   }
 
   @override
-  void finishFunction(
-      List<Expression> annotations,
-      FormalParameters<Expression, Statement, Arguments> formals,
-      AsyncMarker asyncModifier,
-      Statement body) {
+  void finishFunction(List<Expression> annotations, FormalParameters formals,
+      AsyncMarker asyncModifier, Statement body) {
     debugEvent("finishFunction");
     typePromoter.finished();
 
     KernelFunctionBuilder builder = member;
-    if (formals?.optional != null) {
-      Iterator<FormalParameterBuilder<TypeBuilder>> formalBuilders =
-          builder.formals.skip(formals.required.length).iterator;
-      for (VariableDeclaration parameter in formals.optional.formals) {
-        bool hasMore = formalBuilders.moveNext();
-        assert(hasMore);
-        VariableDeclaration realParameter = formalBuilders.current.target;
-        Expression initializer = parameter.initializer ?? forest.literalNull(
-            // TODO(ahe): Should store: realParameter.fileOffset
-            // https://github.com/dart-lang/sdk/issues/32289
-            null);
-        realParameter.initializer = initializer..parent = realParameter;
-        _typeInferrer.inferParameterInitializer(
-            this, initializer, realParameter.type);
+    if (formals?.parameters != null) {
+      for (int i = 0; i < formals.parameters.length; i++) {
+        KernelFormalParameterBuilder parameter = formals.parameters[i];
+        if (parameter.isOptional) {
+          VariableDeclaration realParameter = builder.formals[i].target;
+          Expression initializer =
+              parameter.target.initializer ?? forest.literalNull(
+                  // TODO(ahe): Should store: realParameter.fileOffset
+                  // https://github.com/dart-lang/sdk/issues/32289
+                  null);
+          realParameter.initializer = initializer..parent = realParameter;
+          _typeInferrer.inferParameterInitializer(
+              this, initializer, realParameter.type);
+        }
       }
     }
 
@@ -778,10 +772,9 @@
     }
 
     if (builder.kind == ProcedureKind.Setter) {
-      bool oneParameter = formals != null &&
-          formals.required.length == 1 &&
-          (formals.optional == null || formals.optional.formals.length == 0);
-      if (!oneParameter) {
+      if (formals?.parameters == null ||
+          formals.parameters.length != 1 ||
+          formals.parameters.single.isOptional) {
         int charOffset = formals?.charOffset ??
             body?.fileOffset ??
             builder.target.fileOffset;
@@ -984,10 +977,20 @@
     }
     enterFunctionTypeScope(typeParameterBuilders);
 
+    List<KernelFormalParameterBuilder> formals =
+        parameters.positionalParameters.length == 0
+            ? null
+            : new List<KernelFormalParameterBuilder>(
+                parameters.positionalParameters.length);
+    for (int i = 0; i < parameters.positionalParameters.length; i++) {
+      VariableDeclaration formal = parameters.positionalParameters[i];
+      formals[i] = new KernelFormalParameterBuilder(
+          null, 0, null, formal.name, false, library, formal.fileOffset)
+        ..declaration = formal;
+    }
     enterLocalScope(
         null,
-        new FormalParameters<Expression, Statement, Arguments>(
-                parameters.positionalParameters, null, -1, 0)
+        new FormalParameters(formals, offsetForToken(token), noLength, uri)
             .computeFormalParameterScope(scope, member, this));
 
     token = parser.parseExpression(parser.syntheticPreviousToken(token));
@@ -1002,7 +1005,7 @@
               .withLocation(uri, eof.charOffset, eof.length));
     }
 
-    ReturnJudgment fakeReturn = new ReturnJudgment(null, null, expression);
+    ReturnJudgment fakeReturn = new ReturnJudgment(null, expression);
 
     _typeInferrer.inferFunctionBody(
         this, const DynamicType(), AsyncMarker.Sync, fakeReturn);
@@ -1131,11 +1134,12 @@
   void handleSend(Token beginToken, Token endToken) {
     debugEvent("Send");
     Arguments arguments = pop();
-    List<DartType> typeArguments = pop();
+    List<UnresolvedType<KernelTypeBuilder>> typeArguments = pop();
     Object receiver = pop();
     if (arguments != null && typeArguments != null) {
       assert(forest.argumentsTypeArguments(arguments).isEmpty);
-      forest.argumentsSetTypeArguments(arguments, typeArguments);
+      forest.argumentsSetTypeArguments(
+          arguments, buildDartTypeArguments(typeArguments));
     } else {
       assert(typeArguments == null);
     }
@@ -1275,7 +1279,6 @@
     VariableDeclaration variable = new VariableDeclaration.forValue(a);
     push(new IfNullJudgment(
         variable,
-        tokensSaver?.ifNullTokens(token),
         forest.conditionalExpression(
             buildIsNull(new VariableGet(variable), offsetForToken(token), this),
             token,
@@ -1613,12 +1616,6 @@
         return new UnresolvedNameGenerator(this, token, n);
       }
     } else if (declaration.isTypeDeclaration) {
-      if (constantContext != ConstantContext.none &&
-          declaration.isTypeVariable &&
-          !member.isConstructor) {
-        addProblem(
-            fasta.messageNotAConstantExpression, charOffset, token.length);
-      }
       return new TypeUseGenerator(this, token, declaration, name);
     } else if (declaration.isLocal) {
       if (constantContext != ConstantContext.none &&
@@ -1671,7 +1668,6 @@
       return new StaticAccessGenerator(this, token, declaration.target, null);
     } else if (declaration is PrefixBuilder) {
       assert(prefix == null);
-      _typeInferrer.storePrefix(token, declaration);
       return new PrefixUseGenerator(this, token, declaration);
     } else if (declaration is LoadLibraryBuilder) {
       return new LoadLibraryGenerator(this, token, declaration);
@@ -1907,7 +1903,7 @@
     push(new VariableDeclarationJudgment(identifier.name, functionNestingLevel,
         forSyntheticToken: deprecated_extractToken(identifier).isSynthetic,
         initializer: initializer,
-        type: currentLocalVariableType,
+        type: buildDartType(currentLocalVariableType),
         isFinal: isFinal,
         isConst: isConst)
       ..fileOffset = identifier.charOffset
@@ -1951,7 +1947,7 @@
   @override
   void beginVariablesDeclaration(Token token, Token varFinalOrConst) {
     debugEvent("beginVariablesDeclaration");
-    DartType type = pop();
+    UnresolvedType<KernelTypeBuilder> type = pop();
     int modifiers = Modifier.validateVarFinalOrConst(varFinalOrConst?.lexeme);
     super.push(currentLocalVariableModifiers);
     super.push(currentLocalVariableType ?? NullValue.Type);
@@ -2148,7 +2144,7 @@
       int count, Token leftBracket, Token constKeyword, Token rightBracket) {
     debugEvent("LiteralList");
     List<Expression> expressions = popListForValue(count);
-    List<DartType> typeArguments = pop();
+    List<UnresolvedType<KernelTypeBuilder>> typeArguments = pop();
     DartType typeArgument;
     if (typeArguments != null) {
       if (typeArguments.length > 1) {
@@ -2157,7 +2153,7 @@
             offsetForToken(leftBracket),
             lengthOfSpan(leftBracket, leftBracket.endGroup));
       } else {
-        typeArgument = typeArguments.single;
+        typeArgument = buildDartType(typeArguments.single);
         if (library.loader.target.strongMode) {
           typeArgument =
               instantiateToBounds(typeArgument, coreTypes.objectClass);
@@ -2201,7 +2197,7 @@
     List<MapEntry> entries =
         new List<MapEntry>.filled(count, null, growable: true);
     popList(count, entries);
-    List<DartType> typeArguments = pop();
+    List<UnresolvedType<KernelTypeBuilder>> typeArguments = pop();
     DartType keyType;
     DartType valueType;
     if (typeArguments != null) {
@@ -2211,8 +2207,8 @@
             offsetForToken(leftBrace),
             lengthOfSpan(leftBrace, leftBrace.endGroup));
       } else {
-        keyType = typeArguments[0];
-        valueType = typeArguments[1];
+        keyType = buildDartType(typeArguments[0]);
+        valueType = buildDartType(typeArguments[1]);
         if (library.loader.target.strongMode) {
           keyType = instantiateToBounds(keyType, coreTypes.objectClass);
           valueType = instantiateToBounds(valueType, coreTypes.objectClass);
@@ -2258,8 +2254,8 @@
       value = symbolPartToString(part);
       push(forest.literalSymbolSingluar(value, hashToken, part));
     } else {
-      List<Identifier> parts = popList(identifierCount,
-          new List<Identifier>.filled(identifierCount, null, growable: true));
+      List<Identifier> parts =
+          popList(identifierCount, new List<Identifier>(identifierCount));
       value = symbolPartToString(parts.first);
       for (int i = 1; i < parts.length; i++) {
         value += ".${symbolPartToString(parts[i])}";
@@ -2272,7 +2268,7 @@
   void handleType(Token beginToken) {
     // TODO(ahe): The scope is wrong for return types of generic functions.
     debugEvent("Type");
-    List<DartType> arguments = pop();
+    List<UnresolvedType<KernelTypeBuilder>> arguments = pop();
     Object name = pop();
     if (name is QualifiedName) {
       QualifiedName qualified = name;
@@ -2288,15 +2284,23 @@
         return;
       }
     }
+    KernelTypeBuilder result;
     if (name is Generator) {
-      push(name.buildTypeWithBuiltArguments(arguments,
-          typeInferrer: _typeInferrer));
+      result = name.buildTypeWithResolvedArguments(arguments);
+      if (result == null) {
+        unhandled("null", "result", beginToken.charOffset, uri);
+      }
     } else if (name is TypeBuilder) {
-      push(name.build(library));
+      result = name.build(library);
+      if (result == null) {
+        unhandled("null", "result", beginToken.charOffset, uri);
+      }
     } else {
       unhandled(
           "${name.runtimeType}", "handleType", beginToken.charOffset, uri);
     }
+    push(new UnresolvedType<KernelTypeBuilder>(
+        result, beginToken.charOffset, uri));
   }
 
   @override
@@ -2312,8 +2316,6 @@
       ScopeBuilder scopeBuilder = new ScopeBuilder(scope);
       for (KernelTypeVariableBuilder builder in typeVariables) {
         String name = builder.name;
-        builder.binder = _typeInferrer.binderForTypeVariable(
-            builder, builder.charOffset, name);
         KernelTypeVariableBuilder existing = scopeBuilder[name];
         if (existing == null) {
           scopeBuilder.addMember(name, builder);
@@ -2330,11 +2332,11 @@
   @override
   void endFunctionType(Token functionToken) {
     debugEvent("FunctionType");
-    FormalParameters<Expression, Statement, Arguments> formals = pop();
-    DartType returnType = pop();
-    List<TypeParameter> typeVariables = typeVariableBuildersToKernel(pop());
-    FunctionType type = formals.toFunctionType(returnType, typeVariables);
-    _typeInferrer.functionType(functionToken.offset, type);
+    FormalParameters formals = pop();
+    UnresolvedType<KernelTypeBuilder> returnType = pop();
+    List<KernelTypeVariableBuilder> typeVariables = pop();
+    UnresolvedType<KernelTypeBuilder> type =
+        formals.toFunctionType(returnType, typeVariables);
     exitLocalScope();
     push(type);
   }
@@ -2342,15 +2344,19 @@
   @override
   void handleVoidKeyword(Token token) {
     debugEvent("VoidKeyword");
-    var type = const VoidType();
-    _typeInferrer.voidType(token.offset, token, type);
-    push(type);
+    int offset = offsetForToken(token);
+    push(new UnresolvedType<KernelTypeBuilder>(
+        new KernelNamedTypeBuilder("void", null)
+          ..bind(new VoidTypeBuilder<KernelTypeBuilder, VoidType>(
+              const VoidType(), library, offset)),
+        offset,
+        uri));
   }
 
   @override
   void handleAsOperator(Token operator) {
     debugEvent("AsOperator");
-    DartType type = pop();
+    UnresolvedType<KernelTypeBuilder> type = pop();
     Expression expression = popForValue();
     if (constantContext != ConstantContext.none) {
       push(buildProblem(
@@ -2360,14 +2366,14 @@
               operator.length)
           .desugared);
     } else {
-      push(forest.asExpression(expression, type, operator));
+      push(forest.asExpression(expression, buildDartType(type), operator));
     }
   }
 
   @override
   void handleIsOperator(Token isOperator, Token not) {
     debugEvent("IsOperator");
-    DartType type = pop();
+    DartType type = buildDartType(pop());
     Expression operand = popForValue();
     bool isInverted = not != null;
     Expression isExpression =
@@ -2429,8 +2435,7 @@
           .desugared;
     }
 
-    push(new ThrowJudgment(tokensSaver?.throwTokens(throwToken), expression,
-        desugaredError: error)
+    push(new ThrowJudgment(expression, desugaredError: error)
       ..fileOffset = offsetForToken(throwToken));
   }
 
@@ -2453,52 +2458,52 @@
       }
     }
     Identifier name = pop();
-    DartType type = pop();
+    UnresolvedType<KernelTypeBuilder> type = pop();
+    if (functionNestingLevel == 0) {
+      // TODO(ahe): The type we compute here may be different from what is
+      // computed in the outline phase. We should make sure that the outline
+      // phase computes the same type. See
+      // pkg/front_end/testcases/deferred_type_annotation.dart for an example
+      // where not calling [buildDartType] leads to a missing compile-time
+      // error. Also, notice that the type of the problematic parameter isn't
+      // `invalid-type`.
+      buildDartType(type);
+    }
     int modifiers = pop();
     if (inCatchClause) {
       modifiers |= finalMask;
     }
-    bool isConst = (modifiers & constMask) != 0;
-    bool isFinal = (modifiers & finalMask) != 0;
     List<Expression> annotations = pop();
-    VariableDeclaration variable;
+    KernelFormalParameterBuilder parameter;
     if (!inCatchClause &&
         functionNestingLevel == 0 &&
         memberKind != MemberKind.GeneralizedFunctionType) {
       ProcedureBuilder<TypeBuilder> member = this.member;
-      KernelFormalParameterBuilder formal = member.getFormal(name.name);
-      if (formal == null) {
+      parameter = member.getFormal(name.name);
+      if (parameter == null) {
         internalProblem(
             fasta.templateInternalProblemNotFoundIn
                 .withArguments(name.name, "formals"),
-            member.charOffset,
-            member.fileUri);
-      } else {
-        variable = formal.build(library);
-        if (member is KernelRedirectingFactoryBuilder &&
-            name.initializer != null) {
-          KernelRedirectingFactoryBuilder factory = member;
-          addProblem(
-              fasta.templateDefaultValueInRedirectingFactoryConstructor
-                  .withArguments(factory.redirectionTarget.fullNameForErrors),
-              name.initializer.fileOffset,
-              noLength);
-        } else {
-          variable.initializer = name.initializer;
-        }
+            offsetForToken(nameToken),
+            uri);
       }
     } else {
-      variable = new VariableDeclarationJudgment(
-          name?.name, functionNestingLevel,
-          forSyntheticToken:
-              deprecated_extractToken(name)?.isSynthetic ?? false,
-          type: type,
-          initializer: name?.initializer,
-          isFinal: isFinal,
-          isConst: isConst);
-      if (name != null) {
-        // TODO(ahe): Need an offset when name is null.
-        variable.fileOffset = name.charOffset;
+      parameter = new KernelFormalParameterBuilder(null, modifiers,
+          type?.builder, name?.name, false, library, offsetForToken(nameToken));
+    }
+    VariableDeclaration variable =
+        parameter.build(library, functionNestingLevel);
+    Expression initializer = name?.initializer;
+    if (initializer != null) {
+      if (member is KernelRedirectingFactoryBuilder) {
+        KernelRedirectingFactoryBuilder factory = member;
+        addProblem(
+            fasta.templateDefaultValueInRedirectingFactoryConstructor
+                .withArguments(factory.redirectionTarget.fullNameForErrors),
+            initializer.fileOffset,
+            noLength);
+      } else {
+        variable.initializer = initializer..parent = variable;
       }
     }
     if (annotations != null) {
@@ -2509,7 +2514,7 @@
         variable.addAnnotation(annotation);
       }
     }
-    push(variable);
+    push(parameter);
   }
 
   @override
@@ -2519,10 +2524,17 @@
     FormalParameterKind kind = optional("{", beginToken)
         ? FormalParameterKind.optionalNamed
         : FormalParameterKind.optionalPositional;
-    List<VariableDeclaration> variables =
-        new List<VariableDeclaration>.filled(count, null, growable: true);
-    popList(count, variables);
-    push(new OptionalFormals(kind, variables));
+    // When recovering from an empty list of optional arguments, count may be
+    // 0. It might be simpler if the parser didn't call this method in that
+    // case, however, then [beginOptionalFormalParameters] wouldn't always be
+    // matched by this method.
+    List<KernelFormalParameterBuilder> parameters =
+        new List<KernelFormalParameterBuilder>(count);
+    popList(count, parameters);
+    for (KernelFormalParameterBuilder parameter in parameters) {
+      parameter.kind = kind;
+    }
+    push(parameters);
   }
 
   @override
@@ -2537,11 +2549,11 @@
     if (inCatchClause || functionNestingLevel != 0) {
       exitLocalScope();
     }
-    FormalParameters<Expression, Statement, Arguments> formals = pop();
-    DartType returnType = pop();
-    List<TypeParameter> typeVariables = typeVariableBuildersToKernel(pop());
-    FunctionType type = formals.toFunctionType(returnType, typeVariables);
-    _typeInferrer.functionTypedFormalParameter(nameToken.offset, type);
+    FormalParameters formals = pop();
+    UnresolvedType<KernelTypeBuilder> returnType = pop();
+    List<KernelTypeVariableBuilder> typeVariables = pop();
+    UnresolvedType<KernelTypeBuilder> type =
+        formals.toFunctionType(returnType, typeVariables);
     exitLocalScope();
     push(type);
     functionNestingLevel--;
@@ -2584,20 +2596,24 @@
   void endFormalParameters(
       int count, Token beginToken, Token endToken, MemberKind kind) {
     debugEvent("FormalParameters");
-    OptionalFormals optional;
-    if (count > 0 && peek() is OptionalFormals) {
-      optional = pop();
+    List<KernelFormalParameterBuilder> optionals;
+    int optionalsCount = 0;
+    if (count > 0 && peek() is List<KernelFormalParameterBuilder>) {
+      optionals = pop();
       count--;
+      optionalsCount = optionals.length;
     }
-    List<VariableDeclaration> variables =
-        new List<VariableDeclaration>.filled(count, null, growable: true);
-    popList(count, variables);
-    FormalParameters<Expression, Statement, Arguments> formals =
-        new FormalParameters<Expression, Statement, Arguments>(
-            variables,
-            optional,
-            beginToken.charOffset,
-            endToken.end - beginToken.charOffset);
+    List<KernelFormalParameterBuilder> parameters;
+    if (count + optionalsCount > 0) {
+      parameters =
+          new List<KernelFormalParameterBuilder>(count + optionalsCount);
+      popList(count, parameters);
+      if (optionals != null) {
+        parameters.setRange(count, count + optionalsCount, optionals);
+      }
+    }
+    FormalParameters formals = new FormalParameters(parameters,
+        offsetForToken(beginToken), lengthOfSpan(beginToken, endToken), uri);
     constantContext = pop();
     push(formals);
     if ((inCatchClause || functionNestingLevel != 0) &&
@@ -2631,59 +2647,78 @@
     if (catchKeyword != null) {
       exitLocalScope();
     }
-    FormalParameters<Expression, Statement, Arguments> catchParameters =
-        popIfNotNull(catchKeyword);
-    DartType type = popIfNotNull(onKeyword) ?? const DynamicType();
-    VariableDeclaration exception;
-    VariableDeclaration stackTrace;
+    FormalParameters catchParameters = popIfNotNull(catchKeyword);
+    DartType exceptionType =
+        buildDartType(popIfNotNull(onKeyword)) ?? const DynamicType();
+    KernelFormalParameterBuilder exception;
+    KernelFormalParameterBuilder stackTrace;
+    List<Statement> compileTimeErrors;
     if (catchParameters != null) {
-      int requiredCount = catchParameters.required.length;
-      if ((requiredCount == 1 || requiredCount == 2) &&
-          catchParameters.optional == null) {
-        exception = catchParameters.required[0];
-        exception.type = type;
-        if (requiredCount == 2) {
-          stackTrace = catchParameters.required[1];
-          stackTrace.type = coreTypes.stackTraceClass.rawType;
+      int parameterCount = catchParameters.parameters.length;
+      if (parameterCount > 0) {
+        exception = catchParameters.parameters[0];
+        exception.build(library, functionNestingLevel).type = exceptionType;
+        if (parameterCount > 1) {
+          stackTrace = catchParameters.parameters[1];
+          stackTrace.build(library, functionNestingLevel).type =
+              coreTypes.stackTraceClass.rawType;
         }
-      } else {
-        // TODO(ahe): We're not storing this error in the AST.
-        buildProblem(fasta.messageInvalidCatchArguments,
-            catchParameters.charOffset, catchParameters.charLength);
-
-        var allFormals = <VariableDeclaration>[];
-        allFormals.addAll(catchParameters.required);
-        if (catchParameters.optional != null) {
-          allFormals.addAll(catchParameters.optional.formals);
-        }
-
-        var allCount = allFormals.length;
-        if (allCount >= 1) {
-          exception = allFormals[0];
-          exception.type = type;
-        }
-        if (allCount >= 2) {
-          stackTrace = allFormals[1];
-          stackTrace.type = coreTypes.stackTraceClass.rawType;
+      }
+      if (parameterCount > 2) {
+        // If parameterCount is 0, the parser reported an error already.
+        if (parameterCount != 0) {
+          for (int i = 2; i < parameterCount; i++) {
+            KernelFormalParameterBuilder parameter =
+                catchParameters.parameters[i];
+            compileTimeErrors ??= <Statement>[];
+            compileTimeErrors.add(buildProblemStatement(
+                fasta.messageCatchSyntaxExtraParameters, parameter.charOffset,
+                length: parameter.name.length));
+          }
         }
       }
     }
-    push(forest.catchClause(onKeyword, type, catchKeyword, exception,
-        stackTrace, coreTypes.stackTraceClass.rawType, body));
+    push(forest.catchClause(
+        onKeyword,
+        exceptionType,
+        catchKeyword,
+        exception?.target,
+        stackTrace?.target,
+        coreTypes.stackTraceClass.rawType,
+        body));
+    if (compileTimeErrors == null) {
+      push(NullValue.Block);
+    } else {
+      push(forest.block(null, compileTimeErrors, null));
+    }
   }
 
   @override
   void endTryStatement(int catchCount, Token tryKeyword, Token finallyKeyword) {
     Statement finallyBlock = popStatementIfNotNull(finallyKeyword);
-    List<Catch> catches = popList(
-        catchCount, new List<Catch>.filled(catchCount, null, growable: true));
+    List<Catch> catchBlocks;
+    List<Statement> compileTimeErrors;
+    if (catchCount != 0) {
+      List<Object> catchBlocksAndErrors =
+          popList(catchCount * 2, new List<Object>(catchCount * 2));
+      catchBlocks = new List<Catch>.filled(catchCount, null, growable: true);
+      for (int i = 0; i < catchCount; i++) {
+        catchBlocks[i] = catchBlocksAndErrors[i * 2];
+        Statement error = catchBlocksAndErrors[i * 2 + 1];
+        if (error != null) {
+          compileTimeErrors ??= <Statement>[];
+          compileTimeErrors.add(error);
+        }
+      }
+    }
     Statement tryBlock = popStatement();
-    if (problemInTry == null) {
-      push(forest.tryStatement(
-          tryKeyword, tryBlock, catches, finallyKeyword, finallyBlock));
+    Statement tryStatement = forest.tryStatement(
+        tryKeyword, tryBlock, catchBlocks, finallyKeyword, finallyBlock);
+    if (compileTimeErrors != null) {
+      compileTimeErrors.add(tryStatement);
+      push(forest.block(null, compileTimeErrors, null));
     } else {
-      push(problemInTry);
-      problemInTry = null;
+      push(tryStatement);
     }
   }
 
@@ -2827,7 +2862,7 @@
   void pushQualifiedReference(Token start, Token periodBeforeName) {
     Identifier suffix = popIfNotNull(periodBeforeName);
     Identifier identifier;
-    List<DartType> typeArguments = pop();
+    List<UnresolvedType<KernelTypeBuilder>> typeArguments = pop();
     Object type = pop();
     if (type is QualifiedName) {
       identifier = type;
@@ -2880,7 +2915,7 @@
       LocatedMessage argMessage = checkArgumentsForFunction(
           target.function, arguments, charOffset, typeParameters);
       if (argMessage != null) {
-        var error = throwNoSuchMethodError(
+        Expression error = throwNoSuchMethodError(
             forest.literalNull(null)..fileOffset = charOffset,
             target.name.name,
             arguments,
@@ -3090,7 +3125,7 @@
     Token nameLastToken =
         deprecated_extractToken(nameLastIdentifier) ?? nameToken;
     String name = pop();
-    List<DartType> typeArguments = pop();
+    List<UnresolvedType<KernelTypeBuilder>> typeArguments = pop();
 
     Object type = pop();
 
@@ -3122,7 +3157,7 @@
       Token nameLastToken,
       Arguments arguments,
       String name,
-      List<DartType> typeArguments,
+      List<UnresolvedType<KernelTypeBuilder>> typeArguments,
       int charOffset,
       Constness constness) {
     if (arguments == null) {
@@ -3132,7 +3167,8 @@
 
     if (typeArguments != null) {
       assert(forest.argumentsTypeArguments(arguments).isEmpty);
-      forest.argumentsSetTypeArguments(arguments, typeArguments);
+      forest.argumentsSetTypeArguments(
+          arguments, buildDartTypeArguments(typeArguments));
     }
 
     String errorName;
@@ -3224,8 +3260,7 @@
   @override
   void endTypeArguments(int count, Token beginToken, Token endToken) {
     debugEvent("TypeArguments");
-    push(
-        popList(count, new List<DartType>.filled(count, null, growable: true)));
+    push(popList(count, new List<UnresolvedType<KernelTypeBuilder>>(count)));
   }
 
   @override
@@ -3260,11 +3295,7 @@
     debugEvent("NamedArgument");
     Expression value = popForValue();
     Identifier identifier = pop();
-    push(new NamedExpressionJudgment(
-        tokensSaver?.namedExpressionTokens(
-            deprecated_extractToken(identifier), colon),
-        identifier.name,
-        value)
+    push(new NamedExpressionJudgment(identifier.name, value)
       ..fileOffset = identifier.charOffset);
   }
 
@@ -3337,23 +3368,18 @@
     Statement body = popStatement();
     AsyncMarker asyncModifier = pop();
     exitLocalScope();
-    FormalParameters<Expression, Statement, Arguments> formals = pop();
+    FormalParameters formals = pop();
     Object declaration = pop();
-    DartType returnType = pop();
+    UnresolvedType<KernelTypeBuilder> returnType = pop();
     bool hasImplicitReturnType = returnType == null;
-    returnType ??= const DynamicType();
     exitFunction();
-    List<TypeParameter> typeParameters = typeVariableBuildersToKernel(pop());
+    List<KernelTypeVariableBuilder> typeParameters = pop();
     List<Expression> annotations;
     if (!isFunctionExpression) {
       annotations = pop(); // Metadata.
     }
-    FunctionNode function = formals.addToFunction(new FunctionNodeJudgment(body,
-        typeParameters: typeParameters,
-        asyncMarker: asyncModifier,
-        returnType: returnType)
-      ..fileOffset = formals.charOffset
-      ..fileEndOffset = token.charOffset);
+    FunctionNode function = formals.buildFunctionNode(library, returnType,
+        typeParameters, asyncModifier, body, token.charOffset);
 
     if (declaration is FunctionDeclaration) {
       VariableDeclaration variable = declaration.variable;
@@ -3429,16 +3455,15 @@
     Statement body = popStatement();
     AsyncMarker asyncModifier = pop();
     exitLocalScope();
-    FormalParameters<Expression, Statement, Arguments> formals = pop();
+    FormalParameters formals = pop();
     exitFunction();
-    List<TypeParameter> typeParameters = typeVariableBuildersToKernel(pop());
-    FunctionNode function = formals.addToFunction(new FunctionNodeJudgment(body,
-        typeParameters: typeParameters, asyncMarker: asyncModifier)
-      ..fileOffset = beginToken.charOffset
-      ..fileEndOffset = token.charOffset);
+    List<KernelTypeVariableBuilder> typeParameters = pop();
+    FunctionNode function = formals.buildFunctionNode(
+        library, null, typeParameters, asyncModifier, body, token.charOffset)
+      ..fileOffset = beginToken.charOffset;
     if (constantContext != ConstantContext.none) {
       push(buildProblem(fasta.messageNotAConstantExpression, formals.charOffset,
-          formals.charLength));
+          formals.length));
     } else {
       push(new FunctionExpressionJudgment(function)
         ..fileOffset = offsetForToken(beginToken));
@@ -3533,13 +3558,7 @@
           buildProblem(message, offsetForToken(token), lengthForToken(token)));
     }
     Statement result = new ForInJudgment(
-        tokensSaver?.forInStatementTokens(awaitToken, forToken, leftParenthesis,
-            inKeyword, leftParenthesis.endGroup),
-        variable,
-        expression,
-        kernelBody,
-        declaresVariable,
-        syntheticAssignment,
+        variable, expression, kernelBody, declaresVariable, syntheticAssignment,
         isAsync: awaitToken != null)
       ..fileOffset = awaitToken?.charOffset ?? forToken.charOffset
       ..bodyOffset = kernelBody.fileOffset;
@@ -3560,8 +3579,7 @@
   @override
   void beginLabeledStatement(Token token, int labelCount) {
     debugEvent("beginLabeledStatement");
-    List<Label> labels =
-        new List<Label>.filled(labelCount, null, growable: true);
+    List<Label> labels = new List<Label>(labelCount);
     popList(labelCount, labels);
     enterLocalScope(null, scope.createNestedLabelScope());
     LabelTarget target =
@@ -3597,15 +3615,12 @@
   @override
   void endRethrowStatement(Token rethrowToken, Token endToken) {
     debugEvent("RethrowStatement");
-    var error = inCatchBlock
+    push(new ExpressionStatementJudgment(new RethrowJudgment(inCatchBlock
         ? null
         : buildProblem(fasta.messageRethrowNotCatch,
                 offsetForToken(rethrowToken), lengthForToken(rethrowToken))
-            .desugared;
-    push(new ExpressionStatementJudgment(
-        new RethrowJudgment(tokensSaver?.rethrowTokens(rethrowToken), error)
-          ..fileOffset = offsetForToken(rethrowToken),
-        tokensSaver?.expressionStatementTokens(endToken)));
+            .desugared)
+      ..fileOffset = offsetForToken(rethrowToken)));
   }
 
   @override
@@ -3747,11 +3762,7 @@
     for (Expression expression in expressions) {
       expressionOffsets.add(forest.readOffset(expression));
     }
-    push(new SwitchCaseJudgment(
-        tokensSaver?.switchCaseTokens(defaultKeyword, colonAfterDefault),
-        expressions,
-        expressionOffsets,
-        block,
+    push(new SwitchCaseJudgment(expressions, expressionOffsets, block,
         isDefault: defaultKeyword != null)
       ..fileOffset = firstToken.charOffset);
     push(labels);
@@ -3766,13 +3777,7 @@
     exitSwitchScope();
     exitLocalScope();
     Expression expression = popForValue();
-    // TODO(brianwilkerson): Plumb through the left and right parentheses and
-    // the left and right curly braces.
-    Statement result = new SwitchStatementJudgment(
-        tokensSaver?.switchStatementTokens(
-            switchKeyword, null, null, null, null),
-        expression,
-        cases)
+    Statement result = new SwitchStatementJudgment(expression, cases)
       ..fileOffset = switchKeyword.charOffset;
     if (target.hasUsers) {
       result = new LabeledStatementJudgment(result);
@@ -3899,10 +3904,7 @@
       }
       if (target.isGotoTarget &&
           target.functionNestingLevel == functionNestingLevel) {
-        ContinueSwitchStatement statement = new ContinueSwitchJudgment(
-            tokensSaver?.continueSwitchStatementTokens(
-                continueKeyword, endToken),
-            null)
+        ContinueSwitchStatement statement = new ContinueSwitchJudgment(null)
           ..fileOffset = continueKeyword.charOffset;
         target.addGoto(statement);
         push(statement);
@@ -3934,57 +3936,12 @@
   }
 
   @override
-  void beginTypeVariables(Token token) {
-    debugEvent("beginTypeVariables");
-
-    // TODO(danrubel): Now that the type variable events have been reordered,
-    // we should be able to cleanup body builder type variable declaration
-    // handling and remove this hack.
-
-    OutlineBuilder listener = new OutlineBuilder(library);
-    // TODO(dmitryas):  [ClassMemberParser] shouldn't be used to parse and build
-    // the type variables for the local function.  It also causes the unresolved
-    // types from the bounds of the type variables to appear in [library.types].
-    // See the code that resolves them below.
-    new ClassMemberParser(listener)
-        .parseTypeVariablesOpt(new Token.eof(-1)..next = token);
-    List<Object> typeVariables = listener.pop();
-    if (typeVariables != null) {
-      typeVariables = new List<KernelTypeVariableBuilder>.from(typeVariables);
-    }
-    enterFunctionTypeScope(typeVariables);
-
-    // The invocation of [enterFunctionTypeScope] above has put the type
-    // variables into the scope, and now the possibly unresolved types from
-    // the bounds of the variables can be resolved.  This is needed to apply
-    // instantiate-to-bound later.
-    // TODO(dmitryas):  Move the resolution to the appropriate place once
-    // [ClassMemberParser] is not used to build the type variables for the local
-    // function.  See the comment above.
-    for (UnresolvedType<TypeBuilder> t in library.types) {
-      t.resolveIn(scope, library);
-    }
-    library.types.clear();
-  }
-
-  @override
   void beginTypeVariable(Token token) {
     debugEvent("beginTypeVariable");
     Identifier name = pop();
     List<Expression> annotations = pop();
-
-    KernelTypeVariableBuilder variable;
-    Object inScope = scopeLookup(scope, name.name, token);
-    if (inScope is TypeUseGenerator) {
-      variable = inScope.declaration;
-    } else {
-      // Something went wrong when pre-parsing the type variables.
-      // Assume an error is reported elsewhere.
-      variable = new KernelTypeVariableBuilder(
-          name.name, library, name.charOffset, null);
-      variable.binder = _typeInferrer.binderForTypeVariable(
-          variable, variable.charOffset, variable.name);
-    }
+    KernelTypeVariableBuilder variable = new KernelTypeVariableBuilder(
+        name.name, library, name.charOffset, null);
     if (annotations != null) {
       _typeInferrer.inferMetadata(this, annotations);
       for (Expression annotation in annotations) {
@@ -4000,22 +3957,19 @@
     assert(count > 0);
     List<KernelTypeVariableBuilder> typeVariables =
         popList(count, new List<KernelTypeVariableBuilder>(count));
-
-    // TODO(danrubel): Call enterFunctionScope here
-    // once the hack in beginTypeVariables has been removed.
-    //enterFunctionTypeScope(typeVariables);
+    enterFunctionTypeScope(typeVariables);
     push(typeVariables);
   }
 
   @override
   void endTypeVariable(Token token, int index, Token extendsOrSuper) {
     debugEvent("TypeVariable");
-    DartType bound = pop();
+    UnresolvedType<KernelTypeBuilder> bound = pop();
     // Peek to leave type parameters on top of stack.
     List<KernelTypeVariableBuilder> typeVariables = peek();
 
     KernelTypeVariableBuilder variable = typeVariables[index];
-    variable.parameter.bound = bound;
+    variable.bound = bound?.builder;
   }
 
   @override
@@ -4065,10 +4019,7 @@
         growable: true);
     int i = 0;
     for (KernelTypeVariableBuilder builder in typeVariableBuilders) {
-      var typeParameter = builder.target;
-      _typeInferrer.typeVariableDeclaration(
-          builder.charOffset, builder.binder, typeParameter);
-      typeParameters[i++] = typeParameter;
+      typeParameters[i++] = builder.target;
     }
     return typeParameters;
   }
@@ -4162,9 +4113,9 @@
 
   Statement buildProblemStatement(Message message, int charOffset,
       {List<LocatedMessage> context, int length}) {
+    length ??= noLength;
     return new ExpressionStatementJudgment(
-        buildProblem(message, charOffset, length ?? noLength, context: context),
-        null);
+        buildProblem(message, charOffset, length, context: context));
   }
 
   Statement wrapInProblemStatement(Statement statement, Message message) {
@@ -4297,10 +4248,8 @@
           charOffset);
     }
     needsImplicitSuperInitializer = false;
-    // TODO(brianwilkerson): Plumb through the `super`, period, and constructor
-    // name tokens.
     return new SuperInitializerJudgment(
-        null, constructor, forest.castArguments(arguments))
+        constructor, forest.castArguments(arguments))
       ..fileOffset = charOffset
       ..isSynthetic = isSynthetic;
   }
@@ -4352,22 +4301,44 @@
   }
 
   @override
-  DartType validatedTypeVariableUse(
-      TypeParameterType type, int offset, bool nonInstanceAccessIsError) {
-    if (!isInstanceContext && type.parameter.parent is Class) {
-      Message message = fasta.messageTypeVariableInStaticContext;
-      int length = type.parameter.name.length;
-      if (nonInstanceAccessIsError) {
-        addProblem(message, offset, length, severity: Severity.error);
+  UnresolvedType<KernelTypeBuilder> validateTypeUse(
+      UnresolvedType<KernelTypeBuilder> unresolved,
+      bool nonInstanceAccessIsError) {
+    KernelTypeBuilder builder = unresolved.builder;
+    if (builder is KernelNamedTypeBuilder &&
+        builder.declaration.isTypeVariable) {
+      TypeParameter typeParameter = builder.declaration.target;
+      bool isConstant = constantContext != ConstantContext.none;
+      LocatedMessage message;
+      bool suppressMessage = false;
+      if (!isInstanceContext && typeParameter.parent is Class) {
+        message = fasta.messageTypeVariableInStaticContext.withLocation(
+            unresolved.fileUri,
+            unresolved.charOffset,
+            typeParameter.name.length);
+        if (!nonInstanceAccessIsError &&
+            !isConstant &&
+            !library.loader.target.strongMode) {
+          // This is a warning in legacy mode.
+          addProblem(message.messageObject, message.charOffset, message.length);
+          suppressMessage = true;
+        }
+      } else if (constantContext != ConstantContext.none) {
+        message = fasta.messageTypeVariableInConstantContext.withLocation(
+            unresolved.fileUri,
+            unresolved.charOffset,
+            typeParameter.name.length);
       } else {
-        addProblemErrorIfConst(message, offset, length);
+        return unresolved;
       }
-      return const InvalidType();
-    } else if (constantContext != ConstantContext.none) {
-      addProblem(fasta.messageTypeVariableInConstantContext, offset,
-          type.parameter.name.length);
+      return new UnresolvedType<KernelTypeBuilder>(
+          new KernelNamedTypeBuilder(typeParameter.name, null)
+            ..bind(new KernelInvalidTypeBuilder(
+                typeParameter.name, message, suppressMessage)),
+          unresolved.charOffset,
+          unresolved.fileUri);
     }
-    return type;
+    return unresolved;
   }
 
   @override
@@ -4536,13 +4507,24 @@
   }
 
   @override
-  void storeTypeUse(int offset, Node node) {
-    _typeInferrer.storeTypeUse(offset, node);
+  DartType buildDartType(UnresolvedType<KernelTypeBuilder> unresolvedType,
+      {bool nonInstanceAccessIsError: false}) {
+    if (unresolvedType == null) return null;
+    return validateTypeUse(unresolvedType, nonInstanceAccessIsError)
+        .builder
+        ?.build(library);
   }
 
   @override
-  void storeUnresolved(Token token) {
-    _typeInferrer.storePrefix(token, null);
+  List<DartType> buildDartTypeArguments(
+      List<UnresolvedType<KernelTypeBuilder>> unresolvedTypes) {
+    if (unresolvedTypes == null) return <DartType>[];
+    List<DartType> types =
+        new List<DartType>.filled(unresolvedTypes.length, null, growable: true);
+    for (int i = 0; i < types.length; i++) {
+      types[i] = buildDartType(unresolvedTypes[i]);
+    }
+    return types;
   }
 }
 
@@ -4692,98 +4674,91 @@
   String get fullNameForErrors => "<label-target>";
 }
 
-class OptionalFormals {
-  final FormalParameterKind kind;
-
-  final List<VariableDeclaration> formals;
-
-  OptionalFormals(this.kind, this.formals);
-}
-
-class FormalParameters<Expression, Statement, Arguments> {
-  final List<VariableDeclaration> required;
-  final OptionalFormals optional;
+class FormalParameters {
+  final List<KernelFormalParameterBuilder> parameters;
   final int charOffset;
-  final int charLength;
+  final int length;
+  final Uri uri;
 
-  FormalParameters(
-      this.required, this.optional, this.charOffset, this.charLength);
-
-  FunctionNode addToFunction(FunctionNode function) {
-    function.requiredParameterCount = required.length;
-    function.positionalParameters.addAll(required);
-    if (optional != null) {
-      if (isOptionalPositionalFormalParameterKind(optional.kind)) {
-        function.positionalParameters.addAll(optional.formals);
-      } else {
-        function.namedParameters.addAll(optional.formals);
-        setParents(function.namedParameters, function);
-      }
+  FormalParameters(this.parameters, this.charOffset, this.length, this.uri) {
+    if (parameters?.isEmpty ?? false) {
+      throw "Empty parameters should be null";
     }
-    setParents(function.positionalParameters, function);
-    return function;
   }
 
-  FunctionType toFunctionType(DartType returnType,
-      [List<TypeParameter> typeParameters]) {
-    returnType ??= const DynamicType();
-    typeParameters ??= const <TypeParameter>[];
-    int requiredParameterCount = required.length;
-    List<DartType> positionalParameters = <DartType>[];
-    List<NamedType> namedParameters = const <NamedType>[];
-    for (VariableDeclaration parameter in required) {
-      positionalParameters.add(parameter.type);
-    }
-    if (optional != null) {
-      if (isOptionalPositionalFormalParameterKind(optional.kind)) {
-        for (VariableDeclaration parameter in optional.formals) {
-          positionalParameters.add(parameter.type);
+  FunctionNode buildFunctionNode(
+      KernelLibraryBuilder library,
+      UnresolvedType<KernelTypeBuilder> returnType,
+      List<KernelTypeVariableBuilder> typeParameters,
+      AsyncMarker asyncModifier,
+      Statement body,
+      int fileEndOffset) {
+    FunctionType type =
+        toFunctionType(returnType, typeParameters).builder.build(library);
+    List<VariableDeclaration> positionalParameters = <VariableDeclaration>[];
+    List<VariableDeclaration> namedParameters = <VariableDeclaration>[];
+    if (parameters != null) {
+      for (KernelFormalParameterBuilder parameter in parameters) {
+        if (parameter.isNamed) {
+          namedParameters.add(parameter.target);
+        } else {
+          positionalParameters.add(parameter.target);
         }
-      } else {
-        namedParameters = <NamedType>[];
-        for (VariableDeclaration parameter in optional.formals) {
-          namedParameters.add(new NamedType(parameter.name, parameter.type));
-        }
-        namedParameters.sort();
       }
+      namedParameters.sort((VariableDeclaration a, VariableDeclaration b) {
+        return a.name.compareTo(b.name);
+      });
     }
-    return new FunctionType(positionalParameters, returnType,
+    return new FunctionNodeJudgment(body,
+        typeParameters: type.typeParameters,
+        positionalParameters: positionalParameters,
         namedParameters: namedParameters,
-        requiredParameterCount: requiredParameterCount,
-        typeParameters: typeParameters);
+        requiredParameterCount: type.requiredParameterCount,
+        returnType: type.returnType,
+        asyncMarker: asyncModifier)
+      ..fileOffset = charOffset
+      ..fileEndOffset = fileEndOffset;
+  }
+
+  UnresolvedType<KernelTypeBuilder> toFunctionType(
+      UnresolvedType<KernelTypeBuilder> returnType,
+      [List<KernelTypeVariableBuilder> typeParameters]) {
+    return new UnresolvedType(
+        new KernelFunctionTypeBuilder(
+            returnType?.builder, typeParameters, parameters),
+        charOffset,
+        uri);
   }
 
   Scope computeFormalParameterScope(
       Scope parent, Declaration declaration, ExpressionGeneratorHelper helper) {
-    if (required.length == 0 && optional == null) return parent;
+    if (parameters == null) return parent;
+    assert(parameters.isNotEmpty);
     Map<String, Declaration> local = <String, Declaration>{};
 
-    for (VariableDeclaration parameter in required) {
-      String name = parameter.name;
-      if (local[name] != null) {
+    for (KernelFormalParameterBuilder parameter in parameters) {
+      Declaration existing = local[parameter.name];
+      if (existing != null) {
         helper.addProblem(
-            fasta.templateDuplicatedParameterName.withArguments(name),
-            parameter.fileOffset,
-            name.length);
-      }
-      local[name] = new KernelVariableBuilder(
-          parameter, declaration, declaration.fileUri);
-    }
-    if (optional != null) {
-      for (VariableDeclaration parameter in optional.formals) {
-        String name = parameter.name;
-        if (local[name] != null) {
-          helper.addProblem(
-              fasta.templateDuplicatedParameterName.withArguments(name),
-              parameter.fileOffset,
-              name.length);
-        }
-        local[name] = new KernelVariableBuilder(
-            parameter, declaration, declaration.fileUri);
+            fasta.templateDuplicatedName.withArguments(parameter.name),
+            parameter.charOffset,
+            parameter.name.length,
+            context: <LocatedMessage>[
+              fasta.templateDuplicatedNameCause
+                  .withArguments(parameter.name)
+                  .withLocation(existing.fileUri, existing.charOffset,
+                      parameter.name.length)
+            ]);
+      } else {
+        local[parameter.name] = parameter;
       }
     }
     return new Scope(local, null, parent, "formals", isModifiable: false);
   }
+
+  String toString() {
+    return "FormalParameters($parameters, $charOffset, $uri)";
+  }
 }
 
 /// Returns a block like this:
diff --git a/pkg/front_end/lib/src/fasta/kernel/expression_generator.dart b/pkg/front_end/lib/src/fasta/kernel/expression_generator.dart
index d24d7af..f81b7ef 100644
--- a/pkg/front_end/lib/src/fasta/kernel/expression_generator.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/expression_generator.dart
@@ -11,6 +11,7 @@
 
 import '../fasta_codes.dart'
     show
+        LocatedMessage,
         Message,
         Template,
         messageCantUsePrefixAsExpression,
@@ -45,8 +46,6 @@
 
 import '../problems.dart' show unhandled, unsupported;
 
-import '../type_inference/type_inferrer.dart' show TypeInferrer;
-
 import 'constness.dart' show Constness;
 
 import 'expression_generator_helper.dart' show ExpressionGeneratorHelper;
@@ -69,31 +68,22 @@
         Expression,
         Initializer,
         InvalidConstructorInvocationJudgment,
-        InvalidType,
         Member,
         Name,
         Procedure,
         StaticInvocationJudgment,
         SyntheticExpressionJudgment,
-        TreeNode,
-        TypeParameterType,
         UnresolvedTargetInvocationJudgment,
-        UnresolvedVariableUnaryJudgment,
         VariableDeclaration;
 
 import 'kernel_builder.dart'
     show
         AccessErrorBuilder,
-        BuiltinTypeBuilder,
-        ClassBuilder,
         Declaration,
-        DynamicTypeBuilder,
-        FunctionTypeAliasBuilder,
-        InvalidTypeBuilder,
-        KernelClassBuilder,
-        KernelFunctionTypeAliasBuilder,
-        KernelTypeVariableBuilder,
-        TypeVariableBuilder;
+        KernelInvalidTypeBuilder,
+        KernelNamedTypeBuilder,
+        KernelTypeBuilder,
+        UnresolvedType;
 
 import 'kernel_expression_generator.dart'
     show IncompleteSendGenerator, SendAccessGenerator;
@@ -195,8 +185,10 @@
   Initializer buildFieldInitializer(Map<String, int> initializedFields) {
     int offset = offsetForToken(token);
     return helper.buildInvalidInitializer(
-        helper.buildProblem(messageInvalidInitializer, offset,
-            lengthForToken(token)) /* TODO(ahe): Add .desugared here? */,
+        helper
+            .buildProblem(
+                messageInvalidInitializer, offset, lengthForToken(token))
+            .desugared,
         offset);
   }
 
@@ -223,11 +215,14 @@
     }
   }
 
-  DartType buildTypeWithBuiltArguments(List<DartType> arguments,
-      {bool nonInstanceAccessIsError: false, TypeInferrer typeInferrer}) {
-    helper.addProblem(templateNotAType.withArguments(token.lexeme),
-        offsetForToken(token), lengthForToken(token));
-    return const InvalidType();
+  KernelTypeBuilder buildTypeWithResolvedArguments(
+      List<UnresolvedType<KernelTypeBuilder>> arguments) {
+    KernelNamedTypeBuilder result =
+        new KernelNamedTypeBuilder(token.lexeme, null);
+    result.bind(result.buildInvalidType(templateNotAType
+        .withArguments(token.lexeme)
+        .withLocation(uri, offsetForToken(token), lengthForToken(token))));
+    return result;
   }
 
   /* Expression | Generator */ Object qualifiedLookup(Token name) {
@@ -235,7 +230,7 @@
   }
 
   Expression invokeConstructor(
-      List<DartType> typeArguments,
+      List<UnresolvedType<KernelTypeBuilder>> typeArguments,
       String name,
       Arguments arguments,
       Token nameToken,
@@ -243,21 +238,17 @@
       Constness constness) {
     if (typeArguments != null) {
       assert(forest.argumentsTypeArguments(arguments).isEmpty);
-      forest.argumentsSetTypeArguments(arguments, typeArguments);
+      forest.argumentsSetTypeArguments(
+          arguments, helper.buildDartTypeArguments(typeArguments));
     }
-    var error = helper.throwNoSuchMethodError(
-        forest.literalNull(token),
-        name == "" ? plainNameForRead : "${plainNameForRead}.$name",
-        arguments,
-        nameToken.charOffset);
-
-    return new InvalidConstructorInvocationJudgment(error, null, arguments);
-  }
-
-  /// This generator was unexpectedly used as a prefix in a type name.
-  /// Store its resolution anyway.
-  void storeUnexpectedTypePrefix(TypeInferrer typeInferrer) {
-    typeInferrer.storeUnresolved(token);
+    return new InvalidConstructorInvocationJudgment(
+        helper.throwNoSuchMethodError(
+            forest.literalNull(token),
+            name == "" ? plainNameForRead : "${plainNameForRead}.$name",
+            arguments,
+            nameToken.charOffset),
+        null,
+        arguments);
   }
 
   bool get isThisPropertyAccess => false;
@@ -505,7 +496,7 @@
   @override
   buildPropertyAccess(
       IncompleteSendGenerator send, int operatorOffset, bool isNullAware) {
-    var propertyAccess =
+    Object propertyAccess =
         suffixGenerator.buildPropertyAccess(send, operatorOffset, isNullAware);
     if (propertyAccess is Generator) {
       return new DeferredAccessGenerator(
@@ -527,17 +518,30 @@
   String get debugName => "DeferredAccessGenerator";
 
   @override
-  DartType buildTypeWithBuiltArguments(List<DartType> arguments,
-      {bool nonInstanceAccessIsError: false, TypeInferrer typeInferrer}) {
-    helper.addProblem(
-        templateDeferredTypeAnnotation.withArguments(
-            suffixGenerator.buildTypeWithBuiltArguments(arguments,
-                nonInstanceAccessIsError: nonInstanceAccessIsError,
-                typeInferrer: typeInferrer),
-            prefixGenerator.plainNameForRead),
-        offsetForToken(prefixGenerator.token),
-        lengthOfSpan(prefixGenerator.token, token));
-    return const InvalidType();
+  KernelTypeBuilder buildTypeWithResolvedArguments(
+      List<UnresolvedType<KernelTypeBuilder>> arguments) {
+    String name =
+        "${prefixGenerator.plainNameForRead}.${suffixGenerator.plainNameForRead}";
+    KernelTypeBuilder type =
+        suffixGenerator.buildTypeWithResolvedArguments(arguments);
+    LocatedMessage message;
+    if (type is KernelNamedTypeBuilder &&
+        type.declaration is KernelInvalidTypeBuilder) {
+      KernelInvalidTypeBuilder declaration = type.declaration;
+      message = declaration.message;
+    } else {
+      int charOffset = offsetForToken(prefixGenerator.token);
+      message = templateDeferredTypeAnnotation
+          .withArguments(
+              helper.buildDartType(
+                  new UnresolvedType<KernelTypeBuilder>(type, charOffset, uri)),
+              prefixGenerator.plainNameForRead)
+          .withLocation(
+              uri, charOffset, lengthOfSpan(prefixGenerator.token, token));
+    }
+    KernelNamedTypeBuilder result = new KernelNamedTypeBuilder(name, null);
+    result.bind(result.buildInvalidType(message));
+    return result;
   }
 
   @override
@@ -550,7 +554,7 @@
 
   @override
   Expression invokeConstructor(
-      List<DartType> typeArguments,
+      List<UnresolvedType<KernelTypeBuilder>> typeArguments,
       String name,
       Arguments arguments,
       Token nameToken,
@@ -585,25 +589,13 @@
   String get debugName => "TypeUseGenerator";
 
   @override
-  DartType buildTypeWithBuiltArguments(List<DartType> arguments,
-      {bool nonInstanceAccessIsError: false, TypeInferrer typeInferrer}) {
-    var declaration = this.declaration;
+  KernelTypeBuilder buildTypeWithResolvedArguments(
+      List<UnresolvedType<KernelTypeBuilder>> arguments) {
     if (arguments != null) {
-      int expected = 0;
-      if (declaration is KernelClassBuilder) {
-        expected = declaration.target.typeParameters.length;
-      } else if (declaration is FunctionTypeAliasBuilder) {
-        expected = declaration.target.typeParameters.length;
-      } else if (declaration is KernelTypeVariableBuilder) {
-        // Type arguments on a type variable - error reported elsewhere.
-      } else if (declaration is BuiltinTypeBuilder) {
-        // Type arguments on a built-in type, for example, dynamic or void.
-        expected = 0;
-      } else {
-        return unhandled("${declaration.runtimeType}",
-            "TypeUseGenerator.buildType", offsetForToken(token), helper.uri);
-      }
+      int expected = declaration.typeVariablesCount;
       if (arguments.length != expected) {
+        // Build the type arguments to report any errors they may have.
+        helper.buildDartTypeArguments(arguments);
         helper.warnTypeArgumentsMismatch(
             declaration.name, expected, offsetForToken(token));
         // We ignore the provided arguments, which will in turn return the
@@ -620,57 +612,26 @@
           lengthForToken(token));
     }
 
-    DartType type;
-    if (arguments == null) {
-      TypeDeclarationBuilder typeDeclaration = declaration;
-      if (typeDeclaration is KernelClassBuilder) {
-        type = typeDeclaration.buildType(helper.library, null);
-      } else if (typeDeclaration is KernelFunctionTypeAliasBuilder) {
-        type = typeDeclaration.buildType(helper.library, null);
+    List<KernelTypeBuilder> argumentBuilders;
+    if (arguments != null) {
+      argumentBuilders = new List<KernelTypeBuilder>(arguments.length);
+      for (int i = 0; i < argumentBuilders.length; i++) {
+        argumentBuilders[i] =
+            helper.validateTypeUse(arguments[i], false).builder;
       }
     }
-    if (type == null) {
-      type =
-          declaration.buildTypesWithBuiltArguments(helper.library, arguments);
-    }
-    TreeNode declarationTarget;
-    Object declarationBinder;
-    if (declaration is KernelTypeVariableBuilder &&
-        declaration.binder != null) {
-      declarationBinder = declaration.binder;
-    } else if (declaration is DynamicTypeBuilder ||
-        declaration is InvalidTypeBuilder) {
-      // There's no target associated with these types, so we have to let
-      // the analyzer fill it in.
-    } else if (declaration is ClassBuilder ||
-        declaration is TypeVariableBuilder ||
-        declaration is FunctionTypeAliasBuilder) {
-      declarationTarget = declaration.target;
-    } else {
-      return unhandled(
-          "${declaration.runtimeType}",
-          "TypeUseGenerator.buildTypeWithBuiltArguments",
-          offsetForToken(token),
-          helper.uri);
-    }
-    typeInferrer?.storeTypeReference(token.charOffset, token.isSynthetic,
-        declarationTarget, declarationBinder, type);
-    if (type is TypeParameterType) {
-      return helper.validatedTypeVariableUse(
-          type, offsetForToken(token), nonInstanceAccessIsError);
-    }
-    return type;
+    return new KernelNamedTypeBuilder(plainNameForRead, argumentBuilders)
+      ..bind(declaration);
   }
 
   @override
   Expression invokeConstructor(
-      List<DartType> typeArguments,
+      List<UnresolvedType<KernelTypeBuilder>> typeArguments,
       String name,
       Arguments arguments,
       Token nameToken,
       Token nameLastToken,
       Constness constness) {
-    helper.storeTypeUse(offsetForToken(token), declaration.target);
     return helper.buildConstructorInvocation(
         declaration,
         nameToken,
@@ -683,9 +644,11 @@
   }
 
   @override
-  void storeUnexpectedTypePrefix(TypeInferrer typeInferrer) {
-    typeInferrer.storeTypeReference(offsetForToken(token), token.isSynthetic,
-        declaration.target, null, const DynamicType());
+  void printOn(StringSink sink) {
+    sink.write(", declaration: ");
+    sink.write(declaration);
+    sink.write(", plainNameForRead: ");
+    sink.write(plainNameForRead);
   }
 }
 
@@ -713,16 +676,16 @@
   @override
   String get debugName => "LargeIntAccessGenerator";
 
-  Expression buildError() {
-    return helper
-        .buildProblem(templateIntegerLiteralIsOutOfRange.withArguments(token),
-            offsetForToken(token), lengthForToken(token))
-        .desugared /* TODO(ahe): Remove `.desugared`? */;
+  SyntheticExpressionJudgment buildError() {
+    return helper.buildProblem(
+        templateIntegerLiteralIsOutOfRange.withArguments(token),
+        offsetForToken(token),
+        lengthForToken(token));
   }
 
   @override
   Expression doInvocation(int offset, Arguments arguments) {
-    return new SyntheticExpressionJudgment(buildError());
+    return buildError();
   }
 
   @override
@@ -736,7 +699,7 @@
   /// Pass [arguments] that must be evaluated before throwing an error.  At
   /// most one of [isGetter] and [isSetter] should be true and they're passed
   /// to [ExpressionGeneratorHelper.throwNoSuchMethodError] if it is used.
-  Expression buildError(Arguments arguments,
+  SyntheticExpressionJudgment buildError(Arguments arguments,
       {bool isGetter: false, bool isSetter: false, int offset});
 
   Name get name => unsupported("name", offsetForToken(token), uri);
@@ -748,14 +711,13 @@
 
   @override
   Initializer buildFieldInitializer(Map<String, int> initializedFields) {
-    return helper.buildInvalidInitializer(new SyntheticExpressionJudgment(
-        buildError(forest.argumentsEmpty(token), isSetter: true)));
+    return helper.buildInvalidInitializer(
+        buildError(forest.argumentsEmpty(token), isSetter: true).desugared);
   }
 
   @override
   doInvocation(int offset, Arguments arguments) {
-    return new SyntheticExpressionJudgment(
-        buildError(arguments, offset: offset));
+    return buildError(arguments, offset: offset);
   }
 
   @override
@@ -767,9 +729,8 @@
 
   @override
   Expression buildAssignment(Expression value, {bool voidContext: false}) {
-    return new SyntheticExpressionJudgment(buildError(
-        forest.arguments(<Expression>[value], token),
-        isSetter: true));
+    return buildError(forest.arguments(<Expression>[value], token),
+        isSetter: true);
   }
 
   @override
@@ -779,34 +740,29 @@
       Procedure interfaceTarget,
       bool isPreIncDec: false,
       bool isPostIncDec: false}) {
-    return new SyntheticExpressionJudgment(buildError(
-        forest.arguments(<Expression>[value], token),
-        isGetter: true));
+    return buildError(forest.arguments(<Expression>[value], token),
+        isGetter: true);
   }
 
   @override
   Expression buildPrefixIncrement(Name binaryOperator,
       {int offset: -1, bool voidContext: false, Procedure interfaceTarget}) {
-    var error = buildError(
+    return buildError(
         forest.arguments(
             <Expression>[forest.literalInt(1, null)..fileOffset = offset],
             token),
-        isGetter: true);
-    return new UnresolvedVariableUnaryJudgment(
-        error, token?.offset, token?.isSynthetic)
+        isGetter: true)
       ..fileOffset = offset;
   }
 
   @override
   Expression buildPostfixIncrement(Name binaryOperator,
       {int offset: -1, bool voidContext: false, Procedure interfaceTarget}) {
-    var error = buildError(
+    return buildError(
         forest.arguments(
             <Expression>[forest.literalInt(1, null)..fileOffset = offset],
             token),
-        isGetter: true);
-    return new UnresolvedVariableUnaryJudgment(
-        error, token?.offset, token?.isSynthetic)
+        isGetter: true)
       ..fileOffset = offset;
   }
 
@@ -814,41 +770,41 @@
   Expression buildNullAwareAssignment(
       Expression value, DartType type, int offset,
       {bool voidContext: false}) {
-    return new SyntheticExpressionJudgment(buildError(
-        forest.arguments(<Expression>[value], token),
-        isSetter: true));
+    return buildError(forest.arguments(<Expression>[value], token),
+        isSetter: true);
   }
 
   @override
-  Expression buildSimpleRead() => new SyntheticExpressionJudgment(
-      buildError(forest.argumentsEmpty(token), isGetter: true));
+  Expression buildSimpleRead() {
+    return buildError(forest.argumentsEmpty(token), isGetter: true);
+  }
 
   @override
-  Expression makeInvalidRead() => new SyntheticExpressionJudgment(
-      buildError(forest.argumentsEmpty(token), isGetter: true));
+  Expression makeInvalidRead() {
+    return buildError(forest.argumentsEmpty(token), isGetter: true);
+  }
 
   @override
   Expression makeInvalidWrite(Expression value) {
-    return new SyntheticExpressionJudgment(buildError(
-        forest.arguments(<Expression>[value], token),
-        isSetter: true));
+    return buildError(forest.arguments(<Expression>[value], token),
+        isSetter: true);
   }
 
   @override
   Expression invokeConstructor(
-      List<DartType> typeArguments,
+      List<UnresolvedType<KernelTypeBuilder>> typeArguments,
       String name,
       Arguments arguments,
       Token nameToken,
       Token nameLastToken,
       Constness constness) {
-    helper.storeTypeUse(offsetForToken(token), const InvalidType());
     if (typeArguments != null) {
       assert(forest.argumentsTypeArguments(arguments).isEmpty);
-      forest.argumentsSetTypeArguments(arguments, typeArguments);
+      forest.argumentsSetTypeArguments(
+          arguments, helper.buildDartTypeArguments(typeArguments));
     }
-    var error = buildError(arguments);
-    return new InvalidConstructorInvocationJudgment(error, null, arguments);
+    return new InvalidConstructorInvocationJudgment(
+        buildError(arguments).desugared, null, arguments);
   }
 }
 
@@ -864,26 +820,26 @@
   @override
   Expression doInvocation(int charOffset, Arguments arguments) {
     return new UnresolvedTargetInvocationJudgment(
-        buildError(arguments, offset: charOffset), arguments)
+        buildError(arguments, offset: charOffset).desugared, arguments)
       ..fileOffset = arguments.fileOffset;
   }
 
   @override
-  Expression buildError(Arguments arguments,
+  SyntheticExpressionJudgment buildError(Arguments arguments,
       {bool isGetter: false, bool isSetter: false, int offset}) {
     offset ??= offsetForToken(this.token);
-    return helper.throwNoSuchMethodError(
+    return new SyntheticExpressionJudgment(helper.throwNoSuchMethodError(
         forest.literalNull(null)..fileOffset = offset,
         plainNameForRead,
         arguments,
         offset,
         isGetter: isGetter,
-        isSetter: isSetter);
+        isSetter: isSetter))
+      ..fileOffset = offset;
   }
 
   @override
   /* Expression | Generator */ Object qualifiedLookup(Token name) {
-    helper.storeUnresolved(token);
     return new UnexpectedQualifiedUseGenerator(helper, name, this, true);
   }
 }
@@ -1134,12 +1090,12 @@
   @override
   /* Expression | Generator | Initializer */ doInvocation(
       int offset, Arguments arguments) {
-    var error = helper.wrapInLocatedProblem(
-        helper.evaluateArgumentsBefore(arguments, forest.literalNull(token)),
-        messageCantUsePrefixAsExpression.withLocation(
-            helper.uri, offsetForToken(token), lengthForToken(token)));
     return new StaticInvocationJudgment(null, forest.castArguments(arguments),
-        desugaredError: error)
+        desugaredError: helper.wrapInLocatedProblem(
+            helper.evaluateArgumentsBefore(
+                arguments, forest.literalNull(token)),
+            messageCantUsePrefixAsExpression.withLocation(
+                helper.uri, offsetForToken(token), lengthForToken(token))))
       ..fileOffset = offset;
   }
 
@@ -1218,18 +1174,18 @@
   }
 
   @override
-  DartType buildTypeWithBuiltArguments(List<DartType> arguments,
-      {bool nonInstanceAccessIsError: false, TypeInferrer typeInferrer}) {
+  KernelTypeBuilder buildTypeWithResolvedArguments(
+      List<UnresolvedType<KernelTypeBuilder>> arguments) {
     Template<Message Function(String, String)> template = isUnresolved
         ? templateUnresolvedPrefixInTypeAnnotation
         : templateNotAPrefixInTypeAnnotation;
-    helper.addProblem(
-        template.withArguments(prefixGenerator.token.lexeme, token.lexeme),
-        offsetForToken(prefixGenerator.token),
-        lengthOfSpan(prefixGenerator.token, token));
-    prefixGenerator.storeUnexpectedTypePrefix(typeInferrer);
-    helper.storeTypeUse(offsetForToken(token), const InvalidType());
-    return const InvalidType();
+    KernelNamedTypeBuilder result =
+        new KernelNamedTypeBuilder(plainNameForRead, null);
+    result.bind(result.buildInvalidType(template
+        .withArguments(prefixGenerator.token.lexeme, token.lexeme)
+        .withLocation(uri, offsetForToken(prefixGenerator.token),
+            lengthOfSpan(prefixGenerator.token, token))));
+    return result;
   }
 
   @override
diff --git a/pkg/front_end/lib/src/fasta/kernel/expression_generator_helper.dart b/pkg/front_end/lib/src/fasta/kernel/expression_generator_helper.dart
index 339c43d..4c8a138 100644
--- a/pkg/front_end/lib/src/fasta/kernel/expression_generator_helper.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/expression_generator_helper.dart
@@ -22,7 +22,8 @@
 
 import 'forest.dart' show Forest;
 
-import 'kernel_builder.dart' show KernelTypeBuilder, PrefixBuilder;
+import 'kernel_builder.dart'
+    show KernelTypeBuilder, PrefixBuilder, UnresolvedType;
 
 import 'kernel_ast_api.dart'
     show
@@ -34,11 +35,9 @@
         Initializer,
         Member,
         Name,
-        Node,
         Procedure,
         StaticGet,
-        TypeParameter,
-        TypeParameterType;
+        TypeParameter;
 
 import 'kernel_builder.dart'
     show
@@ -122,12 +121,13 @@
       Token nameLastToken,
       Arguments arguments,
       String name,
-      List<DartType> typeArguments,
+      List<UnresolvedType<KernelTypeBuilder>> typeArguments,
       int charOffset,
       Constness constness);
 
-  DartType validatedTypeVariableUse(
-      TypeParameterType type, int offset, bool nonInstanceAccessIsError);
+  UnresolvedType<KernelTypeBuilder> validateTypeUse(
+      UnresolvedType<KernelTypeBuilder> unresolved,
+      bool nonInstanceAccessIsError);
 
   void addProblemErrorIfConst(Message message, int charOffset, int length);
 
@@ -145,7 +145,9 @@
   Expression evaluateArgumentsBefore(
       Arguments arguments, Expression expression);
 
-  void storeTypeUse(int offset, Node node);
+  DartType buildDartType(UnresolvedType<KernelTypeBuilder> unresolvedType,
+      {bool nonInstanceAccessIsError});
 
-  void storeUnresolved(Token token);
+  List<DartType> buildDartTypeArguments(
+      List<UnresolvedType<KernelTypeBuilder>> unresolvedTypes);
 }
diff --git a/pkg/front_end/lib/src/fasta/kernel/fangorn.dart b/pkg/front_end/lib/src/fasta/kernel/fangorn.dart
index 8461648..6183be9 100644
--- a/pkg/front_end/lib/src/fasta/kernel/fangorn.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/fangorn.dart
@@ -117,14 +117,9 @@
         TypeDeclarationBuilder,
         UnlinkedDeclaration;
 
-import '../type_inference/type_inference_listener.dart'
-    show TypeInferenceTokensSaver;
-
 /// A shadow tree factory.
 class Fangorn extends Forest {
-  TypeInferenceTokensSaver typeInferenceTokensSaver;
-
-  Fangorn(this.typeInferenceTokensSaver);
+  const Fangorn();
 
   @override
   ArgumentsJudgment arguments(List<Expression> positional, Token token,
@@ -163,23 +158,17 @@
 
   @override
   BoolJudgment literalBool(bool value, Token token) {
-    return new BoolJudgment(
-        typeInferenceTokensSaver?.boolLiteralTokens(token), value)
-      ..fileOffset = offsetForToken(token);
+    return new BoolJudgment(value)..fileOffset = offsetForToken(token);
   }
 
   @override
   DoubleJudgment literalDouble(double value, Token token) {
-    return new DoubleJudgment(
-        typeInferenceTokensSaver?.doubleLiteralTokens(token), value)
-      ..fileOffset = offsetForToken(token);
+    return new DoubleJudgment(value)..fileOffset = offsetForToken(token);
   }
 
   @override
   IntJudgment literalInt(int value, Token token) {
-    return new IntJudgment(
-        typeInferenceTokensSaver?.intLiteralTokens(token), value)
-      ..fileOffset = offsetForToken(token);
+    return new IntJudgment(value)..fileOffset = offsetForToken(token);
   }
 
   @override
@@ -193,12 +182,8 @@
       Token rightBracket) {
     // TODO(brianwilkerson): The file offset computed below will not be correct
     // if there are type arguments but no `const` keyword.
-    return new ListLiteralJudgment(
-        typeInferenceTokensSaver?.listLiteralTokens(
-            constKeyword, leftBracket, rightBracket),
-        expressions,
-        typeArgument: typeArgument,
-        isConst: isConst)
+    return new ListLiteralJudgment(expressions,
+        typeArgument: typeArgument, isConst: isConst)
       ..fileOffset = offsetForToken(constKeyword ?? leftBracket);
   }
 
@@ -214,27 +199,19 @@
       Token rightBracket) {
     // TODO(brianwilkerson): The file offset computed below will not be correct
     // if there are type arguments but no `const` keyword.
-    return new MapLiteralJudgment(
-        typeInferenceTokensSaver?.mapLiteralTokens(
-            constKeyword, leftBracket, rightBracket),
-        entries,
-        keyType: keyType,
-        valueType: valueType,
-        isConst: isConst)
+    return new MapLiteralJudgment(entries,
+        keyType: keyType, valueType: valueType, isConst: isConst)
       ..fileOffset = offsetForToken(constKeyword ?? leftBracket);
   }
 
   @override
   NullJudgment literalNull(Token token) {
-    return new NullJudgment(typeInferenceTokensSaver?.nullLiteralTokens(token))
-      ..fileOffset = offsetForToken(token);
+    return new NullJudgment()..fileOffset = offsetForToken(token);
   }
 
   @override
   StringLiteralJudgment literalString(String value, Token token) {
-    return new StringLiteralJudgment(
-        typeInferenceTokensSaver?.stringLiteralTokens(token), value)
-      ..fileOffset = offsetForToken(token);
+    return new StringLiteralJudgment(value)..fileOffset = offsetForToken(token);
   }
 
   @override
@@ -272,9 +249,7 @@
 
   @override
   Expression asExpression(Expression expression, DartType type, Token token) {
-    return new AsJudgment(
-        expression, typeInferenceTokensSaver?.asExpressionTokens(token), type)
-      ..fileOffset = offsetForToken(token);
+    return new AsJudgment(expression, type)..fileOffset = offsetForToken(token);
   }
 
   @override
@@ -284,11 +259,8 @@
       Expression condition,
       Token comma,
       Expression message) {
-    return new AssertInitializerJudgment(
-        assertStatement(
-            assertKeyword, leftParenthesis, condition, comma, message, null),
-        typeInferenceTokensSaver?.assertInitializerTokens(
-            assertKeyword, leftParenthesis, comma, leftParenthesis.endGroup));
+    return new AssertInitializerJudgment(assertStatement(
+        assertKeyword, leftParenthesis, condition, comma, message, null));
   }
 
   @override
@@ -327,10 +299,7 @@
         endOffset = conditionLastToken.offset + conditionLastToken.length;
       }
     }
-    return new AssertStatementJudgment(
-        typeInferenceTokensSaver?.assertStatementTokens(assertKeyword,
-            leftParenthesis, comma, leftParenthesis.endGroup, semicolon),
-        condition,
+    return new AssertStatementJudgment(condition,
         conditionStartOffset: startOffset,
         conditionEndOffset: endOffset,
         message: message);
@@ -338,9 +307,7 @@
 
   @override
   Expression awaitExpression(Expression operand, Token token) {
-    return new AwaitJudgment(
-        typeInferenceTokensSaver?.awaitExpressionTokens(token), operand)
-      ..fileOffset = offsetForToken(token);
+    return new AwaitJudgment(operand)..fileOffset = offsetForToken(token);
   }
 
   @override
@@ -356,18 +323,13 @@
         copy.add(statement);
       }
     }
-    return new BlockJudgment(
-        typeInferenceTokensSaver?.blockTokens(openBrace, closeBrace),
-        copy ?? statements)
+    return new BlockJudgment(copy ?? statements)
       ..fileOffset = offsetForToken(openBrace);
   }
 
   @override
   Statement breakStatement(Token breakKeyword, Object label, Token semicolon) {
-    return new BreakJudgment(
-        typeInferenceTokensSaver?.breakStatementTokens(breakKeyword, semicolon),
-        null)
-      ..fileOffset = breakKeyword.charOffset;
+    return new BreakJudgment(null)..fileOffset = breakKeyword.charOffset;
   }
 
   @override
@@ -379,58 +341,37 @@
       VariableDeclaration stackTraceParameter,
       DartType stackTraceType,
       Statement body) {
-    return new CatchJudgment(
-        typeInferenceTokensSaver?.catchStatementTokens(
-            onKeyword, catchKeyword, null, null, null),
-        exceptionParameter,
-        body,
-        guard: exceptionType,
-        stackTrace: stackTraceParameter)
+    return new CatchJudgment(exceptionParameter, body,
+        guard: exceptionType, stackTrace: stackTraceParameter)
       ..fileOffset = offsetForToken(onKeyword ?? catchKeyword);
   }
 
   @override
   Expression conditionalExpression(Expression condition, Token question,
       Expression thenExpression, Token colon, Expression elseExpression) {
-    return new ConditionalJudgment(
-        condition,
-        typeInferenceTokensSaver?.conditionalExpressionTokens(question, colon),
-        thenExpression,
-        elseExpression)
+    return new ConditionalJudgment(condition, thenExpression, elseExpression)
       ..fileOffset = offsetForToken(question);
   }
 
   @override
   Statement continueStatement(
       Token continueKeyword, Object label, Token semicolon) {
-    return new ContinueJudgment(
-        typeInferenceTokensSaver?.continueStatementTokens(
-            continueKeyword, semicolon),
-        null)
-      ..fileOffset = continueKeyword.charOffset;
+    return new ContinueJudgment(null)..fileOffset = continueKeyword.charOffset;
   }
 
   @override
   Statement doStatement(Token doKeyword, Statement body, Token whileKeyword,
       Expression condition, Token semicolon) {
-    // TODO(brianwilkerson): Plumb through the left-and right parentheses.
-    return new DoJudgment(
-        typeInferenceTokensSaver?.doStatementTokens(
-            doKeyword, whileKeyword, null, null, semicolon),
-        body,
-        condition)
-      ..fileOffset = doKeyword.charOffset;
+    return new DoJudgment(body, condition)..fileOffset = doKeyword.charOffset;
   }
 
   Statement expressionStatement(Expression expression, Token semicolon) {
-    return new ExpressionStatementJudgment(expression,
-        typeInferenceTokensSaver?.expressionStatementTokens(semicolon));
+    return new ExpressionStatementJudgment(expression);
   }
 
   @override
   Statement emptyStatement(Token semicolon) {
-    return new EmptyStatementJudgment(
-        typeInferenceTokensSaver?.emptyStatementTokens(semicolon));
+    return new EmptyStatementJudgment();
   }
 
   @override
@@ -445,28 +386,15 @@
       List<Expression> updaters,
       Token rightParenthesis,
       Statement body) {
-    // TODO(brianwilkerson): Plumb through the right separator.
     return new ForJudgment(
-        typeInferenceTokensSaver?.forStatementTokens(forKeyword,
-            leftParenthesis, leftSeparator, null, leftParenthesis.endGroup),
-        variableList,
-        initializers,
-        condition,
-        updaters,
-        body)
+        variableList, initializers, condition, updaters, body)
       ..fileOffset = forKeyword.charOffset;
   }
 
   @override
   Statement ifStatement(Token ifKeyword, Expression condition,
       Statement thenStatement, Token elseKeyword, Statement elseStatement) {
-    // TODO(brianwilkerson) Plumb through the left and right parentheses.
-    return new IfJudgment(
-        typeInferenceTokensSaver?.ifStatementTokens(
-            ifKeyword, null, null, elseKeyword),
-        condition,
-        thenStatement,
-        elseStatement)
+    return new IfJudgment(condition, thenStatement, elseStatement)
       ..fileOffset = ifKeyword.charOffset;
   }
 
@@ -475,17 +403,9 @@
       Expression operand, isOperator, Token notOperator, DartType type) {
     int offset = offsetForToken(isOperator);
     if (notOperator != null) {
-      return new IsNotJudgment(
-          operand,
-          typeInferenceTokensSaver?.isNotExpressionTokens(
-              isOperator, notOperator),
-          type,
-          offset)
-        ..fileOffset = offset;
+      return new IsNotJudgment(operand, type, offset)..fileOffset = offset;
     }
-    return new IsJudgment(
-        operand, typeInferenceTokensSaver?.isExpressionTokens(isOperator), type)
-      ..fileOffset = offset;
+    return new IsJudgment(operand, type)..fileOffset = offset;
   }
 
   @override
@@ -495,18 +415,13 @@
   @override
   Expression logicalExpression(
       Expression leftOperand, Token operator, Expression rightOperand) {
-    return new LogicalJudgment(
-        leftOperand,
-        typeInferenceTokensSaver?.logicalExpressionTokens(operator),
-        operator.stringValue,
-        rightOperand)
+    return new LogicalJudgment(leftOperand, operator.stringValue, rightOperand)
       ..fileOffset = offsetForToken(operator);
   }
 
   @override
   Expression notExpression(Expression operand, Token token, bool isSynthetic) {
-    return new NotJudgment(
-        isSynthetic, typeInferenceTokensSaver?.notTokens(token), operand)
+    return new NotJudgment(isSynthetic, operand)
       ..fileOffset = offsetForToken(token);
   }
 
@@ -519,20 +434,13 @@
   @override
   Statement rethrowStatement(Token rethrowKeyword, Token semicolon) {
     return new ExpressionStatementJudgment(
-        new RethrowJudgment(
-            typeInferenceTokensSaver?.rethrowTokens(rethrowKeyword), null)
-          ..fileOffset = offsetForToken(rethrowKeyword),
-        typeInferenceTokensSaver?.expressionStatementTokens(semicolon));
+        new RethrowJudgment(null)..fileOffset = offsetForToken(rethrowKeyword));
   }
 
   @override
   Statement returnStatement(
       Token returnKeyword, Expression expression, Token semicolon) {
-    return new ReturnJudgment(
-        typeInferenceTokensSaver?.returnStatementTokens(
-            returnKeyword, semicolon),
-        returnKeyword?.lexeme,
-        expression)
+    return new ReturnJudgment(returnKeyword?.lexeme, expression)
       ..fileOffset = returnKeyword.charOffset;
   }
 
@@ -550,15 +458,12 @@
 
   @override
   Expression thisExpression(Token token) {
-    return new ThisJudgment(
-        typeInferenceTokensSaver?.thisExpressionTokens(token))
-      ..fileOffset = offsetForToken(token);
+    return new ThisJudgment()..fileOffset = offsetForToken(token);
   }
 
   @override
   Expression throwExpression(Token throwKeyword, Expression expression) {
-    return new ThrowJudgment(
-        typeInferenceTokensSaver?.throwTokens(throwKeyword), expression)
+    return new ThrowJudgment(expression)
       ..fileOffset = offsetForToken(throwKeyword);
   }
 
@@ -566,12 +471,7 @@
   Statement tryStatement(Token tryKeyword, Statement body,
       List<Catch> catchClauses, Token finallyKeyword, Statement finallyBlock) {
     if (finallyBlock != null) {
-      return new TryFinallyJudgment(
-          typeInferenceTokensSaver?.tryFinallyTokens(
-              tryKeyword, finallyKeyword),
-          body,
-          catchClauses,
-          finallyBlock);
+      return new TryFinallyJudgment(body, catchClauses, finallyBlock);
     }
     return new TryCatchJudgment(body, catchClauses ?? const <CatchJudgment>[]);
   }
@@ -591,10 +491,10 @@
   @override
   Statement wrapVariables(Statement statement) {
     if (statement is _VariablesDeclaration) {
-      return new BlockJudgment(null, statement.declarations)
+      return new BlockJudgment(statement.declarations)
         ..fileOffset = statement.fileOffset;
     } else if (statement is VariableDeclaration) {
-      return new BlockJudgment(null, <Statement>[statement])
+      return new BlockJudgment(<Statement>[statement])
         ..fileOffset = statement.fileOffset;
     } else {
       return statement;
@@ -604,23 +504,14 @@
   @override
   Statement whileStatement(
       Token whileKeyword, Expression condition, Statement body) {
-    // TODO(brianwilkerson) Plumb through the left and right parentheses.
-    return new WhileJudgment(
-        typeInferenceTokensSaver?.whileStatementTokens(
-            whileKeyword, null, null),
-        condition,
-        body)
+    return new WhileJudgment(condition, body)
       ..fileOffset = whileKeyword.charOffset;
   }
 
   @override
   Statement yieldStatement(
       Token yieldKeyword, Token star, Expression expression, Token semicolon) {
-    return new YieldJudgment(
-        typeInferenceTokensSaver?.yieldStatementTokens(
-            yieldKeyword, star, semicolon),
-        star != null,
-        expression)
+    return new YieldJudgment(star != null, expression)
       ..fileOffset = yieldKeyword.charOffset;
   }
 
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_ast_api.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_ast_api.dart
index 5629444..d794aa9 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_ast_api.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_ast_api.dart
@@ -95,10 +95,8 @@
         IllegalAssignmentJudgment,
         IndexAssignmentJudgment,
         InvalidConstructorInvocationJudgment,
-        InvalidPropertyGetJudgment,
         InvalidStatementJudgment,
         InvalidSuperInitializerJudgment,
-        InvalidVariableWriteJudgment,
         InvalidWriteJudgment,
         ShadowInvalidFieldInitializer,
         ShadowInvalidInitializer,
@@ -125,9 +123,7 @@
         SyntheticExpressionJudgment,
         ThrowJudgment,
         UnresolvedTargetInvocationJudgment,
-        UnresolvedVariableGetJudgment,
         UnresolvedVariableAssignmentJudgment,
-        UnresolvedVariableUnaryJudgment,
         VariableAssignmentJudgment,
         VariableDeclarationJudgment,
         VariableGetJudgment,
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_body_builder.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_body_builder.dart
index 6e15991..5c83989 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_body_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_body_builder.dart
@@ -34,12 +34,12 @@
       bool isInstanceMember,
       Uri uri,
       TypeInferrer typeInferrer)
-      : forest = new Fangorn(typeInferrer?.tokensSaver),
+      : forest = const Fangorn(),
         super(library, member, scope, formalParameterScope, hierarchy,
             coreTypes, classBuilder, isInstanceMember, uri, typeInferrer);
 
   KernelBodyBuilder.forField(ModifierBuilder member, TypeInferrer typeInferrer)
-      : forest = new Fangorn(typeInferrer?.tokensSaver),
+      : forest = const Fangorn(),
         super.forField(member, typeInferrer);
 
   @override
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_class_builder.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_class_builder.dart
index e277db1..10c696a 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_class_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_class_builder.dart
@@ -301,7 +301,7 @@
               declaration.setRedirectingFactoryBody(
                   targetBuilder.member, typeArguments);
             } else {
-              var message = templateRedirectionTargetNotFound
+              Message message = templateRedirectionTargetNotFound
                   .withArguments(redirectionTarget.fullNameForErrors);
               if (declaration.isConst) {
                 addProblem(message, declaration.charOffset, noLength);
@@ -794,7 +794,8 @@
           ]);
     } else if (library.loader.target.backendTarget.strongMode &&
         declaredFunction?.typeParameters != null) {
-      var substitutionMap = <TypeParameter, DartType>{};
+      Map<TypeParameter, DartType> substitutionMap =
+          <TypeParameter, DartType>{};
       for (int i = 0; i < declaredFunction.typeParameters.length; ++i) {
         substitutionMap[interfaceFunction.typeParameters[i]] =
             new TypeParameterType(declaredFunction.typeParameters[i]);
@@ -862,7 +863,9 @@
       // a type which is a subtype of the parameter it overrides.
     } else {
       // Report an error.
-      var declaredMemberName = '$name::${declaredMember.name.name}';
+      // TODO(ahe): The double-colon notation shouldn't be used in error
+      // messages.
+      String declaredMemberName = '$name::${declaredMember.name.name}';
       Message message;
       int fileOffset;
       if (declaredParameter == null) {
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_expression_generator.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_expression_generator.dart
index 9ecc44b..403b63e 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_expression_generator.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_expression_generator.dart
@@ -3,7 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:kernel/ast.dart'
-    show Arguments, DynamicType, Expression, InvalidExpression, Node;
+    show Arguments, Expression, InvalidExpression, Node;
 
 import '../../scanner/token.dart' show Token;
 
@@ -31,8 +31,6 @@
 
 import '../problems.dart' show unhandled, unsupported;
 
-import '../type_inference/type_inferrer.dart' show TypeInferrer;
-
 import 'body_builder.dart' show noLocation;
 
 import 'constness.dart' show Constness;
@@ -69,7 +67,12 @@
 import 'forest.dart' show Forest;
 
 import 'kernel_builder.dart'
-    show LoadLibraryBuilder, PrefixBuilder, UnlinkedDeclaration;
+    show
+        KernelTypeBuilder,
+        LoadLibraryBuilder,
+        PrefixBuilder,
+        UnlinkedDeclaration,
+        UnresolvedType;
 
 import 'kernel_api.dart' show NameSystem, printNodeOn, printQualifiedNameOn;
 
@@ -82,9 +85,6 @@
         IllegalAssignmentJudgment,
         IndexAssignmentJudgment,
         Initializer,
-        InvalidPropertyGetJudgment,
-        InvalidType,
-        InvalidVariableWriteJudgment,
         InvalidWriteJudgment,
         Let,
         LoadLibraryTearOffJudgment,
@@ -107,7 +107,6 @@
         TreeNode,
         TypeParameter,
         UnresolvedVariableAssignmentJudgment,
-        UnresolvedVariableGetJudgment,
         VariableAssignmentJudgment,
         VariableDeclaration,
         VariableDeclarationJudgment,
@@ -247,7 +246,7 @@
 
   @override
   Expression makeInvalidWrite(Expression value) {
-    return buildInvalidWriteJudgment(helper.throwNoSuchMethodError(
+    return new SyntheticExpressionJudgment(helper.throwNoSuchMethodError(
         forest.literalNull(token),
         plainNameForRead,
         forest.arguments(<Expression>[value], noLocation),
@@ -255,10 +254,6 @@
         isSetter: true));
   }
 
-  Expression buildInvalidWriteJudgment(Expression desugared) {
-    return new SyntheticExpressionJudgment(desugared);
-  }
-
   Expression _makeSimpleRead() => _makeRead(null);
 
   Expression _makeSimpleWrite(Expression value, bool voidContext,
@@ -1131,17 +1126,6 @@
   }
 
   @override
-  DartType buildTypeWithBuiltArguments(List<DartType> arguments,
-      {bool nonInstanceAccessIsError: false, TypeInferrer typeInferrer}) {
-    var offset = offsetForToken(token);
-    typeInferrer.storeTypeReference(
-        offset, token.isSynthetic, readTarget, null, const DynamicType());
-    return super.buildTypeWithBuiltArguments(arguments,
-        nonInstanceAccessIsError: nonInstanceAccessIsError,
-        typeInferrer: typeInferrer);
-  }
-
-  @override
   Expression doInvocation(int offset, Arguments arguments) {
     Expression error;
     if (helper.constantContext != ConstantContext.none &&
@@ -1151,7 +1135,7 @@
               templateNotConstantExpression.withArguments('Method invocation'),
               offset,
               readTarget?.name?.name?.length ?? 0)
-          .desugared /* TODO(ahe): Remove `.desugared`? */;
+          .desugared;
     }
     if (readTarget == null || isFieldOrGetter(readTarget)) {
       return helper.buildMethodInvocation(buildSimpleRead(), callName,
@@ -1168,12 +1152,6 @@
   }
 
   @override
-  void storeUnexpectedTypePrefix(TypeInferrer typeInferrer) {
-    typeInferrer.storeTypeReference(offsetForToken(token), token.isSynthetic,
-        readTarget, null, const DynamicType());
-  }
-
-  @override
   ComplexAssignmentJudgment startComplexAssignment(Expression rhs) =>
       new StaticAssignmentJudgment(rhs);
 
@@ -1284,7 +1262,10 @@
               ..fileOffset = offset);
       } else {
         super.expression = forest.literalType(
-            buildTypeWithBuiltArguments(null, nonInstanceAccessIsError: true),
+            helper.buildDartType(
+                new UnresolvedType<KernelTypeBuilder>(
+                    buildTypeWithResolvedArguments(null), offset, uri),
+                nonInstanceAccessIsError: true),
             token);
       }
     }
@@ -1305,8 +1286,6 @@
   @override
   buildPropertyAccess(
       IncompleteSendGenerator send, int operatorOffset, bool isNullAware) {
-    helper.storeTypeUse(offsetForToken(token), declaration.target);
-
     // `SomeType?.toString` is the same as `SomeType.toString`, not
     // `(SomeType).toString`.
     isNullAware = false;
@@ -1393,18 +1372,6 @@
       super._finish(makeLet(value, body), complexAssignment);
 
   @override
-  Expression buildInvalidWriteJudgment(Expression desugared) {
-    var expression = this.expression;
-    if (expression is VariableGet) {
-      return new InvalidVariableWriteJudgment(desugared, expression.variable)
-        ..fileOffset = token.charOffset;
-    } else {
-      // TODO(paulberry): handle other cases
-      return super.buildInvalidWriteJudgment(desugared);
-    }
-  }
-
-  @override
   Expression doInvocation(int offset, Arguments arguments) {
     return helper.buildMethodInvocation(buildSimpleRead(), callName, arguments,
         adjustForImplicitCall(plainNameForRead, offset),
@@ -1429,23 +1396,23 @@
       : super(helper, token);
 
   @override
-  Expression _makeSimpleRead() => new SyntheticExpressionJudgment(buildError());
+  Expression _makeSimpleRead() => buildError();
 
   @override
   Expression _makeSimpleWrite(Expression value, bool voidContext,
       ComplexAssignmentJudgment complexAssignment) {
-    return new SyntheticExpressionJudgment(buildError());
+    return buildError();
   }
 
   @override
   Expression _makeRead(ComplexAssignmentJudgment complexAssignment) {
-    return new SyntheticExpressionJudgment(buildError());
+    return buildError();
   }
 
   @override
   Expression _makeWrite(Expression value, bool voidContext,
       ComplexAssignmentJudgment complexAssignment) {
-    return new SyntheticExpressionJudgment(buildError());
+    return buildError();
   }
 }
 
@@ -1475,21 +1442,10 @@
 
   @override
   Expression buildSimpleRead() {
-    Expression error = buildError(forest.argumentsEmpty(token), isGetter: true);
-    return new UnresolvedVariableGetJudgment(error, token.isSynthetic)
+    return buildError(forest.argumentsEmpty(token), isGetter: true)
       ..fileOffset = token.charOffset;
   }
 
-  DartType buildTypeWithBuiltArguments(List<DartType> arguments,
-      {bool nonInstanceAccessIsError: false, TypeInferrer typeInferrer}) {
-    var type = super.buildTypeWithBuiltArguments(arguments,
-        nonInstanceAccessIsError: nonInstanceAccessIsError,
-        typeInferrer: typeInferrer);
-    typeInferrer.storeTypeReference(
-        token.offset, token.isSynthetic, null, null, type);
-    return type;
-  }
-
   @override
   void printOn(StringSink sink) {
     sink.write(", name: ");
@@ -1499,7 +1455,8 @@
   UnresolvedVariableAssignmentJudgment _buildUnresolvedVariableAssignment(
       bool isCompound, Expression value) {
     return new UnresolvedVariableAssignmentJudgment(
-      buildError(forest.arguments(<Expression>[value], token), isSetter: true),
+      buildError(forest.arguments(<Expression>[value], token), isSetter: true)
+          .desugared,
       isCompound,
       value,
     )..fileOffset = token.charOffset;
@@ -1602,18 +1559,6 @@
   KernelUnexpectedQualifiedUseGenerator(ExpressionGeneratorHelper helper,
       Token token, this.prefixGenerator, this.isUnresolved)
       : super(helper, token);
-
-  Expression invokeConstructor(
-      List<DartType> typeArguments,
-      String name,
-      Arguments arguments,
-      Token nameToken,
-      Token nameStringToken,
-      Constness constness) {
-    helper.storeTypeUse(offsetForToken(token), const InvalidType());
-    return super.invokeConstructor(
-        typeArguments, name, arguments, nameToken, nameStringToken, constness);
-  }
 }
 
 Expression makeLet(VariableDeclaration variable, Expression body) {
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_expression_generator_impl.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_expression_generator_impl.dart
index e39f5d42..24358ca 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_expression_generator_impl.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_expression_generator_impl.dart
@@ -213,17 +213,19 @@
       ExpressionGeneratorHelper helper, Token token, this.member, this.message)
       : super(helper, token, null);
 
+  String get plainNameForRead => token.lexeme;
+
   String get debugName => "IncompleteErrorGenerator";
 
   @override
-  Expression buildError(Arguments arguments,
+  SyntheticExpressionJudgment buildError(Arguments arguments,
       {bool isGetter: false, bool isSetter: false, int offset}) {
     int length = noLength;
     if (offset == null) {
       offset = offsetForToken(token);
       length = lengthForToken(token);
     }
-    return helper.buildProblem(message, offset, length).desugared;
+    return helper.buildProblem(message, offset, length);
   }
 
   @override
@@ -231,8 +233,7 @@
 
   @override
   Expression buildSimpleRead() {
-    var error = buildError(forest.argumentsEmpty(token), isGetter: true);
-    return new InvalidPropertyGetJudgment(error, member)
+    return buildError(forest.argumentsEmpty(token), isGetter: true)
       ..fileOffset = offsetForToken(token);
   }
 
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_field_builder.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_field_builder.dart
index e2b769e..ee9bac4 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_field_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_field_builder.dart
@@ -16,9 +16,6 @@
 
 import '../problems.dart' show internalProblem;
 
-import '../type_inference/type_inference_listener.dart'
-    show KernelTypeInferenceListener;
-
 import 'kernel_body_builder.dart' show KernelBodyBuilder;
 
 import 'kernel_builder.dart'
@@ -90,10 +87,8 @@
   @override
   void prepareTopLevelInference() {
     if (!isEligibleForInference) return;
-    var listener = new KernelTypeInferenceListener();
     var typeInferrer = library.loader.typeInferenceEngine
-        .createTopLevelTypeInferrer(
-            listener, field.enclosingClass?.thisType, field);
+        .createTopLevelTypeInferrer(field.enclosingClass?.thisType, field);
     if (hasInitializer) {
       initializer = new KernelBodyBuilder.forField(this, typeInferrer)
           .parseFieldInitializer(initializerTokenForInference);
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_formal_parameter_builder.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_formal_parameter_builder.dart
index b41180a..b76dbae 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_formal_parameter_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_formal_parameter_builder.dart
@@ -34,9 +34,10 @@
 
   VariableDeclaration get target => declaration;
 
-  VariableDeclaration build(KernelLibraryBuilder library) {
+  VariableDeclaration build(
+      KernelLibraryBuilder library, int functionNestingLevel) {
     if (declaration == null) {
-      declaration = new VariableDeclarationJudgment(name, 0,
+      declaration = new VariableDeclarationJudgment(name, functionNestingLevel,
           type: type?.build(library),
           isFinal: isFinal,
           isConst: isConst,
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_function_type_alias_builder.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_function_type_alias_builder.dart
index b36a54e..1242eff 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_function_type_alias_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_function_type_alias_builder.dart
@@ -69,7 +69,7 @@
 
       if (type.formals != null) {
         for (KernelFormalParameterBuilder formal in type.formals) {
-          VariableDeclaration parameter = formal.build(libraryBuilder);
+          VariableDeclaration parameter = formal.build(libraryBuilder, 0);
           parameter.type = freshTypeParameters.substitute(parameter.type);
           if (formal.isNamed) {
             target.namedParameters.add(parameter);
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_library_builder.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_library_builder.dart
index e666eb4..37562af 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_library_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_library_builder.dart
@@ -12,6 +12,7 @@
         Class,
         ConstructorInvocation,
         DartType,
+        DynamicType,
         Expression,
         Field,
         Library,
@@ -162,14 +163,12 @@
 
   Uri get uri => library.importUri;
 
-  void becomeCoreLibrary(dynamicType) {
-    if (scope.local["dynamic"] == null) {
-      addBuilder(
-          "dynamic",
-          new DynamicTypeBuilder<KernelTypeBuilder, DartType>(
-              dynamicType, this, -1),
-          -1);
-    }
+  void addSyntheticDeclarationOfDynamic() {
+    addBuilder(
+        "dynamic",
+        new DynamicTypeBuilder<KernelTypeBuilder, DartType>(
+            const DynamicType(), this, -1),
+        -1);
   }
 
   KernelTypeBuilder addNamedType(
@@ -335,7 +334,7 @@
       /// 1. `S with M1`.
       /// 2. `(S with M1) with M2`.
       /// 3. `((S with M1) with M2) with M3`.
-      KernelTypeBuilder supertype = type.supertype;
+      KernelTypeBuilder supertype = type.supertype ?? loader.target.objectType;
 
       /// The variable part of the mixin application's synthetic name. It
       /// starts out as the name of the superclass, but is only used after it
@@ -1155,7 +1154,8 @@
       if (declaration is KernelClassBuilder) {
         {
           List<Object> issues = strongMode
-              ? getNonSimplicityIssuesForDeclaration(declaration)
+              ? getNonSimplicityIssuesForDeclaration(declaration,
+                  performErrorRecovery: true)
               : const <Object>[];
           reportIssues(issues);
           // In case of issues, use non-strong mode for error recovery.
@@ -1175,7 +1175,8 @@
         });
       } else if (declaration is KernelFunctionTypeAliasBuilder) {
         List<Object> issues = strongMode
-            ? getNonSimplicityIssuesForDeclaration(declaration)
+            ? getNonSimplicityIssuesForDeclaration(declaration,
+                performErrorRecovery: true)
             : const <Object>[];
         reportIssues(issues);
         // In case of issues, use non-strong mode for error recovery.
@@ -1196,8 +1197,8 @@
   }
 
   @override
-  void includePart(covariant KernelLibraryBuilder part) {
-    super.includePart(part);
+  void includePart(covariant KernelLibraryBuilder part, Set<Uri> usedParts) {
+    super.includePart(part, usedParts);
     nativeMethods.addAll(part.nativeMethods);
     boundlessTypeVariables.addAll(part.boundlessTypeVariables);
   }
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_procedure_builder.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_procedure_builder.dart
index c65c7b8..3b12ad17 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_procedure_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_procedure_builder.dart
@@ -152,7 +152,7 @@
     }
     if (formals != null) {
       for (KernelFormalParameterBuilder formal in formals) {
-        VariableDeclaration parameter = formal.build(library);
+        VariableDeclaration parameter = formal.build(library, 0);
         if (formal.isNamed) {
           result.namedParameters.add(parameter);
         } else {
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_shadow_ast.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_shadow_ast.dart
index ce99bf3..14df1f6 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_shadow_ast.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_shadow_ast.dart
@@ -70,49 +70,6 @@
         TypeInferrerDisabled,
         TypeInferrerImpl;
 
-import '../type_inference/type_inference_listener.dart'
-    show
-        AsExpressionTokens,
-        AssertInitializerTokens,
-        AssertStatementTokens,
-        AwaitExpressionTokens,
-        BlockTokens,
-        BoolLiteralTokens,
-        BreakStatementTokens,
-        ContinueStatementTokens,
-        ConditionalExpressionTokens,
-        ContinueSwitchStatementTokens,
-        DoStatementTokens,
-        DoubleLiteralTokens,
-        EmptyStatementTokens,
-        ExpressionStatementTokens,
-        ForInStatementTokens,
-        ForStatementTokens,
-        IfNullTokens,
-        IfStatementTokens,
-        IntLiteralTokens,
-        IsExpressionTokens,
-        IsNotExpressionTokens,
-        ListLiteralTokens,
-        LogicalExpressionTokens,
-        MapLiteralTokens,
-        NotTokens,
-        NullLiteralTokens,
-        RethrowTokens,
-        ReturnStatementTokens,
-        StringLiteralTokens,
-        SuperInitializerTokens,
-        SwitchCaseTokens,
-        SwitchStatementTokens,
-        ThisExpressionTokens,
-        ThrowTokens,
-        CatchStatementTokens,
-        TryFinallyTokens,
-        WhileStatementTokens,
-        YieldStatementTokens,
-        NamedExpressionTokens,
-        TypeInferenceListener;
-
 import '../type_inference/type_promotion.dart'
     show TypePromoter, TypePromoterImpl, TypePromotionFact, TypePromotionScope;
 
@@ -204,12 +161,9 @@
 
 /// Shadow object for [AsExpression].
 class AsJudgment extends AsExpression implements ExpressionJudgment {
-  final AsExpressionTokens tokens;
-
   DartType inferredType;
 
-  AsJudgment(Expression operand, this.tokens, DartType type)
-      : super(operand, type);
+  AsJudgment(Expression operand, DartType type) : super(operand, type);
 
   ExpressionJudgment get judgment => operand;
 
@@ -219,8 +173,6 @@
     inferrer.inferExpression(judgment, const UnknownType(), false,
         isVoidAllowed: true);
     inferredType = type;
-    inferrer.listener
-        .asExpression(this, fileOffset, null, tokens, null, inferredType);
     return null;
   }
 }
@@ -228,10 +180,7 @@
 /// Concrete shadow object representing an assert initializer in kernel form.
 class AssertInitializerJudgment extends AssertInitializer
     implements InitializerJudgment {
-  final AssertInitializerTokens tokens;
-
-  AssertInitializerJudgment(AssertStatement statement, this.tokens)
-      : super(statement);
+  AssertInitializerJudgment(AssertStatement statement) : super(statement);
 
   AssertStatementJudgment get judgment => statement;
 
@@ -239,16 +188,13 @@
   void infer<Expression, Statement, Initializer, Type>(
       ShadowTypeInferrer inferrer) {
     inferrer.inferStatement(judgment);
-    inferrer.listener.assertInitializer(this, fileOffset, tokens, null, null);
   }
 }
 
 /// Concrete shadow object representing an assertion statement in kernel form.
 class AssertStatementJudgment extends AssertStatement
     implements StatementJudgment {
-  final AssertStatementTokens tokens;
-
-  AssertStatementJudgment(this.tokens, Expression condition,
+  AssertStatementJudgment(Expression condition,
       {Expression message, int conditionStartOffset, int conditionEndOffset})
       : super(condition,
             message: message,
@@ -272,16 +218,14 @@
     if (messageJudgment != null) {
       inferrer.inferExpression(messageJudgment, const UnknownType(), false);
     }
-    inferrer.listener.assertStatement(this, fileOffset, tokens, null, null);
   }
 }
 
 /// Shadow object for [AwaitExpression].
 class AwaitJudgment extends AwaitExpression implements ExpressionJudgment {
-  AwaitExpressionTokens tokens;
   DartType inferredType;
 
-  AwaitJudgment(this.tokens, Expression operand) : super(operand);
+  AwaitJudgment(Expression operand) : super(operand);
 
   ExpressionJudgment get judgment => operand;
 
@@ -295,17 +239,13 @@
     inferrer.inferExpression(judgment, typeContext, true, isVoidAllowed: true);
     inferredType =
         inferrer.typeSchemaEnvironment.unfutureType(judgment.inferredType);
-    inferrer.listener
-        .awaitExpression(this, fileOffset, tokens, null, inferredType);
     return null;
   }
 }
 
 /// Concrete shadow object representing a statement block in kernel form.
 class BlockJudgment extends Block implements StatementJudgment {
-  BlockTokens tokens;
-
-  BlockJudgment(this.tokens, List<Statement> statements) : super(statements);
+  BlockJudgment(List<Statement> statements) : super(statements);
 
   List<Statement> get judgments => statements;
 
@@ -315,33 +255,26 @@
     for (var judgment in judgments) {
       inferrer.inferStatement(judgment);
     }
-    inferrer.listener.block(this, fileOffset, tokens, null);
   }
 }
 
 /// Concrete shadow object representing a boolean literal in kernel form.
 class BoolJudgment extends BoolLiteral implements ExpressionJudgment {
-  final BoolLiteralTokens tokens;
-
   DartType inferredType;
 
-  BoolJudgment(this.tokens, bool value) : super(value);
+  BoolJudgment(bool value) : super(value);
 
   @override
   Expression infer<Expression, Statement, Initializer, Type>(
       ShadowTypeInferrer inferrer, DartType typeContext) {
     inferredType = inferrer.coreTypes.boolClass.rawType;
-    inferrer.listener
-        .boolLiteral(this, fileOffset, tokens, value, inferredType);
     return null;
   }
 }
 
 /// Concrete shadow object representing a break statement in kernel form.
 class BreakJudgment extends BreakStatement implements StatementJudgment {
-  BreakStatementTokens tokens;
-
-  BreakJudgment(this.tokens, LabeledStatement target) : super(target);
+  BreakJudgment(LabeledStatement target) : super(target);
 
   LabeledStatementJudgment get targetJudgment => target;
 
@@ -349,16 +282,12 @@
   void infer<Expression, Statement, Initializer, Type>(
       ShadowTypeInferrer inferrer) {
     // No inference needs to be done.
-    inferrer.listener.breakStatement(
-        this, fileOffset, tokens, null, targetJudgment?.createBinder(inferrer));
   }
 }
 
 /// Concrete shadow object representing a continue statement in kernel form.
 class ContinueJudgment extends BreakStatement implements StatementJudgment {
-  ContinueStatementTokens tokens;
-
-  ContinueJudgment(this.tokens, LabeledStatement target) : super(target);
+  ContinueJudgment(LabeledStatement target) : super(target);
 
   LabeledStatementJudgment get targetJudgment => target;
 
@@ -366,8 +295,6 @@
   void infer<Expression, Statement, Initializer, Type>(
       ShadowTypeInferrer inferrer) {
     // No inference needs to be done.
-    inferrer.listener.continueStatement(
-        this, fileOffset, tokens, null, targetJudgment?.createBinder(inferrer));
   }
 }
 
@@ -448,7 +375,6 @@
       inferrer.inferExpression(judgment, const UnknownType(), false,
           isVoidAllowed: true);
     }
-    inferrer.listener.cascadeExpression(this, fileOffset, inferredType);
     return null;
   }
 }
@@ -716,7 +642,6 @@
 /// Shadow object for [ConditionalExpression].
 class ConditionalJudgment extends ConditionalExpression
     implements ExpressionJudgment {
-  ConditionalExpressionTokens tokens;
   DartType inferredType;
 
   ExpressionJudgment get conditionJudgment => condition;
@@ -726,7 +651,7 @@
   ExpressionJudgment get otherwiseJudgment => otherwise;
 
   ConditionalJudgment(
-      Expression condition, this.tokens, Expression then, Expression otherwise)
+      Expression condition, Expression then, Expression otherwise)
       : super(condition, then, otherwise, null);
 
   @override
@@ -752,8 +677,6 @@
     if (inferrer.strongMode) {
       staticType = inferredType;
     }
-    inferrer.listener.conditionalExpression(
-        this, fileOffset, null, tokens, null, null, inferredType);
     return null;
   }
 }
@@ -820,9 +743,6 @@
           fileOffset,
           noLength);
     }
-    inferrer.listener.constructorInvocation(
-        this, argumentJudgments.fileOffset, target, inferredType);
-
     return null;
   }
 }
@@ -831,9 +751,7 @@
 /// statement, in kernel form.
 class ContinueSwitchJudgment extends ContinueSwitchStatement
     implements StatementJudgment {
-  ContinueSwitchStatementTokens tokens;
-
-  ContinueSwitchJudgment(this.tokens, SwitchCase target) : super(target);
+  ContinueSwitchJudgment(SwitchCase target) : super(target);
 
   SwitchCaseJudgment get targetJudgment => target;
 
@@ -841,8 +759,6 @@
   void infer<Expression, Statement, Initializer, Type>(
       ShadowTypeInferrer inferrer) {
     // No inference needs to be done.
-    inferrer.listener.continueSwitchStatement(
-        this, fileOffset, tokens, null, targetJudgment?.createBinder(inferrer));
   }
 }
 
@@ -863,17 +779,13 @@
     var judgment = this.judgment;
     inferrer.inferExpression(judgment, typeContext, true, isVoidAllowed: true);
     inferredType = judgment.inferredType;
-    inferrer.listener.deferredCheck(this, fileOffset, inferredType);
     return null;
   }
 }
 
 /// Concrete shadow object representing a do loop in kernel form.
 class DoJudgment extends DoStatement implements StatementJudgment {
-  DoStatementTokens tokens;
-
-  DoJudgment(this.tokens, Statement body, Expression condition)
-      : super(body, condition);
+  DoJudgment(Statement body, Expression condition) : super(body, condition);
 
   StatementJudgment get bodyJudgment => body;
 
@@ -888,23 +800,19 @@
     inferrer.inferExpression(conditionJudgment, boolType, !inferrer.isTopLevel);
     inferrer.ensureAssignable(boolType, conditionJudgment.inferredType,
         condition, condition.fileOffset);
-    inferrer.listener.doStatement(this, fileOffset, tokens, null, null);
   }
 }
 
 /// Concrete shadow object representing a double literal in kernel form.
 class DoubleJudgment extends DoubleLiteral implements ExpressionJudgment {
-  DoubleLiteralTokens tokens;
   DartType inferredType;
 
-  DoubleJudgment(this.tokens, double value) : super(value);
+  DoubleJudgment(double value) : super(value);
 
   @override
   Expression infer<Expression, Statement, Initializer, Type>(
       ShadowTypeInferrer inferrer, DartType typeContext) {
     inferredType = inferrer.coreTypes.doubleClass.rawType;
-    inferrer.listener
-        .doubleLiteral(this, fileOffset, tokens, value, inferredType);
     return null;
   }
 }
@@ -923,25 +831,19 @@
 /// Concrete shadow object representing an empty statement in kernel form.
 class EmptyStatementJudgment extends EmptyStatement
     implements StatementJudgment {
-  EmptyStatementTokens tokens;
-
-  EmptyStatementJudgment(this.tokens);
+  EmptyStatementJudgment();
 
   @override
   void infer<Expression, Statement, Initializer, Type>(
       ShadowTypeInferrer inferrer) {
     // No inference needs to be done.
-    inferrer.listener.emptyStatement(tokens);
   }
 }
 
 /// Concrete shadow object representing an expression statement in kernel form.
 class ExpressionStatementJudgment extends ExpressionStatement
     implements StatementJudgment {
-  ExpressionStatementTokens tokens;
-
-  ExpressionStatementJudgment(Expression expression, this.tokens)
-      : super(expression);
+  ExpressionStatementJudgment(Expression expression) : super(expression);
 
   Expression get judgment => expression;
 
@@ -950,7 +852,6 @@
       ShadowTypeInferrer inferrer) {
     inferrer.inferExpression(judgment, const UnknownType(), false,
         isVoidAllowed: true);
-    inferrer.listener.expressionStatement(this, fileOffset, null, tokens);
   }
 }
 
@@ -977,11 +878,7 @@
         computeConstructorReturnType(target),
         argumentJudgments,
         isConst: isConst);
-    var inferredType = inferenceResult.type;
-    this.inferredType = inferredType;
-    inferrer.listener.constructorInvocation(
-        this, argumentJudgments.fileOffset, target, inferredType);
-
+    inferredType = inferenceResult.type;
     return null;
   }
 }
@@ -1025,20 +922,16 @@
       ShadowTypeInferrer inferrer) {
     var initializerType = inferrer.inferExpression(value, field.type, true);
     inferrer.ensureAssignable(field.type, initializerType, value, fileOffset);
-    inferrer.listener.fieldInitializer(
-        this, fileOffset, null, null, null, null, null, field);
   }
 }
 
 /// Concrete shadow object representing a for-in loop in kernel form.
 class ForInJudgment extends ForInStatement implements StatementJudgment {
-  final ForInStatementTokens tokens;
-
   final bool _declaresVariable;
 
   final SyntheticExpressionJudgment _syntheticAssignment;
 
-  ForInJudgment(this.tokens, VariableDeclaration variable, Expression iterable,
+  ForInJudgment(VariableDeclaration variable, Expression iterable,
       Statement body, this._declaresVariable, this._syntheticAssignment,
       {bool isAsync: false})
       : super(variable, iterable, body, isAsync: isAsync);
@@ -1060,7 +953,6 @@
     bool typeChecksNeeded = !inferrer.isTopLevel;
     VariableDeclarationJudgment variable;
     var syntheticAssignment = _syntheticAssignment;
-    kernel.Expression syntheticWrite;
     DartType syntheticWriteType;
     if (_declaresVariable) {
       variable = this.variableJudgment;
@@ -1071,7 +963,6 @@
         context = variable.type;
       }
     } else if (syntheticAssignment is ComplexAssignmentJudgment) {
-      syntheticWrite = syntheticAssignment.write;
       syntheticWriteType =
           context = syntheticAssignment._getWriteType(inferrer);
     } else {
@@ -1146,83 +1037,15 @@
       }
       syntheticAssignment._replaceWithDesugared();
     }
-    if (syntheticWrite is VariableSet) {
-      inferrer.listener.forInStatement(
-          this,
-          fileOffset,
-          tokens,
-          null,
-          iterable,
-          body,
-          variable?.createBinder(inferrer),
-          variable?.type,
-          syntheticWrite.fileOffset,
-          syntheticWrite.variable.type,
-          (syntheticWrite.variable as VariableDeclarationJudgment)
-              .createBinder(inferrer),
-          null);
-    } else if (syntheticWrite is PropertySet) {
-      inferrer.listener.forInStatement(
-          this,
-          fileOffset,
-          tokens,
-          null,
-          iterable,
-          body,
-          variable?.createBinder(inferrer),
-          variable?.type,
-          syntheticWrite.fileOffset,
-          syntheticWrite.interfaceTarget?.setterType,
-          null,
-          syntheticWrite.interfaceTarget);
-    } else if (syntheticWrite is StaticSet) {
-      inferrer.listener.forInStatement(
-          this,
-          fileOffset,
-          tokens,
-          null,
-          iterable,
-          body,
-          variable?.createBinder(inferrer),
-          variable?.type,
-          syntheticWrite.fileOffset,
-          syntheticWrite.target.setterType,
-          null,
-          syntheticWrite.target);
-    } else if (syntheticWrite == null ||
-        syntheticWrite is SyntheticExpressionJudgment) {
-      inferrer.listener.forInStatement(
-          this,
-          fileOffset,
-          tokens,
-          null,
-          null,
-          null,
-          variable?.createBinder(inferrer),
-          variable?.type,
-          null,
-          null,
-          null,
-          null);
-    } else {
-      throw new UnimplementedError(
-          '(${syntheticWrite.runtimeType}) $syntheticWrite');
-    }
   }
 }
 
 /// Concrete shadow object representing a classic for loop in kernel form.
 class ForJudgment extends ForStatement implements StatementJudgment {
-  ForStatementTokens tokens;
   final List<ExpressionJudgment> initializers;
 
-  ForJudgment(
-      this.tokens,
-      List<VariableDeclaration> variables,
-      this.initializers,
-      ExpressionJudgment condition,
-      List<Expression> updates,
-      Statement body)
+  ForJudgment(List<VariableDeclaration> variables, this.initializers,
+      ExpressionJudgment condition, List<Expression> updates, Statement body)
       : super(variables ?? [], condition, updates, body);
 
   List<VariableDeclarationJudgment> get variableJudgments => variables.cast();
@@ -1262,8 +1085,6 @@
           isVoidAllowed: true);
     }
     inferrer.inferStatement(bodyJudgment);
-    inferrer.listener.forStatement(
-        this, fileOffset, tokens, null, null, condition, updates, body);
   }
 }
 
@@ -1319,9 +1140,7 @@
         : function.returnType;
     var inferenceResult =
         functionJudgment.infer(inferrer, null, returnContext, fileOffset);
-    var inferredType = variable.type = inferenceResult.type;
-    inferrer.listener.functionDeclaration(
-        variableJudgment.createBinder(inferrer), inferredType);
+    variable.type = inferenceResult.type;
   }
 
   static void setHasImplicitReturnType(
@@ -1346,7 +1165,6 @@
     var inferenceResult =
         judgment.infer(inferrer, typeContext, null, fileOffset);
     inferredType = inferenceResult.type;
-    inferrer.listener.functionExpression(this, fileOffset, inferredType);
     return null;
   }
 }
@@ -1375,7 +1193,6 @@
         inferrer.thisType,
         argumentsJudgment,
         skipTypeArgumentInference: true);
-    inferrer.listener.superInitializer(this, fileOffset, null, null);
   }
 }
 
@@ -1386,11 +1203,9 @@
 ///
 ///     let v = a in v == null ? b : v
 class IfNullJudgment extends Let implements ExpressionJudgment {
-  final IfNullTokens tokens;
-
   DartType inferredType;
 
-  IfNullJudgment(VariableDeclaration variable, this.tokens, Expression body)
+  IfNullJudgment(VariableDeclaration variable, Expression body)
       : super(variable, body);
 
   @override
@@ -1434,18 +1249,13 @@
     if (inferrer.strongMode) {
       body.staticType = inferredType;
     }
-    inferrer.listener
-        .ifNull(this, fileOffset, null, tokens, null, inferredType);
     return null;
   }
 }
 
 /// Concrete shadow object representing an if statement in kernel form.
 class IfJudgment extends IfStatement implements StatementJudgment {
-  IfStatementTokens tokens;
-
-  IfJudgment(
-      this.tokens, Expression condition, Statement then, Statement otherwise)
+  IfJudgment(Expression condition, Statement then, Statement otherwise)
       : super(condition, then, otherwise);
 
   ExpressionJudgment get conditionJudgment => condition;
@@ -1467,7 +1277,6 @@
     if (otherwiseJudgment != null) {
       inferrer.inferStatement(otherwiseJudgment);
     }
-    inferrer.listener.ifStatement(this, fileOffset, tokens, null, null, null);
   }
 }
 
@@ -1494,9 +1303,6 @@
     if (write != null) {
       inferrer.inferExpression(write, const UnknownType(), false);
     }
-    if (assignmentOffset != -1) {
-      inferrer.listener.invalidAssignment(this, assignmentOffset);
-    }
     inferrer.inferExpression(rhs, const UnknownType(), false);
     _replaceWithDesugared();
     inferredType = const DynamicType();
@@ -1590,9 +1396,7 @@
           read.fileOffset);
       _storeLetType(inferrer, replacedRead, readType);
     }
-    var inferredResult = _inferRhs(inferrer, readType, writeContext);
-    inferrer.listener.indexAssign(this, write.fileOffset, writeMember,
-        inferredResult.combiner, inferredType);
+    _inferRhs(inferrer, readType, writeContext);
     _replaceWithDesugared();
     return null;
   }
@@ -1609,17 +1413,14 @@
 
 /// Concrete shadow object representing an integer literal in kernel form.
 class IntJudgment extends IntLiteral implements ExpressionJudgment {
-  IntLiteralTokens tokens;
-
   DartType inferredType;
 
-  IntJudgment(this.tokens, int value) : super(value);
+  IntJudgment(int value) : super(value);
 
   @override
   Expression infer<Expression, Statement, Initializer, Type>(
       ShadowTypeInferrer inferrer, DartType typeContext) {
     inferredType = inferrer.coreTypes.intClass.rawType;
-    inferrer.listener.intLiteral(this, fileOffset, tokens, value, inferredType);
     return null;
   }
 }
@@ -1633,7 +1434,6 @@
   void infer<Expression, Statement, Initializer, Type>(
       ShadowTypeInferrer inferrer) {
     inferrer.inferExpression(variable.initializer, const UnknownType(), false);
-    inferrer.listener.invalidInitializer(this, fileOffset);
   }
 }
 
@@ -1655,36 +1455,28 @@
   void infer<Expression, Statement, Initializer, Type>(
       ShadowTypeInferrer inferrer) {
     inferrer.inferExpression(value, field.type, false);
-    inferrer.listener.fieldInitializer(
-        this, fileOffset, null, null, null, null, null, field);
   }
 }
 
 /// Concrete shadow object representing a non-inverted "is" test in kernel form.
 class IsJudgment extends IsExpression implements ExpressionJudgment {
-  IsExpressionTokens tokens;
-
   DartType inferredType;
 
   ExpressionJudgment get judgment => operand;
 
-  IsJudgment(Expression operand, this.tokens, DartType type)
-      : super(operand, type);
+  IsJudgment(Expression operand, DartType type) : super(operand, type);
 
   @override
   Expression infer<Expression, Statement, Initializer, Type>(
       ShadowTypeInferrer inferrer, DartType typeContext) {
     inferrer.inferExpression(judgment, const UnknownType(), false);
     inferredType = inferrer.coreTypes.boolClass.rawType;
-    inferrer.listener
-        .isExpression(this, fileOffset, null, tokens, null, inferredType);
     return null;
   }
 }
 
 /// Concrete shadow object representing an inverted "is" test in kernel form.
 class IsNotJudgment extends Not implements ExpressionJudgment {
-  IsNotExpressionTokens tokens;
   DartType inferredType;
 
   @override
@@ -1692,7 +1484,7 @@
 
   ExpressionJudgment get judgment => operand.operand;
 
-  IsNotJudgment(Expression operand, this.tokens, DartType type, int charOffset)
+  IsNotJudgment(Expression operand, DartType type, int charOffset)
       : super(new IsExpression(operand, type)..fileOffset = charOffset);
 
   @override
@@ -1700,8 +1492,6 @@
       ShadowTypeInferrer inferrer, DartType typeContext) {
     inferrer.inferExpression(judgment, const UnknownType(), false);
     inferredType = inferrer.coreTypes.boolClass.rawType;
-    inferrer.listener
-        .isNotExpression(this, fileOffset, null, tokens, null, inferredType);
     return null;
   }
 }
@@ -1711,38 +1501,24 @@
     implements StatementJudgment {
   LabeledStatementJudgment(Statement body) : super(body);
 
-  Object binder;
-
   StatementJudgment get judgment => body;
 
-  Object createBinder(ShadowTypeInferrer inferrer) {
-    // TODO(paulberry): we need one binder for each label
-    return binder ??=
-        inferrer.listener.binderForStatementLabel(this, fileOffset, null);
-  }
-
   @override
   void infer<Expression, Statement, Initializer, Type>(
       ShadowTypeInferrer inferrer) {
     inferrer.inferStatement(judgment);
-    // TODO(paulberry): support multiple labels.
-    List<Object> labels = <Object>[
-      inferrer.listener.statementLabel(createBinder(inferrer), null, null)
-    ];
-    inferrer.listener.labeledStatement(labels, null);
   }
 }
 
 /// Type inference derivation for [LiteralList].
 class ListLiteralJudgment extends ListLiteral implements ExpressionJudgment {
-  ListLiteralTokens tokens;
   DartType inferredType;
 
   List<Expression> get judgments => expressions;
 
   final DartType _declaredTypeArgument;
 
-  ListLiteralJudgment(this.tokens, List<Expression> expressions,
+  ListLiteralJudgment(List<Expression> expressions,
       {DartType typeArgument, bool isConst: false})
       : _declaredTypeArgument = typeArgument,
         super(expressions,
@@ -1805,21 +1581,16 @@
             isVoidAllowed: typeArgument is VoidType);
       }
     }
-    var inferredType = new InterfaceType(listClass, [inferredTypeArgument]);
-    inferrer.listener
-        .listLiteral(this, fileOffset, tokens, null, expressions, inferredType);
-    this.inferredType = inferredType;
+    inferredType = new InterfaceType(listClass, [inferredTypeArgument]);
     return null;
   }
 }
 
 /// Shadow object for [LogicalExpression].
 class LogicalJudgment extends LogicalExpression implements ExpressionJudgment {
-  LogicalExpressionTokens tokens;
   DartType inferredType;
 
-  LogicalJudgment(
-      Expression left, this.tokens, String operator, Expression right)
+  LogicalJudgment(Expression left, String operator, Expression right)
       : super(left, operator, right);
 
   ExpressionJudgment get leftJudgment => left;
@@ -1839,8 +1610,6 @@
     inferrer.ensureAssignable(
         boolType, rightJudgment.inferredType, right, right.fileOffset);
     inferredType = boolType;
-    inferrer.listener
-        .logicalExpression(this, fileOffset, null, tokens, null, inferredType);
     return null;
   }
 }
@@ -1878,7 +1647,6 @@
 
 /// Type inference derivation for [MapLiteral].
 class MapLiteralJudgment extends MapLiteral implements ExpressionJudgment {
-  MapLiteralTokens tokens;
   DartType inferredType;
 
   List<MapEntry> get judgments => entries;
@@ -1886,7 +1654,7 @@
   final DartType _declaredKeyType;
   final DartType _declaredValueType;
 
-  MapLiteralJudgment(this.tokens, List<MapEntry> judgments,
+  MapLiteralJudgment(List<MapEntry> judgments,
       {DartType keyType, DartType valueType, bool isConst: false})
       : _declaredKeyType = keyType,
         _declaredValueType = valueType,
@@ -1971,8 +1739,6 @@
     }
     inferredType =
         new InterfaceType(mapClass, [inferredKeyType, inferredValueType]);
-    inferrer.listener
-        .mapLiteral(this, fileOffset, tokens, null, entries, inferredType);
     return null;
   }
 }
@@ -2056,7 +1822,6 @@
     inferrer.inferExpression(initializer, typeContext, true);
     inferredType = initializer.inferredType;
     if (inferrer.strongMode) variable.type = inferredType;
-    inferrer.listener.namedFunctionExpression(this, fileOffset, inferredType);
     return null;
   }
 }
@@ -2064,12 +1829,10 @@
 /// Shadow object for [Not].
 class NotJudgment extends Not implements ExpressionJudgment {
   final bool isSynthetic;
-  final NotTokens tokens;
 
   DartType inferredType;
 
-  NotJudgment(this.isSynthetic, this.tokens, ExpressionJudgment operand)
-      : super(operand);
+  NotJudgment(this.isSynthetic, ExpressionJudgment operand) : super(operand);
 
   ExpressionJudgment get judgment => operand;
 
@@ -2083,10 +1846,6 @@
     inferrer.ensureAssignable(
         boolType, judgment.inferredType, operand, fileOffset);
     inferredType = boolType;
-    // TODO(scheglov) Temporary: https://github.com/dart-lang/sdk/issues/33666
-    if (!isSynthetic) {
-      inferrer.listener.not(this, fileOffset, tokens, null, inferredType);
-    }
     return null;
   }
 }
@@ -2161,18 +1920,14 @@
 
 /// Concrete shadow object representing a null literal in kernel form.
 class NullJudgment extends NullLiteral implements ExpressionJudgment {
-  NullLiteralTokens tokens;
-
   DartType inferredType;
 
-  NullJudgment(this.tokens);
+  NullJudgment();
 
   @override
   Expression infer<Expression, Statement, Initializer, Type>(
       ShadowTypeInferrer inferrer, DartType typeContext) {
     inferredType = inferrer.coreTypes.nullClass.rawType;
-    inferrer.listener
-        .nullLiteral(this, fileOffset, tokens, fileOffset == -1, inferredType);
     return null;
   }
 }
@@ -2261,15 +2016,8 @@
     // member.  TODO(paulberry): would it be better to use the read member when
     // doing compound assignment?
     var writeContext = inferrer.getSetterType(writeMember, receiverType);
-    var inferredResult = _inferRhs(inferrer, readType, writeContext);
+    _inferRhs(inferrer, readType, writeContext);
     if (inferrer.strongMode) nullAwareGuard?.staticType = inferredType;
-    inferrer.listener.propertyAssign(
-        this,
-        write.fileOffset,
-        inferrer.getRealTarget(writeMember),
-        writeContext,
-        inferredResult.combiner,
-        inferredType);
     _replaceWithDesugared();
     return null;
   }
@@ -2326,25 +2074,21 @@
         target.enclosingClass.thisType, argumentJudgments,
         skipTypeArgumentInference: true);
     ArgumentsJudgment.removeNonInferrableArgumentTypes(arguments);
-    inferrer.listener.redirectingInitializer(
-        this, fileOffset, null, null, null, null, target);
   }
 }
 
 /// Shadow object for [Rethrow].
 class RethrowJudgment extends Rethrow implements ExpressionJudgment {
-  RethrowTokens tokens;
   final kernel.Expression desugaredError;
 
   DartType inferredType;
 
-  RethrowJudgment(this.tokens, this.desugaredError);
+  RethrowJudgment(this.desugaredError);
 
   @override
   Expression infer<Expression, Statement, Initializer, Type>(
       ShadowTypeInferrer inferrer, DartType typeContext) {
     inferredType = const BottomType();
-    inferrer.listener.rethrow_(this, fileOffset, tokens, inferredType);
     if (desugaredError != null) {
       parent.replaceChild(this, desugaredError);
       parent = null;
@@ -2355,10 +2099,9 @@
 
 /// Concrete shadow object representing a return statement in kernel form.
 class ReturnJudgment extends ReturnStatement implements StatementJudgment {
-  final ReturnStatementTokens tokens;
   final String returnKeywordLexeme;
 
-  ReturnJudgment(this.tokens, this.returnKeywordLexeme, [Expression expression])
+  ReturnJudgment(this.returnKeywordLexeme, [Expression expression])
       : super(expression);
 
   ExpressionJudgment get judgment => expression;
@@ -2381,7 +2124,6 @@
     }
     closureContext.handleReturn(inferrer, this, inferredType,
         !identical(returnKeywordLexeme, "return"));
-    inferrer.listener.returnStatement(this, fileOffset, tokens, null);
   }
 }
 
@@ -2424,14 +2166,7 @@
         writeMember.inferenceNode = null;
       }
     }
-    var inferredResult = _inferRhs(inferrer, readType, writeContext);
-    inferrer.listener.staticAssign(
-        this,
-        write?.fileOffset,
-        writeMember,
-        writeContext is UnknownType ? const DynamicType() : writeContext,
-        inferredResult.combiner,
-        inferredType);
+    _inferRhs(inferrer, readType, writeContext);
     _replaceWithDesugared();
     return null;
   }
@@ -2457,7 +2192,6 @@
       type = inferrer.instantiateTearOff(type, typeContext, this);
     }
     inferredType = type;
-    inferrer.listener.staticGet(this, fileOffset, target, inferredType);
     return null;
   }
 }
@@ -2482,16 +2216,7 @@
         : new FunctionType([], const DynamicType());
     var inferenceResult = inferrer.inferInvocation(typeContext, fileOffset,
         calleeType, calleeType.returnType, argumentJudgments);
-    var inferredType = inferenceResult.type;
-    this.inferredType = inferredType;
-    inferrer.listener.staticInvocation(
-        this,
-        arguments.fileOffset,
-        target,
-        arguments.types,
-        inferrer.lastCalleeType,
-        inferrer.lastInferredSubstitution,
-        inferredType);
+    inferredType = inferenceResult.type;
     if (desugaredError != null) {
       parent.replaceChild(this, desugaredError);
       parent = null;
@@ -2517,7 +2242,6 @@
       }
     }
     inferredType = inferrer.coreTypes.stringClass.rawType;
-    inferrer.listener.stringConcatenation(this, fileOffset, inferredType);
     return null;
   }
 }
@@ -2525,18 +2249,14 @@
 /// Type inference derivation for [StringLiteral].
 class StringLiteralJudgment extends StringLiteral
     implements ExpressionJudgment {
-  StringLiteralTokens tokens;
   DartType inferredType;
 
-  StringLiteralJudgment(this.tokens, String value) : super(value);
+  StringLiteralJudgment(String value) : super(value);
 
   @override
   Expression infer<Expression, Statement, Initializer, Type>(
       ShadowTypeInferrer inferrer, DartType typeContext) {
-    var inferredType = inferrer.coreTypes.stringClass.rawType;
-    inferrer.listener
-        .stringLiteral(this, fileOffset, tokens, value, inferredType);
-    this.inferredType = inferredType;
+    inferredType = inferrer.coreTypes.stringClass.rawType;
     return null;
   }
 }
@@ -2544,10 +2264,7 @@
 /// Concrete shadow object representing a super initializer in kernel form.
 class SuperInitializerJudgment extends SuperInitializer
     implements InitializerJudgment {
-  SuperInitializerTokens tokens;
-
-  SuperInitializerJudgment(
-      this.tokens, Constructor target, ArgumentsJudgment arguments)
+  SuperInitializerJudgment(Constructor target, ArgumentsJudgment arguments)
       : super(target, arguments);
 
   ArgumentsJudgment get argumentJudgments => arguments;
@@ -2566,7 +2283,6 @@
         inferrer.thisType,
         argumentJudgments,
         skipTypeArgumentInference: true);
-    inferrer.listener.superInitializer(this, fileOffset, tokens, null);
   }
 }
 
@@ -2632,39 +2348,24 @@
 
 /// Concrete shadow object representing a switch case.
 class SwitchCaseJudgment extends SwitchCase {
-  SwitchCaseTokens tokens;
-  Object binder;
-
-  SwitchCaseJudgment(this.tokens, List<Expression> expressions,
-      List<int> expressionOffsets, Statement body,
+  SwitchCaseJudgment(
+      List<Expression> expressions, List<int> expressionOffsets, Statement body,
       {bool isDefault: false})
       : super(expressions, expressionOffsets, body, isDefault: isDefault);
 
-  SwitchCaseJudgment.defaultCase(this.tokens, Statement body)
-      : super.defaultCase(body);
+  SwitchCaseJudgment.defaultCase(Statement body) : super.defaultCase(body);
 
-  SwitchCaseJudgment.empty()
-      : tokens = null,
-        super.empty();
+  SwitchCaseJudgment.empty() : super.empty();
 
   List<ExpressionJudgment> get expressionJudgments => expressions.cast();
 
   StatementJudgment get bodyJudgment => body;
-
-  Object createBinder(ShadowTypeInferrer inferrer) {
-    // TODO(paulberry): we need one binder for each label
-    return binder ??=
-        inferrer.listener.binderForSwitchLabel(this, fileOffset, null);
-  }
 }
 
 /// Concrete shadow object representing a switch statement in kernel form.
 class SwitchStatementJudgment extends SwitchStatement
     implements StatementJudgment {
-  SwitchStatementTokens tokens;
-
-  SwitchStatementJudgment(
-      this.tokens, Expression expression, List<SwitchCase> cases)
+  SwitchStatementJudgment(Expression expression, List<SwitchCase> cases)
       : super(expression, cases);
 
   ExpressionJudgment get expressionJudgment => expression;
@@ -2697,12 +2398,7 @@
         }
       }
       inferrer.inferStatement(switchCase.bodyJudgment);
-      // TODO(paulberry): support labels.
-      inferrer.listener.switchCase(switchCase, null, null, null, null, null);
     }
-
-    inferrer.listener
-        .switchStatement(this, fileOffset, tokens, expression, cases);
   }
 }
 
@@ -2717,8 +2413,6 @@
   Expression infer<Expression, Statement, Initializer, Type>(
       ShadowTypeInferrer inferrer, DartType typeContext) {
     inferredType = inferrer.coreTypes.symbolClass.rawType;
-    inferrer.listener
-        .symbolLiteral(this, fileOffset, null, null, null, inferredType);
     return null;
   }
 }
@@ -2726,6 +2420,7 @@
 /// Synthetic judgment class representing an attempt to invoke an unresolved
 /// constructor, or a constructor that cannot be invoked, or a resolved
 /// constructor with wrong number of arguments.
+// TODO(ahe): Remove this?
 class InvalidConstructorInvocationJudgment extends SyntheticExpressionJudgment {
   final Member constructor;
   final Arguments arguments;
@@ -2751,26 +2446,6 @@
     ExpressionInferenceResult inferenceResult = inferrer.inferInvocation(
         typeContext, fileOffset, calleeType, returnType, argumentJudgments);
     this.inferredType = inferenceResult.type;
-    inferrer.listener.constructorInvocation(
-        this, arguments.fileOffset, constructor, inferredType);
-    return super.infer(inferrer, typeContext);
-  }
-}
-
-/// Synthetic judgment class representing an attempt to write to a read-only
-/// local variable.
-class InvalidVariableWriteJudgment extends SyntheticExpressionJudgment {
-  /// Note: private to avoid colliding with Let.variable.
-  final VariableDeclarationJudgment _variable;
-
-  InvalidVariableWriteJudgment(kernel.Expression desugared, this._variable)
-      : super(desugared);
-
-  @override
-  Expression infer<Expression, Statement, Initializer, Type>(
-      ShadowTypeInferrer inferrer, DartType typeContext) {
-    inferrer.listener.variableAssign(this, fileOffset, _variable.type,
-        _variable.createBinder(inferrer), null, _variable.type);
     return super.infer(inferrer, typeContext);
   }
 }
@@ -2796,24 +2471,6 @@
   }
 }
 
-/// Synthetic judgment class representing an attempt reference a member
-/// that is not allowed at this location.
-class InvalidPropertyGetJudgment extends SyntheticExpressionJudgment {
-  final Member member;
-
-  InvalidPropertyGetJudgment(kernel.Expression desugared, this.member)
-      : super(desugared);
-
-  @override
-  Expression infer<Expression, Statement, Initializer, Type>(
-      ShadowTypeInferrer inferrer, DartType typeContext) {
-    var inferredType = member?.getterType ?? const DynamicType();
-    inferrer.listener
-        .propertyGet(this, fileOffset, false, member, inferredType);
-    return super.infer(inferrer, typeContext);
-  }
-}
-
 /// Shadow object for expressions that are introduced by the front end as part
 /// of desugaring or the handling of error conditions.
 ///
@@ -2882,30 +2539,26 @@
 }
 
 class ThisJudgment extends ThisExpression implements ExpressionJudgment {
-  final ThisExpressionTokens tokens;
-
   DartType inferredType;
 
-  ThisJudgment(this.tokens);
+  ThisJudgment();
 
   @override
   Expression infer<Expression, Statement, Initializer, Type>(
       ShadowTypeInferrer inferrer, DartType typeContext) {
     inferredType = inferrer.thisType ?? const DynamicType();
-    inferrer.listener.thisExpression(this, fileOffset, tokens, inferredType);
     return null;
   }
 }
 
 class ThrowJudgment extends Throw implements ExpressionJudgment {
-  final ThrowTokens tokens;
   final kernel.Expression desugaredError;
 
   DartType inferredType;
 
   ExpressionJudgment get judgment => expression;
 
-  ThrowJudgment(this.tokens, Expression expression, {this.desugaredError})
+  ThrowJudgment(Expression expression, {this.desugaredError})
       : super(expression);
 
   @override
@@ -2913,7 +2566,6 @@
       ShadowTypeInferrer inferrer, DartType typeContext) {
     inferrer.inferExpression(judgment, const UnknownType(), false);
     inferredType = const BottomType();
-    inferrer.listener.throw_(this, fileOffset, tokens, null, inferredType);
     if (desugaredError != null) {
       parent.replaceChild(this, desugaredError);
       parent = null;
@@ -2948,8 +2600,7 @@
 
 /// Concrete shadow object representing a catch clause.
 class CatchJudgment extends Catch {
-  CatchStatementTokens tokens;
-  CatchJudgment(this.tokens, VariableDeclaration exception, Statement body,
+  CatchJudgment(VariableDeclaration exception, Statement body,
       {DartType guard: const DynamicType(), VariableDeclaration stackTrace})
       : super(exception, body, guard: guard, stackTrace: stackTrace);
 
@@ -2962,16 +2613,6 @@
   void infer<Expression, Statement, Initializer, Type>(
       ShadowTypeInferrer inferrer) {
     inferrer.inferStatement(bodyJudgment);
-    inferrer.listener.catchStatement(
-        this,
-        fileOffset,
-        tokens,
-        null,
-        null, // body
-        exceptionJudgment?.createBinder(inferrer),
-        exceptionJudgment?.type,
-        stackTraceJudgment?.createBinder(inferrer),
-        stackTraceJudgment?.type);
   }
 }
 
@@ -2990,17 +2631,14 @@
     for (var catch_ in catchJudgments) {
       catch_.infer(inferrer);
     }
-    inferrer.listener.tryCatch(this, fileOffset);
   }
 }
 
 /// Concrete shadow object representing a try-finally block in kernel form.
 class TryFinallyJudgment extends TryFinally implements StatementJudgment {
-  TryFinallyTokens tokens;
   final List<Catch> catches;
 
-  TryFinallyJudgment(
-      this.tokens, Statement body, this.catches, Statement finalizer)
+  TryFinallyJudgment(Statement body, this.catches, Statement finalizer)
       : super(body, finalizer);
 
   List<CatchJudgment> get catchJudgments => catches?.cast();
@@ -3018,8 +2656,6 @@
       body = new TryCatch(body, catches)..parent = this;
     }
     inferrer.inferStatement(finalizerJudgment);
-    inferrer.listener
-        .tryFinally(this, fileOffset, tokens, body, catches, finalizer);
   }
 }
 
@@ -3035,21 +2671,15 @@
 
   @override
   ShadowTypeInferrer createLocalTypeInferrer(
-      Uri uri,
-      TypeInferenceListener<int, Node, int> listener,
-      InterfaceType thisType,
-      SourceLibraryBuilder library) {
-    return new ShadowTypeInferrer._(
-        this, uri, listener, false, thisType, library);
+      Uri uri, InterfaceType thisType, SourceLibraryBuilder library) {
+    return new ShadowTypeInferrer._(this, uri, false, thisType, library);
   }
 
   @override
   ShadowTypeInferrer createTopLevelTypeInferrer(
-      TypeInferenceListener<int, Node, int> listener,
-      InterfaceType thisType,
-      ShadowField field) {
-    return field._typeInferrer = new ShadowTypeInferrer._(
-        this, field.fileUri, listener, true, thisType, null);
+      InterfaceType thisType, ShadowField field) {
+    return field._typeInferrer =
+        new ShadowTypeInferrer._(this, field.fileUri, true, thisType, null);
   }
 
   @override
@@ -3064,15 +2694,10 @@
   @override
   final typePromoter;
 
-  ShadowTypeInferrer._(
-      ShadowTypeInferenceEngine engine,
-      Uri uri,
-      TypeInferenceListener<int, Node, int> listener,
-      bool topLevel,
-      InterfaceType thisType,
-      SourceLibraryBuilder library)
+  ShadowTypeInferrer._(ShadowTypeInferenceEngine engine, Uri uri, bool topLevel,
+      InterfaceType thisType, SourceLibraryBuilder library)
       : typePromoter = new ShadowTypePromoter(engine.typeSchemaEnvironment),
-        super(engine, uri, listener, topLevel, thisType, library);
+        super(engine, uri, topLevel, thisType, library);
 
   @override
   Expression getFieldInitializer(ShadowField field) {
@@ -3180,7 +2805,6 @@
   Expression infer<Expression, Statement, Initializer, Type>(
       ShadowTypeInferrer inferrer, DartType typeContext) {
     inferredType = inferrer.coreTypes.typeClass.rawType;
-    inferrer.listener.typeLiteral(this, fileOffset, type, inferredType);
     return null;
   }
 }
@@ -3279,17 +2903,7 @@
         _storeLetType(inferrer, read, writeContext);
       }
     }
-    var inferredResult = _inferRhs(inferrer, readType, writeContext);
-    inferrer.listener.variableAssign(
-        this,
-        write.fileOffset,
-        writeContext,
-        write is VariableSet
-            ? (write.variable as VariableDeclarationJudgment)
-                .createBinder(inferrer)
-            : null,
-        inferredResult.combiner,
-        inferredType);
+    _inferRhs(inferrer, readType, writeContext);
     _replaceWithDesugared();
     return null;
   }
@@ -3302,16 +2916,22 @@
 
   final bool _implicitlyTyped;
 
+  // TODO(ahe): Remove this field. We can get rid of it by recording closure
+  // mutation in [BodyBuilder].
   final int _functionNestingLevel;
 
+  // TODO(ahe): Remove this field. It's only used locally when compiling a
+  // method, and this can thus be tracked in a [Set] (actually, tracking this
+  // information in a [List] is probably even faster as the average size will
+  // be close to zero).
   bool _mutatedInClosure = false;
 
+  // TODO(ahe): Investigate if this can be removed.
   bool _mutatedAnywhere = false;
 
+  // TODO(ahe): Investigate if this can be removed.
   final bool _isLocalFunction;
 
-  Object binder;
-
   /// The same [annotations] list is used for all [VariableDeclarationJudgment]s
   /// of a variable declaration statement. But we need to perform inference
   /// only once. So, we set this flag to `false` for the second and subsequent
@@ -3408,17 +3028,8 @@
         initializer = replacedInitializer;
       }
     }
-    inferrer.listener.variableDeclaration(
-        createBinder(inferrer), _implicitlyTyped ? inferredType : type);
   }
 
-  Object createBinder(ShadowTypeInferrer inferrer) =>
-      binder ??= _isLocalFunction
-          ? inferrer.listener
-              .binderForFunctionDeclaration(this, fileOffset, name)
-          : inferrer.listener.binderForVariableDeclaration(
-              this, fileOffset, name, forSyntheticToken);
-
   /// Determine whether the given [VariableDeclarationJudgment] had an implicit
   /// type.
   ///
@@ -3455,8 +3066,6 @@
         TypeInferrerImpl.unknownFunction,
         const DynamicType(),
         argumentsJudgment);
-    inferrer.listener.staticInvocation(this, fileOffset, null,
-        argumentsJudgment.types, null, null, inferredType);
     return result;
   }
 }
@@ -3476,47 +3085,6 @@
       ShadowTypeInferrer inferrer, DartType typeContext) {
     inferrer.inferExpression(rhs, const UnknownType(), true);
     inferredType = isCompound ? const DynamicType() : rhs.inferredType;
-    inferrer.listener.variableAssign(
-        this, fileOffset, const DynamicType(), null, null, inferredType);
-    return super.infer(inferrer, typeContext);
-  }
-}
-
-/// Synthetic judgment class representing an attempt to apply a prefix or
-/// postfix operator to an unresolved variable.
-class UnresolvedVariableUnaryJudgment extends SyntheticExpressionJudgment {
-  final int offset;
-  final bool isSynthetic;
-
-  UnresolvedVariableUnaryJudgment(
-      kernel.Expression desugared, this.offset, this.isSynthetic)
-      : super(desugared);
-
-  @override
-  Expression infer<Expression, Statement, Initializer, Type>(
-      ShadowTypeInferrer inferrer, DartType typeContext) {
-    inferrer.listener.variableGet(
-        this, offset, isSynthetic, false, null, const DynamicType());
-    inferrer.listener.variableAssign(
-        this, fileOffset, const DynamicType(), null, null, inferredType);
-    return super.infer(inferrer, typeContext);
-  }
-}
-
-/// Synthetic judgment class representing an attempt to read an unresolved
-/// variable.
-class UnresolvedVariableGetJudgment extends SyntheticExpressionJudgment {
-  final bool forSyntheticToken;
-
-  UnresolvedVariableGetJudgment(
-      kernel.Expression desugared, this.forSyntheticToken)
-      : super(desugared);
-
-  @override
-  Expression infer<Expression, Statement, Initializer, Type>(
-      ShadowTypeInferrer inferrer, DartType typeContext) {
-    inferrer.listener.variableGet(
-        this, fileOffset, forSyntheticToken, false, null, const DynamicType());
     return super.infer(inferrer, typeContext);
   }
 }
@@ -3532,19 +3100,6 @@
   VariableGetJudgment(VariableDeclaration variable, this._fact, this._scope)
       : super(variable);
 
-  /// Return `true` if the given [variable] declaration occurs in a let
-  /// expression that is, or is part of, a cascade expression.
-  bool _isInCascade() {
-    TreeNode ancestor = variable.parent;
-    while (ancestor is Let) {
-      if (ancestor is CascadeJudgment) {
-        return true;
-      }
-      ancestor = ancestor.parent;
-    }
-    return false;
-  }
-
   @override
   Expression infer<Expression, Statement, Initializer, Type>(
       ShadowTypeInferrer inferrer, DartType typeContext) {
@@ -3564,18 +3119,13 @@
       type = inferrer.instantiateTearOff(type, typeContext, this);
     }
     inferredType = type;
-    inferrer.listener.variableGet(this, fileOffset, false, _isInCascade(),
-        variable.createBinder(inferrer), inferredType);
     return null;
   }
 }
 
 /// Concrete shadow object representing a while loop in kernel form.
 class WhileJudgment extends WhileStatement implements StatementJudgment {
-  WhileStatementTokens tokens;
-
-  WhileJudgment(this.tokens, Expression condition, Statement body)
-      : super(condition, body);
+  WhileJudgment(Expression condition, Statement body) : super(condition, body);
 
   ExpressionJudgment get conditionJudgment => condition;
 
@@ -3591,15 +3141,12 @@
     inferrer.ensureAssignable(expectedType, conditionJudgment.inferredType,
         condition, condition.fileOffset);
     inferrer.inferStatement(bodyJudgment);
-    inferrer.listener.whileStatement(this, fileOffset, tokens, null, null);
   }
 }
 
 /// Concrete shadow object representing a yield statement in kernel form.
 class YieldJudgment extends YieldStatement implements StatementJudgment {
-  YieldStatementTokens tokens;
-
-  YieldJudgment(this.tokens, bool isYieldStar, Expression expression)
+  YieldJudgment(bool isYieldStar, Expression expression)
       : super(expression, isYieldStar: isYieldStar);
 
   ExpressionJudgment get judgment => expression;
@@ -3624,7 +3171,6 @@
     }
     closureContext.handleYield(
         inferrer, isYieldStar, judgment.inferredType, expression, fileOffset);
-    inferrer.listener.yieldStatement(this, fileOffset, tokens, null);
   }
 }
 
@@ -3647,8 +3193,6 @@
       var calleeType = new FunctionType([], inferredType);
       inferrer.inferInvocation(typeContext, fileOffset, calleeType,
           calleeType.returnType, argumentJudgments);
-      inferrer.listener.loadLibrary(this, arguments.fileOffset,
-          import.targetLibrary, calleeType, inferredType);
     }
     return null;
   }
@@ -3668,8 +3212,6 @@
       ShadowTypeInferrer inferrer, DartType typeContext) {
     inferredType = new FunctionType(
         [], inferrer.typeSchemaEnvironment.futureType(const DynamicType()));
-    inferrer.listener.loadLibraryTearOff(
-        this, fileOffset, import.targetLibrary, inferredType);
     return null;
   }
 }
@@ -3691,9 +3233,7 @@
 
 /// Concrete shadow object representing a named expression.
 class NamedExpressionJudgment extends NamedExpression {
-  NamedExpressionTokens tokens;
-
-  NamedExpressionJudgment(this.tokens, String nameLexeme, Expression value)
+  NamedExpressionJudgment(String nameLexeme, Expression value)
       : super(nameLexeme, value);
 
   ExpressionJudgment get judgment => value;
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
index 86122bb..5daa713 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
@@ -15,7 +15,6 @@
         Component,
         Constructor,
         DartType,
-        DynamicType,
         EmptyStatement,
         Expression,
         ExpressionStatement,
@@ -151,7 +150,7 @@
   }
 
   void read(Uri uri) {
-    loader.read(uri, -1);
+    loader.read(uri, -1, accessor: loader.first);
   }
 
   @override
@@ -238,7 +237,7 @@
         () async {
           loader.createTypeInferenceEngine();
           await loader.buildOutlines();
-          loader.coreLibrary.becomeCoreLibrary(const DynamicType());
+          loader.coreLibrary.becomeCoreLibrary();
           dynamicType.bind(loader.coreLibrary["dynamic"]);
           loader.resolveParts();
           loader.computeLibraryScopes();
@@ -810,13 +809,13 @@
       KernelLibraryBuilder first;
       for (Uri patch in patches) {
         if (first == null) {
-          first =
-              library.loader.read(patch, -1, fileUri: patch, origin: library);
+          first = library.loader.read(patch, -1,
+              fileUri: patch, origin: library, accessor: library);
         } else {
           // If there's more than one patch file, it's interpreted as a part of
           // the patch library.
           KernelLibraryBuilder part =
-              library.loader.read(patch, -1, fileUri: patch);
+              library.loader.read(patch, -1, fileUri: patch, accessor: first);
           first.parts.add(part);
           part.addPartOf(null, null, "${first.uri}", -1);
         }
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_type_builder.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_type_builder.dart
index 3a22f6f..39fe14d 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_type_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_type_builder.dart
@@ -4,17 +4,18 @@
 
 library fasta.kernel_type_builder;
 
-import 'package:kernel/ast.dart' show DartType, Supertype;
+import 'package:kernel/ast.dart' show DartType, Library, Supertype;
 
 import 'kernel_builder.dart' show LibraryBuilder, TypeBuilder;
 
 abstract class KernelTypeBuilder extends TypeBuilder {
   const KernelTypeBuilder();
 
-  DartType build(LibraryBuilder library);
+  DartType build(LibraryBuilder<TypeBuilder, Object> library);
 
-  Supertype buildSupertype(LibraryBuilder library, int charOffset, Uri fileUri);
+  Supertype buildSupertype(LibraryBuilder<KernelTypeBuilder, Library> library,
+      int charOffset, Uri fileUri);
 
-  Supertype buildMixedInType(
-      LibraryBuilder library, int charOffset, Uri fileUri);
+  Supertype buildMixedInType(LibraryBuilder<KernelTypeBuilder, Library> library,
+      int charOffset, Uri fileUri);
 }
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_type_variable_builder.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_type_variable_builder.dart
index 017c9fc..6d1bca2 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_type_variable_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_type_variable_builder.dart
@@ -7,8 +7,6 @@
 import 'package:kernel/ast.dart'
     show DartType, TypeParameter, TypeParameterType;
 
-import '../deprecated_problems.dart' show deprecated_inputError;
-
 import '../fasta_codes.dart' show templateTypeArgumentsOnTypeVariable;
 
 import 'kernel_builder.dart'
@@ -27,8 +25,6 @@
 
   KernelTypeVariableBuilder actualOrigin;
 
-  Object binder;
-
   KernelTypeVariableBuilder(
       String name, KernelLibraryBuilder compilationUnit, int charOffset,
       [KernelTypeBuilder bound, TypeParameter actual])
@@ -68,11 +64,15 @@
   DartType buildTypesWithBuiltArguments(
       LibraryBuilder library, List<DartType> arguments) {
     if (arguments != null) {
-      return deprecated_inputError(null, null,
-          "Can't use type arguments with type parameter $parameter");
-    } else {
-      return buildType(library, null);
+      int charOffset = -1; // TODO(ahe): Provide these.
+      Uri fileUri = null; // TODO(ahe): Provide these.
+      library.addProblem(
+          templateTypeArgumentsOnTypeVariable.withArguments(name),
+          charOffset,
+          name.length,
+          fileUri);
     }
+    return buildType(library, null);
   }
 
   KernelTypeBuilder asTypeBuilder() {
diff --git a/pkg/front_end/lib/src/fasta/kernel/type_algorithms.dart b/pkg/front_end/lib/src/fasta/kernel/type_algorithms.dart
index a45b739..026ee98 100644
--- a/pkg/front_end/lib/src/fasta/kernel/type_algorithms.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/type_algorithms.dart
@@ -371,13 +371,25 @@
           typesAndDependencies.add(type);
           typesAndDependencies.add(dependencies);
         }
-      } else if (declaration is FunctionTypeAliasBuilder<TypeBuilder, Object> &&
-          declaration.typeVariables != null) {
-        List<Object> dependencies =
-            findInboundReferences(declaration.typeVariables);
-        if (dependencies.length != 0) {
-          typesAndDependencies.add(type);
-          typesAndDependencies.add(dependencies);
+      } else if (declaration is FunctionTypeAliasBuilder<TypeBuilder, Object>) {
+        if (declaration.typeVariables != null) {
+          List<Object> dependencies =
+              findInboundReferences(declaration.typeVariables);
+          if (dependencies.length != 0) {
+            typesAndDependencies.add(type);
+            typesAndDependencies.add(dependencies);
+          }
+        }
+        if (declaration.type is FunctionTypeBuilder) {
+          FunctionTypeBuilder type = declaration.type;
+          if (type.typeVariables != null) {
+            List<Object> dependencies =
+                findInboundReferences(type.typeVariables);
+            if (dependencies.length != 0) {
+              typesAndDependencies.add(type);
+              typesAndDependencies.add(dependencies);
+            }
+          }
         }
       }
     } else {
@@ -495,14 +507,32 @@
             }
           }
         } else if (declaration
-                is FunctionTypeAliasBuilder<TypeBuilder, Object> &&
-            declaration.typeVariables != null) {
-          for (TypeVariableBuilder<TypeBuilder, Object> variable
-              in declaration.typeVariables) {
-            if (variable.bound != null) {
-              for (List<Object> dependencyPath in findRawTypePathsToDeclaration(
-                  variable.bound, end, visited)) {
-                paths.add(<Object>[start, variable]..addAll(dependencyPath));
+            is FunctionTypeAliasBuilder<TypeBuilder, Object>) {
+          if (declaration.typeVariables != null) {
+            for (TypeVariableBuilder<TypeBuilder, Object> variable
+                in declaration.typeVariables) {
+              if (variable.bound != null) {
+                for (List<Object> dependencyPath
+                    in findRawTypePathsToDeclaration(
+                        variable.bound, end, visited)) {
+                  paths.add(<Object>[start, variable]..addAll(dependencyPath));
+                }
+              }
+            }
+          }
+          if (declaration.type is FunctionTypeBuilder) {
+            FunctionTypeBuilder type = declaration.type;
+            if (type.typeVariables != null) {
+              for (TypeVariableBuilder<TypeBuilder, Object> variable
+                  in type.typeVariables) {
+                if (variable.bound != null) {
+                  for (List<Object> dependencyPath
+                      in findRawTypePathsToDeclaration(
+                          variable.bound, end, visited)) {
+                    paths
+                        .add(<Object>[start, variable]..addAll(dependencyPath));
+                  }
+                }
               }
             }
           }
@@ -562,14 +592,29 @@
         }
       }
     }
-  } else if (declaration is FunctionTypeAliasBuilder<TypeBuilder, Object> &&
-      declaration.typeVariables != null) {
-    for (TypeVariableBuilder<TypeBuilder, Object> variable
-        in declaration.typeVariables) {
-      if (variable.bound != null) {
-        for (List<Object> dependencyPath
-            in findRawTypePathsToDeclaration(variable.bound, declaration)) {
-          cycles.add(<Object>[variable]..addAll(dependencyPath));
+  } else if (declaration is FunctionTypeAliasBuilder<TypeBuilder, Object>) {
+    if (declaration.typeVariables != null) {
+      for (TypeVariableBuilder<TypeBuilder, Object> variable
+          in declaration.typeVariables) {
+        if (variable.bound != null) {
+          for (List<Object> dependencyPath
+              in findRawTypePathsToDeclaration(variable.bound, declaration)) {
+            cycles.add(<Object>[variable]..addAll(dependencyPath));
+          }
+        }
+      }
+    }
+    if (declaration.type is FunctionTypeBuilder) {
+      FunctionTypeBuilder type = declaration.type;
+      if (type.typeVariables != null) {
+        for (TypeVariableBuilder<TypeBuilder, Object> variable
+            in type.typeVariables) {
+          if (variable.bound != null) {
+            for (List<Object> dependencyPath
+                in findRawTypePathsToDeclaration(variable.bound, declaration)) {
+              cycles.add(<Object>[variable]..addAll(dependencyPath));
+            }
+          }
         }
       }
     }
@@ -620,16 +665,6 @@
   return issues;
 }
 
-/// Finds issues by cycles of raw generic types containing [declaration].
-///
-/// Returns flattened list of triplets according to the format specified by
-/// [convertRawTypeCyclesIntoIssues].
-List<Object> getRawTypeCycleIssues(
-    TypeDeclarationBuilder<TypeBuilder, Object> declaration) {
-  return convertRawTypeCyclesIntoIssues(
-      declaration, findRawTypeCycles(declaration));
-}
-
 /// Finds non-simplicity issues for the given set of [variables].
 ///
 /// The issues are those caused by raw types with inbound references in the
@@ -656,7 +691,8 @@
 /// The second element in the triplet is the error message.  The third element
 /// in the triplet is the context.
 List<Object> getNonSimplicityIssuesForDeclaration(
-    TypeDeclarationBuilder<TypeBuilder, Object> declaration) {
+    TypeDeclarationBuilder<TypeBuilder, Object> declaration,
+    {bool performErrorRecovery: true}) {
   var issues = <Object>[];
   if (declaration is ClassBuilder<TypeBuilder, Object> &&
       declaration.typeVariables != null) {
@@ -690,10 +726,28 @@
       }
     }
   }
-  issues.addAll(convertRawTypeCyclesIntoIssues(declaration, cyclesToReport));
+  List<Object> rawTypeCyclesAsIssues =
+      convertRawTypeCyclesIntoIssues(declaration, cyclesToReport);
+  issues.addAll(rawTypeCyclesAsIssues);
+
+  if (performErrorRecovery) {
+    breakCycles(cyclesToReport);
+  }
+
   return issues;
 }
 
+/// Break raw generic type [cycles] as error recovery.
+///
+/// The [cycles] are expected to be in the format specified for the return value
+/// of [findRawTypeCycles].
+void breakCycles(List<List<Object>> cycles) {
+  for (List<Object> cycle in cycles) {
+    TypeVariableBuilder<TypeBuilder, Object> variable = cycle[0];
+    variable.bound = null;
+  }
+}
+
 void findGenericFunctionTypes(TypeBuilder type, {List<TypeBuilder> result}) {
   result ??= <TypeBuilder>[];
   if (type is FunctionTypeBuilder) {
diff --git a/pkg/front_end/lib/src/fasta/loader.dart b/pkg/front_end/lib/src/fasta/loader.dart
index f1f9d5c..0d794a7 100644
--- a/pkg/front_end/lib/src/fasta/loader.dart
+++ b/pkg/front_end/lib/src/fasta/loader.dart
@@ -23,7 +23,7 @@
         templateInternalProblemContextSeverity,
         templateSourceBodySummary;
 
-import 'problems.dart' show internalProblem;
+import 'problems.dart' show internalProblem, unhandled;
 
 import 'rewrite_severity.dart' show rewriteSeverity;
 
@@ -35,6 +35,8 @@
 
 import 'type_inference/type_inference_engine.dart' show TypeInferenceEngine;
 
+const String untranslatableUriScheme = "org-dartlang-untranslatable-uri";
+
 abstract class Loader<L> {
   final Map<Uri, LibraryBuilder> builders = <Uri, LibraryBuilder>{};
 
@@ -78,6 +80,8 @@
 
   TypeInferenceEngine get typeInferenceEngine => null;
 
+  bool get isSourceLoader => false;
+
   /// Look up a library builder by the name [uri], or if such doesn't
   /// exist, create one. The canonical URI of the library is [uri], and its
   /// actual location is [fileUri].
@@ -102,7 +106,10 @@
         switch (uri.scheme) {
           case "package":
           case "dart":
-            fileUri = target.translateUri(uri);
+            fileUri = target.translateUri(uri) ??
+                new Uri(
+                    scheme: untranslatableUriScheme,
+                    path: Uri.encodeComponent("$uri"));
             break;
 
           default:
@@ -114,9 +121,11 @@
           target.createLibraryBuilder(uri, fileUri, origin);
       if (uri.scheme == "dart" && uri.path == "core") {
         coreLibrary = library;
-        target.loadExtraRequiredLibraries(this);
       }
       if (library.loader != this) {
+        if (coreLibrary == library) {
+          target.loadExtraRequiredLibraries(this);
+        }
         // This library isn't owned by this loader, so not further processing
         // should be attempted.
         return library;
@@ -129,6 +138,9 @@
         firstSourceUri ??= uri;
         first ??= library;
       }
+      if (coreLibrary == library) {
+        target.loadExtraRequiredLibraries(this);
+      }
       if (target.backendTarget.mayDefineRestrictedType(origin?.uri ?? uri)) {
         library.mayImplementRestrictedTypes = true;
       }
@@ -138,19 +150,25 @@
       unparsedLibraries.addLast(library);
       return library;
     });
-    if (accessor != null &&
-        !accessor.isPatch &&
-        !target.backendTarget
-            .allowPlatformPrivateLibraryAccess(accessor.uri, uri)) {
-      accessor.addProblem(messagePlatformPrivateLibraryAccess, charOffset,
-          noLength, accessor.fileUri);
+    if (accessor == null) {
+      if (builder.loader == this && first != builder && isSourceLoader) {
+        unhandled("null", "accessor", charOffset, uri);
+      }
+    } else {
+      builder.recordAccess(charOffset, noLength, accessor.fileUri);
+      if (!accessor.isPatch &&
+          !target.backendTarget
+              .allowPlatformPrivateLibraryAccess(accessor.uri, uri)) {
+        accessor.addProblem(messagePlatformPrivateLibraryAccess, charOffset,
+            noLength, accessor.fileUri);
+      }
     }
     return builder;
   }
 
   void ensureCoreLibrary() {
     if (coreLibrary == null) {
-      read(Uri.parse("dart:core"), -1);
+      read(Uri.parse("dart:core"), 0, accessor: first);
       assert(coreLibrary != null);
     }
   }
diff --git a/pkg/front_end/lib/src/fasta/parser/forwarding_listener.dart b/pkg/front_end/lib/src/fasta/parser/forwarding_listener.dart
index 0a6ea11..8ed626c 100644
--- a/pkg/front_end/lib/src/fasta/parser/forwarding_listener.dart
+++ b/pkg/front_end/lib/src/fasta/parser/forwarding_listener.dart
@@ -291,11 +291,6 @@
   }
 
   @override
-  void beginMixinApplication(Token token) {
-    listener?.beginMixinApplication(token);
-  }
-
-  @override
   void beginMixinDeclaration(Token mixinKeyword, Token name) {
     listener?.beginMixinDeclaration(mixinKeyword, name);
   }
@@ -727,13 +722,8 @@
   }
 
   @override
-  void endMixinApplication(Token withKeyword) {
-    listener?.endMixinApplication(withKeyword);
-  }
-
-  @override
-  void endMixinDeclaration(Token token) {
-    listener?.endMixinDeclaration(token);
+  void endMixinDeclaration(Token mixinKeyword, Token endToken) {
+    listener?.endMixinDeclaration(mixinKeyword, endToken);
   }
 
   @override
@@ -928,12 +918,22 @@
   }
 
   @override
+  void handleClassNoWithClause() {
+    listener?.handleClassNoWithClause();
+  }
+
+  @override
   void handleClassOrMixinImplements(
       Token implementsKeyword, int interfacesCount) {
     listener?.handleClassOrMixinImplements(implementsKeyword, interfacesCount);
   }
 
   @override
+  void handleClassWithClause(Token withKeyword) {
+    listener?.handleClassWithClause(withKeyword);
+  }
+
+  @override
   void handleCommentReference(
       Token newKeyword, Token prefix, Token period, Token token) {
     listener?.handleCommentReference(newKeyword, prefix, period, token);
@@ -1138,6 +1138,11 @@
   }
 
   @override
+  void handleNamedMixinApplicationWithClause(Token withKeyword) {
+    listener?.handleNamedMixinApplicationWithClause(withKeyword);
+  }
+
+  @override
   void handleNativeClause(Token nativeToken, bool hasName) {
     listener?.handleNativeClause(nativeToken, hasName);
   }
diff --git a/pkg/front_end/lib/src/fasta/parser/listener.dart b/pkg/front_end/lib/src/fasta/parser/listener.dart
index 0d9dfb9..f0c1b8a 100644
--- a/pkg/front_end/lib/src/fasta/parser/listener.dart
+++ b/pkg/front_end/lib/src/fasta/parser/listener.dart
@@ -111,7 +111,8 @@
   /// - modifiers
   /// - class name
   /// - type variables
-  /// - supertype (may be a mixin application)
+  /// - supertype
+  /// - with clause
   /// - implemented types
   /// - native clause
   void handleClassHeader(Token begin, Token classKeyword, Token nativeToken) {
@@ -123,7 +124,8 @@
   /// to recover information about the previous class header.
   /// The substructures are a subset of
   /// and in the same order as [handleClassHeader]:
-  /// - supertype (may be a mixin application)
+  /// - supertype
+  /// - with clause
   /// - implemented types
   void handleRecoverClassHeader() {
     logEvent("RecoverClassHeader");
@@ -169,7 +171,7 @@
   /// Handle the end of a mixin declaration.  Substructures:
   /// - mixin header
   /// - class or mixin body
-  void endMixinDeclaration(Token token) {
+  void endMixinDeclaration(Token mixinKeyword, Token endToken) {
     logEvent("MixinDeclaration");
   }
 
@@ -433,14 +435,16 @@
     logEvent("FunctionTypeAlias");
   }
 
-  void beginMixinApplication(Token token) {}
-
-  /// Handle the end of a mixin application construct (e.g. "A with B, C").
+  /// Handle the end of a with clause (e.g. "with B, C").
   /// Substructures:
-  /// - supertype
   /// - mixin types (TypeList)
-  void endMixinApplication(Token withKeyword) {
-    logEvent("MixinApplication");
+  void handleClassWithClause(Token withKeyword) {
+    logEvent("ClassWithClause");
+  }
+
+  /// Handle the absence of a with clause.
+  void handleClassNoWithClause() {
+    logEvent("ClassNoWithClause");
   }
 
   /// Handle the beginning of a named mixin application.
@@ -449,12 +453,21 @@
   void beginNamedMixinApplication(
       Token begin, Token abstractToken, Token name) {}
 
+  /// Handle a named mixin application with clause (e.g. "A with B, C").
+  /// Substructures:
+  /// - supertype
+  /// - mixin types (TypeList)
+  void handleNamedMixinApplicationWithClause(Token withKeyword) {
+    logEvent("NamedMixinApplicationWithClause");
+  }
+
   /// Handle the end of a named mixin declaration.  Substructures:
   /// - metadata
   /// - modifiers
   /// - class name
   /// - type variables
-  /// - mixin application
+  /// - supertype
+  /// - with clause
   /// - implemented types (TypeList)
   ///
   /// TODO(paulberry,ahe): it seems inconsistent that for a named mixin
diff --git a/pkg/front_end/lib/src/fasta/parser/parser.dart b/pkg/front_end/lib/src/fasta/parser/parser.dart
index 9bbe503..bb2982e 100644
--- a/pkg/front_end/lib/src/fasta/parser/parser.dart
+++ b/pkg/front_end/lib/src/fasta/parser/parser.dart
@@ -259,9 +259,6 @@
 
   bool mayParseFunctionExpressions = true;
 
-  // TODO(danrubel): remove this once mixin support is enabled by default.
-  bool isMixinSupportEnabled = false;
-
   /// Represents parser state: what asynchronous syntax is allowed in the
   /// function being currently parsed. In rare situations, this can be set by
   /// external clients, for example, to parse an expression outside a function.
@@ -580,12 +577,6 @@
         directiveState?.checkDeclaration();
         return parseTopLevelMemberImpl(start);
       } else {
-        // TODO(danrubel): Remove this once mixin support is enabled by default.
-        if (!isMixinSupportEnabled && identical(value, 'mixin')) {
-          directiveState?.checkDeclaration();
-          return parseTopLevelMemberImpl(start);
-        }
-
         parseTopLevelKeywordModifiers(start, keyword);
         if (identical(value, 'mixin')) {
           directiveState?.checkDeclaration();
@@ -1103,6 +1094,7 @@
   Token parseMixinApplicationRest(Token token) {
     Token withKeyword = token.next;
     if (!optional('with', withKeyword)) {
+      // Recovery: Report an error and insert synthetic `with` clause.
       reportRecoverableError(
           withKeyword, fasta.templateExpectedButGot.withArguments('with'));
       withKeyword =
@@ -1112,10 +1104,19 @@
         rewriter.insertSyntheticIdentifier(withKeyword);
       }
     }
-    listener.beginMixinApplication(withKeyword);
-    assert(optional('with', withKeyword));
     token = parseTypeList(withKeyword);
-    listener.endMixinApplication(withKeyword);
+    listener.handleNamedMixinApplicationWithClause(withKeyword);
+    return token;
+  }
+
+  Token parseWithClauseOpt(Token token) {
+    Token withKeyword = token.next;
+    if (optional('with', withKeyword)) {
+      token = parseTypeList(withKeyword);
+      listener.handleClassWithClause(withKeyword);
+    } else {
+      listener.handleClassNoWithClause();
+    }
     return token;
   }
 
@@ -1712,6 +1713,7 @@
 
   Token parseClassHeaderOpt(Token token, Token begin, Token classKeyword) {
     token = parseClassExtendsOpt(token);
+    token = parseWithClauseOpt(token);
     token = parseClassOrMixinImplementsOpt(token);
     Token nativeToken;
     if (optional('native', token.next)) {
@@ -1733,7 +1735,7 @@
     token = parseClassHeaderOpt(token, begin, classKeyword);
     bool hasExtends = recoveryListener.extendsKeyword != null;
     bool hasImplements = recoveryListener.implementsKeyword != null;
-    Token withKeyword = recoveryListener.withKeyword;
+    bool hasWith = recoveryListener.withKeyword != null;
 
     // Update the recovery listener to forward subsequent events
     // to the primary listener.
@@ -1751,42 +1753,29 @@
       // During recovery, clauses are parsed in the same order
       // and generate the same events as in the parseClassHeader method above.
       recoveryListener.clear();
-      Token next = token.next;
-      if (optional('with', next)) {
-        // If there is a `with` clause without a preceding `extends` clause
-        // then insert a synthetic `extends` clause and parse both clauses.
-        Token extendsKeyword =
-            new SyntheticKeywordToken(Keyword.EXTENDS, next.offset);
-        Token superclassToken = new SyntheticStringToken(
-            TokenType.IDENTIFIER, 'Object', next.offset, 0);
-        rewriter.insertTokenAfter(token, extendsKeyword);
-        rewriter.insertTokenAfter(extendsKeyword, superclassToken);
-        token = computeType(extendsKeyword, true)
-            .ensureTypeNotVoid(extendsKeyword, this);
-        token = parseMixinApplicationRest(token);
-        listener.handleClassExtends(extendsKeyword);
-      } else {
-        token = parseClassExtendsOpt(token);
 
-        if (recoveryListener.extendsKeyword != null) {
-          if (hasExtends) {
-            reportRecoverableError(
-                recoveryListener.extendsKeyword, fasta.messageMultipleExtends);
-          } else {
-            if (withKeyword != null) {
-              reportRecoverableError(recoveryListener.extendsKeyword,
-                  fasta.messageWithBeforeExtends);
-            } else if (hasImplements) {
-              reportRecoverableError(recoveryListener.extendsKeyword,
-                  fasta.messageImplementsBeforeExtends);
-            }
-            hasExtends = true;
+      token = parseClassExtendsOpt(token);
+
+      if (recoveryListener.extendsKeyword != null) {
+        if (hasExtends) {
+          reportRecoverableError(
+              recoveryListener.extendsKeyword, fasta.messageMultipleExtends);
+        } else {
+          if (hasWith) {
+            reportRecoverableError(recoveryListener.extendsKeyword,
+                fasta.messageWithBeforeExtends);
+          } else if (hasImplements) {
+            reportRecoverableError(recoveryListener.extendsKeyword,
+                fasta.messageImplementsBeforeExtends);
           }
+          hasExtends = true;
         }
       }
 
+      token = parseWithClauseOpt(token);
+
       if (recoveryListener.withKeyword != null) {
-        if (withKeyword != null) {
+        if (hasWith) {
           reportRecoverableError(
               recoveryListener.withKeyword, fasta.messageMultipleWith);
         } else {
@@ -1794,7 +1783,7 @@
             reportRecoverableError(recoveryListener.withKeyword,
                 fasta.messageImplementsBeforeWith);
           }
-          withKeyword = recoveryListener.withKeyword;
+          hasWith = true;
         }
       }
 
@@ -1814,10 +1803,6 @@
       // Exit if a class body is detected, or if no progress has been made
     } while (!optional('{', token.next) && start != token);
 
-    if (withKeyword != null && !hasExtends) {
-      reportRecoverableError(withKeyword, fasta.messageWithWithoutExtends);
-    }
-
     listener = primaryListener;
     return token;
   }
@@ -1827,11 +1812,6 @@
     if (optional('extends', next)) {
       Token extendsKeyword = next;
       token = computeType(next, true).ensureTypeNotVoid(next, this);
-      if (optional('with', token.next)) {
-        token = parseMixinApplicationRest(token);
-      } else {
-        token = token;
-      }
       listener.handleClassExtends(extendsKeyword);
     } else {
       listener.handleNoType(token);
@@ -1870,6 +1850,7 @@
   /// ```
   Token parseMixin(Token mixinKeyword) {
     assert(optional('mixin', mixinKeyword));
+    listener.beginClassOrNamedMixinApplication(mixinKeyword);
     Token name = ensureIdentifier(
         mixinKeyword, IdentifierContext.classOrMixinDeclaration);
     Token headerStart =
@@ -1882,7 +1863,7 @@
       ensureBlock(token, fasta.templateExpectedClassOrMixinBody);
     }
     token = parseClassOrMixinBody(token);
-    listener.endMixinDeclaration(token);
+    listener.endMixinDeclaration(mixinKeyword, token);
     return token;
   }
 
@@ -3875,10 +3856,18 @@
         next = token.next;
         mayParseFunctionExpressions = old;
         if (!optional(']', next)) {
-          Message message = fasta.templateExpectedButGot.withArguments(']');
-          Token newToken = new SyntheticToken(
-              TokenType.CLOSE_SQUARE_BRACKET, next.charOffset);
-          next = rewriteAndRecover(token, message, newToken).next;
+          // Recovery
+          reportRecoverableError(
+              next, fasta.templateExpectedButGot.withArguments(']'));
+          // Scanner ensures a closing ']'
+          Token endGroup = openSquareBracket.endGroup;
+          if (endGroup.isSynthetic) {
+            // Scanner inserted closing ']' in the wrong place, so move it.
+            next = rewriter.moveSynthetic(token, endGroup);
+          } else {
+            // Skip over unexpected tokens to where the user placed the `]`.
+            next = endGroup;
+          }
         }
         listener.handleIndexedExpression(openSquareBracket, next);
         token = next;
@@ -5378,7 +5367,8 @@
             if (!optional(")", traceName.next)) {
               // Recovery
               if (!traceName.isSynthetic) {
-                reportRecoverableError(exceptionName, fasta.messageCatchSyntax);
+                reportRecoverableError(
+                    traceName.next, fasta.messageCatchSyntaxExtraParameters);
               }
               if (openParens.endGroup.isSynthetic) {
                 // The scanner did not place the synthetic ')' correctly.
diff --git a/pkg/front_end/lib/src/fasta/parser/recovery_listeners.dart b/pkg/front_end/lib/src/fasta/parser/recovery_listeners.dart
index 0508ecd..c10bc98 100644
--- a/pkg/front_end/lib/src/fasta/parser/recovery_listeners.dart
+++ b/pkg/front_end/lib/src/fasta/parser/recovery_listeners.dart
@@ -18,12 +18,6 @@
   }
 
   @override
-  void endMixinApplication(Token withKeyword) {
-    this.withKeyword = withKeyword;
-    super.endMixinApplication(withKeyword);
-  }
-
-  @override
   void handleClassExtends(Token extendsKeyword) {
     this.extendsKeyword = extendsKeyword;
     super.handleClassExtends(extendsKeyword);
@@ -35,6 +29,12 @@
     this.implementsKeyword = implementsKeyword;
     super.handleClassOrMixinImplements(implementsKeyword, interfacesCount);
   }
+
+  @override
+  void handleClassWithClause(Token withKeyword) {
+    this.withKeyword = withKeyword;
+    super.handleClassWithClause(withKeyword);
+  }
 }
 
 class ImportRecoveryListener extends ForwardingListener {
diff --git a/pkg/front_end/lib/src/fasta/parser/type_info_impl.dart b/pkg/front_end/lib/src/fasta/parser/type_info_impl.dart
index a6a3a80..84d4024 100644
--- a/pkg/front_end/lib/src/fasta/parser/type_info_impl.dart
+++ b/pkg/front_end/lib/src/fasta/parser/type_info_impl.dart
@@ -699,7 +699,7 @@
       }
       token = typeInfo.skipType(next);
       next = token.next;
-      if (optional('extends', next) || optional('super', next)) {
+      if (optional('extends', next)) {
         token = computeType(next, true, inDeclaration).skipType(next);
         next = token.next;
       }
@@ -803,7 +803,7 @@
       typeStarts = typeStarts.prepend(token);
 
       next = token.next;
-      if (optional('extends', next) || optional('super', next)) {
+      if (optional('extends', next)) {
         TypeInfo typeInfo = computeType(next, true, inDeclaration);
         token = typeInfo.skipType(next);
         next = token.next;
@@ -840,12 +840,12 @@
       Token extendsOrSuper = null;
       Token next2 = token2.next;
       if (typeInfo != null) {
-        assert(optional('extends', next2) || optional('super', next2));
+        assert(optional('extends', next2));
         extendsOrSuper = next2;
-        token2 = typeInfo.ensureTypeOrVoid(next2, parser);
+        token2 = typeInfo.ensureTypeNotVoid(next2, parser);
         next2 = token2.next;
       } else {
-        assert(!optional('extends', next2) && !optional('super', next2));
+        assert(!optional('extends', next2));
         listener.handleNoType(token2);
       }
       // Type variables are "completed" in reverse order, so capture the last
diff --git a/pkg/front_end/lib/src/fasta/rewrite_severity.dart b/pkg/front_end/lib/src/fasta/rewrite_severity.dart
index 6fc8581..bd79cf0 100644
--- a/pkg/front_end/lib/src/fasta/rewrite_severity.dart
+++ b/pkg/front_end/lib/src/fasta/rewrite_severity.dart
@@ -43,18 +43,10 @@
     // sites.
     switch (path.substring(fastaPath.length + index)) {
       case "command_line.dart":
-      case "command_line_reporting.dart":
       case "deprecated_problems.dart":
       case "entry_points.dart":
       case "kernel/body_builder.dart":
-      case "kernel/expression_generator.dart":
-      case "kernel/kernel_expression_generator.dart":
-      case "kernel/kernel_expression_generator_impl.dart":
-      case "kernel/kernel_type_variable_builder.dart":
       case "source/diet_listener.dart":
-      case "source/source_library_builder.dart":
-      case "source/source_loader.dart":
-      case "source/stack_listener.dart":
         return severity;
     }
   } else if (code == msg.codeMissingExplicitTypeArguments) {
diff --git a/pkg/front_end/lib/src/fasta/source/diet_listener.dart b/pkg/front_end/lib/src/fasta/source/diet_listener.dart
index ad4a1df..763fce3 100644
--- a/pkg/front_end/lib/src/fasta/source/diet_listener.dart
+++ b/pkg/front_end/lib/src/fasta/source/diet_listener.dart
@@ -12,7 +12,6 @@
         Library,
         LibraryDependency,
         LibraryPart,
-        Node,
         TreeNode,
         VariableDeclaration;
 
@@ -34,10 +33,13 @@
 import '../fasta_codes.dart'
     show
         LocatedMessage,
+        Code,
         Message,
         messageExpectedBlockToSkip,
         templateInternalProblemNotFound;
 
+import '../ignored_parser_errors.dart' show isIgnoredParserError;
+
 import '../kernel/kernel_body_builder.dart' show KernelBodyBuilder;
 
 import '../kernel/kernel_formal_parameter_builder.dart'
@@ -52,9 +54,6 @@
 
 import '../type_inference/type_inference_engine.dart' show TypeInferenceEngine;
 
-import '../type_inference/type_inference_listener.dart'
-    show KernelTypeInferenceListener, TypeInferenceListener;
-
 import 'source_library_builder.dart' show SourceLibraryBuilder;
 
 import 'stack_listener.dart' show NullValue, StackListener;
@@ -163,8 +162,18 @@
   }
 
   @override
-  void endMixinApplication(Token withKeyword) {
-    debugEvent("MixinApplication");
+  void handleNamedMixinApplicationWithClause(Token withKeyword) {
+    debugEvent("NamedMixinApplicationWithClause");
+  }
+
+  @override
+  void handleClassWithClause(Token withKeyword) {
+    debugEvent("ClassWithClause");
+  }
+
+  @override
+  void handleClassNoWithClause() {
+    debugEvent("ClassNoWithClause");
   }
 
   @override
@@ -561,16 +570,13 @@
 
   StackListener createListener(
       ModifierBuilder builder, Scope memberScope, bool isInstanceMember,
-      [Scope formalParameterScope,
-      TypeInferenceListener<int, Node, int> listener]) {
-    listener ??= new KernelTypeInferenceListener();
+      [Scope formalParameterScope]) {
     // Note: we set thisType regardless of whether we are building a static
     // member, since that provides better error recovery.
     InterfaceType thisType = currentClass?.target?.thisType;
     var typeInferrer = library.disableTypeInference
         ? typeInferenceEngine.createDisabledTypeInferrer()
-        : typeInferenceEngine.createLocalTypeInferrer(
-            uri, listener, thisType, library);
+        : typeInferenceEngine.createLocalTypeInferrer(uri, thisType, library);
     ConstantContext constantContext = builder.isConstructor && builder.isConst
         ? ConstantContext.inferred
         : ConstantContext.none;
@@ -686,6 +692,12 @@
   }
 
   @override
+  void endMixinDeclaration(Token mixinKeyword, Token endToken) {
+    debugEvent("MixinDeclaration");
+    checkEmpty(mixinKeyword.charOffset);
+  }
+
+  @override
   void endEnum(Token enumKeyword, Token leftBrace, int count) {
     debugEvent("Enum");
 
@@ -909,4 +921,10 @@
     }
     return result;
   }
+
+  @override
+  bool isIgnoredError(Code code, Token token) {
+    return isIgnoredParserError(code, token) ||
+        super.isIgnoredError(code, token);
+  }
 }
diff --git a/pkg/front_end/lib/src/fasta/source/outline_builder.dart b/pkg/front_end/lib/src/fasta/source/outline_builder.dart
index 8bbedb6..96e5a23 100644
--- a/pkg/front_end/lib/src/fasta/source/outline_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/outline_builder.dart
@@ -6,16 +6,17 @@
 
 import 'package:kernel/ast.dart' show ProcedureKind;
 
-import '../../scanner/token.dart' show Token;
-
 import '../builder/builder.dart';
 
 import '../builder/metadata_builder.dart' show ExpressionMetadataBuilder;
 
 import '../combinator.dart' show Combinator;
 
+import '../configuration.dart' show Configuration;
+
 import '../fasta_codes.dart'
     show
+        Code,
         LocatedMessage,
         Message,
         messageConstConstructorWithBody,
@@ -36,6 +37,16 @@
         templateOperatorParameterMismatch1,
         templateOperatorParameterMismatch2;
 
+import '../ignored_parser_errors.dart' show isIgnoredParserError;
+
+// TODO(ahe): The outline isn't supposed to import kernel-specific builders.
+import '../kernel/kernel_builder.dart'
+    show
+        KernelFormalParameterBuilder,
+        KernelMixinApplicationBuilder,
+        KernelNamedTypeBuilder,
+        KernelTypeBuilder;
+
 import '../modifier.dart'
     show
         Const,
@@ -72,18 +83,12 @@
 
 import '../quote.dart' show unescapeString;
 
+import '../scanner.dart' show Token;
+
 import 'source_library_builder.dart' show SourceLibraryBuilder;
 
 import 'stack_listener.dart' show NullValue, StackListener;
 
-import '../configuration.dart' show Configuration;
-
-import '../kernel/kernel_builder.dart'
-    show
-        KernelFormalParameterBuilder,
-        KernelNamedTypeBuilder,
-        KernelTypeBuilder;
-
 enum MethodBody {
   Abstract,
   Regular,
@@ -416,6 +421,17 @@
   }
 
   @override
+  void beginMixinDeclaration(Token mixinKeyword, Token name) {
+    debugEvent("beginMixinDeclaration");
+    List<TypeVariableBuilder> typeVariables = pop();
+    push(typeVariables ?? NullValue.TypeVariables);
+    library.currentDeclaration
+      ..name = name.lexeme
+      ..charOffset = name.charOffset
+      ..typeVariables = typeVariables;
+  }
+
+  @override
   void beginNamedMixinApplication(
       Token begin, Token abstractToken, Token name) {
     debugEvent("beginNamedMixinApplication");
@@ -448,12 +464,29 @@
   }
 
   @override
+  void handleRecoverMixinHeader() {
+    debugEvent("handleRecoverMixinHeader");
+    pop(NullValue.TypeBuilderList); // Interfaces.
+    pop(NullValue.TypeBuilderList); // Supertype constraints.
+  }
+
+  @override
   void handleClassExtends(Token extendsKeyword) {
     debugEvent("handleClassExtends");
     push(extendsKeyword?.charOffset ?? -1);
   }
 
   @override
+  void handleMixinOn(Token onKeyword, int typeCount) {
+    debugEvent("handleMixinOn");
+    var supertypeConstraints = new List<KernelNamedTypeBuilder>.filled(
+        typeCount, null,
+        growable: true);
+    popList(typeCount, supertypeConstraints);
+    push(supertypeConstraints);
+  }
+
+  @override
   void endClassDeclaration(Token beginToken, Token endToken) {
     debugEvent("endClassDeclaration");
     String documentationComment = getDocumentationComment(beginToken);
@@ -487,6 +520,43 @@
     checkEmpty(beginToken.charOffset);
   }
 
+  @override
+  void endMixinDeclaration(Token mixinToken, Token endToken) {
+    debugEvent("endMixinDeclaration");
+    String documentationComment = getDocumentationComment(mixinToken);
+    List<TypeBuilder> interfaces = pop(NullValue.TypeBuilderList);
+    List<KernelTypeBuilder> supertypeConstraints = pop();
+    List<TypeVariableBuilder> typeVariables = pop(NullValue.TypeVariables);
+    int nameOffset = pop();
+    String name = pop();
+    List<MetadataBuilder> metadata = pop(NullValue.Metadata);
+    int startOffset =
+        metadata == null ? mixinToken.charOffset : metadata.first.charOffset;
+
+    TypeBuilder supertype;
+    if (supertypeConstraints != null && supertypeConstraints.isNotEmpty) {
+      if (supertypeConstraints.length == 1) {
+        supertype = supertypeConstraints.first;
+      } else {
+        supertype = new KernelMixinApplicationBuilder(
+            supertypeConstraints.first, supertypeConstraints.skip(1).toList());
+      }
+    }
+    library.addClass(
+        documentationComment,
+        metadata,
+        abstractMask,
+        name,
+        typeVariables,
+        supertype,
+        interfaces,
+        startOffset,
+        nameOffset,
+        endToken.charOffset,
+        -1);
+    checkEmpty(mixinToken.charOffset);
+  }
+
   ProcedureKind computeProcedureKind(Token token) {
     if (token == null) return ProcedureKind.Method;
     if (optional("get", token)) return ProcedureKind.Getter;
@@ -765,8 +835,8 @@
   }
 
   @override
-  void endMixinApplication(Token withKeyword) {
-    debugEvent("MixinApplication");
+  void handleNamedMixinApplicationWithClause(Token withKeyword) {
+    debugEvent("NamedMixinApplicationWithClause");
     List<TypeBuilder> mixins = pop();
     TypeBuilder supertype = pop();
     push(
@@ -888,10 +958,10 @@
     // 0. It might be simpler if the parser didn't call this method in that
     // case, however, then [beginOptionalFormalParameters] wouldn't always be
     // matched by this method.
-    var parameters = new List<KernelFormalParameterBuilder>.filled(count, null,
-        growable: true);
+    List<KernelFormalParameterBuilder> parameters =
+        new List<KernelFormalParameterBuilder>(count);
     popList(count, parameters);
-    for (FormalParameterBuilder parameter in parameters) {
+    for (KernelFormalParameterBuilder parameter in parameters) {
       parameter.kind = kind;
     }
     push(parameters);
@@ -1328,12 +1398,36 @@
   }
 
   @override
+  void handleClassWithClause(Token withKeyword) {
+    debugEvent("ClassWithClause");
+
+    List<TypeBuilder> mixins = pop();
+    int extendsOffset = pop();
+    TypeBuilder supertype = pop();
+
+    push(
+        library.addMixinApplication(supertype, mixins, withKeyword.charOffset));
+    push(extendsOffset);
+  }
+
+  @override
+  void handleClassNoWithClause() {
+    debugEvent("ClassNoWithClause");
+  }
+
+  @override
   void handleClassHeader(Token begin, Token classKeyword, Token nativeToken) {
     debugEvent("ClassHeader");
     nativeMethodName = null;
   }
 
   @override
+  void handleMixinHeader(Token mixinKeyword) {
+    debugEvent("handleMixinHeader");
+    nativeMethodName = null;
+  }
+
+  @override
   void endClassOrMixinBody(int memberCount, Token beginToken, Token endToken) {
     debugEvent("ClassOrMixinBody");
   }
@@ -1349,6 +1443,12 @@
         wasHandled: wasHandled, context: context);
   }
 
+  @override
+  bool isIgnoredError(Code code, Token token) {
+    return isIgnoredParserError(code, token) ||
+        super.isIgnoredError(code, token);
+  }
+
   /// Return the documentation comment for the entity that starts at the
   /// given [token], or `null` if there is no preceding documentation comment.
   static String getDocumentationComment(Token token) {
diff --git a/pkg/front_end/lib/src/fasta/source/source_library_builder.dart b/pkg/front_end/lib/src/fasta/source/source_library_builder.dart
index a96b82c..7d81a1a 100644
--- a/pkg/front_end/lib/src/fasta/source/source_library_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_library_builder.dart
@@ -34,15 +34,19 @@
 
 import '../combinator.dart' show Combinator;
 
-import '../deprecated_problems.dart' show deprecated_inputError;
-
 import '../export.dart' show Export;
 
 import '../fasta_codes.dart'
     show
+        LocatedMessage,
+        Message,
         messageConstructorWithWrongName,
         messageExpectedUri,
         messageMemberWithSameNameAsClass,
+        messagePartExport,
+        messagePartExportContext,
+        messagePartInPart,
+        messagePartInPartLibraryContext,
         messagePartOfSelf,
         messagePartOfTwoLibraries,
         messagePartOfTwoLibrariesContext,
@@ -83,6 +87,9 @@
 
   final List<SourceLibraryBuilder<T, R>> parts = <SourceLibraryBuilder<T, R>>[];
 
+  // Can I use library.parts instead? See KernelLibraryBuilder.addPart.
+  final List<int> partOffsets = <int>[];
+
   final List<Import> imports = <Import>[];
 
   final List<Export> exports = <Export>[];
@@ -98,6 +105,8 @@
   @override
   final bool disableTypeInference;
 
+  final List<Object> accessors = <Object>[];
+
   String documentationComment;
 
   String name;
@@ -116,6 +125,10 @@
 
   bool canAddImplementationBuilders = false;
 
+  /// Non-null if this library causes an error upon access, that is, there was
+  /// an error reading its source.
+  Message accessProblem;
+
   SourceLibraryBuilder(SourceLoader loader, Uri fileUri, Scope scope)
       : this.fromScopes(loader, fileUri, new DeclarationBuilder<T>.library(),
             scope ?? new Scope.top());
@@ -134,6 +147,9 @@
 
   List<UnresolvedType<T>> get types => libraryDeclaration.types;
 
+  @override
+  bool get isSynthetic => accessProblem != null;
+
   T addNamedType(Object name, List<T> arguments, int charOffset);
 
   T addMixinApplication(T supertype, List<T> mixins, int charOffset);
@@ -308,7 +324,7 @@
       }
     } else {
       resolvedUri = resolve(this.uri, uri, uriOffset);
-      builder = loader.read(resolvedUri, charOffset, accessor: this);
+      builder = loader.read(resolvedUri, uriOffset, accessor: this);
     }
 
     imports.add(new Import(this, builder, deferred, prefix, combinators,
@@ -323,6 +339,7 @@
     newFileUri = resolve(fileUri, uri, charOffset);
     parts.add(loader.read(resolvedUri, charOffset,
         fileUri: newFileUri, accessor: this));
+    partOffsets.add(charOffset);
   }
 
   void addPartOf(
@@ -580,19 +597,36 @@
     implementationBuilders.add([name, declaration, charOffset]);
   }
 
-  void validatePart() {
-    if (parts.isNotEmpty) {
-      deprecated_inputError(fileUri, -1,
-          "A file that's a part of a library can't have parts itself.");
+  void validatePart(SourceLibraryBuilder library, Set<Uri> usedParts) {
+    if (library != null && parts.isNotEmpty) {
+      // If [library] is null, we have already reported a problem that this
+      // part is orphaned.
+      List<LocatedMessage> context = <LocatedMessage>[
+        messagePartInPartLibraryContext.withLocation(library.fileUri, 0, 1),
+      ];
+      for (int offset in partOffsets) {
+        addProblem(messagePartInPart, offset, noLength, fileUri,
+            context: context);
+      }
+      for (SourceLibraryBuilder part in parts) {
+        // Mark this part as used so we don't report it as orphaned.
+        usedParts.add(part.uri);
+      }
     }
+    parts.clear();
     if (exporters.isNotEmpty) {
-      Export export = exporters.first;
-      deprecated_inputError(
-          export.fileUri, export.charOffset, "A part can't be exported.");
+      List<LocatedMessage> context = <LocatedMessage>[
+        messagePartExportContext.withLocation(fileUri, 0, 1),
+      ];
+      for (Export export in exporters) {
+        export.exporter.addProblem(
+            messagePartExport, export.charOffset, "export".length, null,
+            context: context);
+      }
     }
   }
 
-  void includeParts() {
+  void includeParts(Set<Uri> usedParts) {
     Set<Uri> seenParts = new Set<Uri>();
     for (SourceLibraryBuilder<T, R> part in parts) {
       if (part == this) {
@@ -607,7 +641,8 @@
                     this.fileUri, -1, noLength)
               ]);
         } else {
-          includePart(part);
+          usedParts.add(part.uri);
+          includePart(part, usedParts);
         }
       } else {
         addProblem(templatePartTwice.withArguments(part.fileUri), -1, noLength,
@@ -616,7 +651,7 @@
     }
   }
 
-  void includePart(SourceLibraryBuilder<T, R> part) {
+  void includePart(SourceLibraryBuilder<T, R> part, Set<Uri> usedParts) {
     if (part.partOfUri != null) {
       if (uriIsValid(part.partOfUri) && part.partOfUri != uri) {
         // This is a warning, but the part is still included.
@@ -656,6 +691,7 @@
             noLength, fileUri);
       }
     }
+    part.validatePart(this, usedParts);
     part.forEach((String name, Declaration declaration) {
       if (declaration.next != null) {
         // TODO(ahe): This shouldn't be necessary as setters have been added to
@@ -759,6 +795,33 @@
       member.instrumentTopLevelInference(instrumentation);
     });
   }
+
+  @override
+  void recordAccess(int charOffset, int length, Uri fileUri) {
+    accessors.add(fileUri);
+    accessors.add(charOffset);
+    accessors.add(length);
+    if (accessProblem != null) {
+      addProblem(accessProblem, charOffset, length, fileUri);
+    }
+  }
+
+  void addProblemAtAccessors(Message message) {
+    if (accessProblem == null) {
+      if (accessors.isEmpty && this == loader.first) {
+        // This is the entry point library, and nobody access it directly. So
+        // we need to report a problem.
+        loader.addProblem(message, -1, 1, null);
+      }
+      for (int i = 0; i < accessors.length; i += 3) {
+        Uri accessor = accessors[i];
+        int charOffset = accessors[i + 1];
+        int length = accessors[i + 2];
+        addProblem(message, charOffset, length, accessor);
+      }
+      accessProblem = message;
+    }
+  }
 }
 
 /// Unlike [Scope], this scope is used during construction of builders to
diff --git a/pkg/front_end/lib/src/fasta/source/source_loader.dart b/pkg/front_end/lib/src/fasta/source/source_loader.dart
index 9f48ebd..d318a5a 100644
--- a/pkg/front_end/lib/src/fasta/source/source_loader.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_loader.dart
@@ -6,6 +6,8 @@
 
 import 'dart:async' show Future;
 
+import 'dart:convert' show utf8;
+
 import 'dart:typed_data' show Uint8List;
 
 import 'package:kernel/ast.dart'
@@ -45,18 +47,18 @@
         NamedTypeBuilder,
         TypeBuilder;
 
-import '../deprecated_problems.dart' show deprecated_inputError;
-
 import '../export.dart' show Export;
 
 import '../fasta_codes.dart'
     show
         LocatedMessage,
         Message,
-        noLength,
         SummaryTemplate,
         Template,
+        messagePartOrphan,
+        noLength,
         templateAmbiguousSupertypes,
+        templateCantReadFile,
         templateCyclicClassHierarchy,
         templateExtendingEnum,
         templateExtendingRestricted,
@@ -64,7 +66,8 @@
         templateIllegalMixinDueToConstructors,
         templateIllegalMixinDueToConstructorsCause,
         templateInternalProblemUriMissingScheme,
-        templateSourceOutlineSummary;
+        templateSourceOutlineSummary,
+        templateUntranslatableUri;
 
 import '../fasta_codes.dart' as fasta_codes;
 
@@ -77,13 +80,13 @@
 
 import '../kernel/body_builder.dart' show BodyBuilder;
 
-import '../loader.dart' show Loader;
+import '../loader.dart' show Loader, untranslatableUriScheme;
 
 import '../parser/class_member_parser.dart' show ClassMemberParser;
 
 import '../parser.dart' show Parser, lengthForToken, offsetForToken;
 
-import '../problems.dart' show internalProblem, unhandled;
+import '../problems.dart' show internalProblem, unexpected, unhandled;
 
 import '../scanner.dart' show ErrorToken, ScannerResult, Token, scan;
 
@@ -138,37 +141,55 @@
   Template<SummaryTemplate> get outlineSummaryTemplate =>
       templateSourceOutlineSummary;
 
+  bool get isSourceLoader => true;
+
   Future<Token> tokenize(SourceLibraryBuilder library,
       {bool suppressLexicalErrors: false}) async {
     Uri uri = library.fileUri;
-    if (uri == null) {
-      return deprecated_inputError(
-          library.uri, -1, "Not found: ${library.uri}.");
-    } else if (!uri.hasScheme) {
-      return internalProblem(
-          templateInternalProblemUriMissingScheme.withArguments(uri),
-          -1,
-          library.uri);
-    } else if (uri.scheme == SourceLibraryBuilder.MALFORMED_URI_SCHEME) {
-      // Simulate empty file
-      return null;
-    }
 
-    // Get the library text from the cache, or read from the file system.
+    // Lookup the file URI in the cache.
     List<int> bytes = sourceBytes[uri];
+
     if (bytes == null) {
-      try {
-        List<int> rawBytes = await fileSystem.entityForUri(uri).readAsBytes();
-        Uint8List zeroTerminatedBytes = new Uint8List(rawBytes.length + 1);
-        zeroTerminatedBytes.setRange(0, rawBytes.length, rawBytes);
+      // Error recovery.
+      if (uri.scheme == untranslatableUriScheme) {
+        Message message = templateUntranslatableUri.withArguments(library.uri);
+        library.addProblemAtAccessors(message);
+        bytes = synthesizeSourceForMissingFile(library.uri, null);
+      } else if (!uri.hasScheme) {
+        return internalProblem(
+            templateInternalProblemUriMissingScheme.withArguments(uri),
+            -1,
+            library.uri);
+      } else if (uri.scheme == SourceLibraryBuilder.MALFORMED_URI_SCHEME) {
+        bytes = synthesizeSourceForMissingFile(library.uri, null);
+      }
+      if (bytes != null) {
+        Uint8List zeroTerminatedBytes = new Uint8List(bytes.length + 1);
+        zeroTerminatedBytes.setRange(0, bytes.length, bytes);
         bytes = zeroTerminatedBytes;
         sourceBytes[uri] = bytes;
-        byteCount += rawBytes.length;
-      } on FileSystemException catch (e) {
-        return deprecated_inputError(uri, -1, e.message);
       }
     }
 
+    if (bytes == null) {
+      // If it isn't found in the cache, read the file read from the file
+      // system.
+      List<int> rawBytes;
+      try {
+        rawBytes = await fileSystem.entityForUri(uri).readAsBytes();
+      } on FileSystemException catch (e) {
+        Message message = templateCantReadFile.withArguments(uri, e.message);
+        library.addProblemAtAccessors(message);
+        rawBytes = synthesizeSourceForMissingFile(library.uri, message);
+      }
+      Uint8List zeroTerminatedBytes = new Uint8List(rawBytes.length + 1);
+      zeroTerminatedBytes.setRange(0, rawBytes.length, rawBytes);
+      bytes = zeroTerminatedBytes;
+      sourceBytes[uri] = bytes;
+      byteCount += rawBytes.length;
+    }
+
     ScannerResult result = scan(bytes, includeComments: includeComments);
     Token token = result.tokens;
     if (!suppressLexicalErrors) {
@@ -186,6 +207,19 @@
     return token;
   }
 
+  List<int> synthesizeSourceForMissingFile(Uri uri, Message message) {
+    switch ("$uri") {
+      case "dart:core":
+        return utf8.encode(defaultDartCoreSource);
+
+      case "dart:async":
+        return utf8.encode(defaultDartAsyncSource);
+
+      default:
+        return utf8.encode(message == null ? "" : "/* ${message.message} */");
+    }
+  }
+
   List<int> getSource(List<int> bytes) {
     // bytes is 0-terminated. We don't want that included.
     if (bytes is Uint8List) {
@@ -267,18 +301,29 @@
 
   void resolveParts() {
     List<Uri> parts = <Uri>[];
+    List<SourceLibraryBuilder> libraries = <SourceLibraryBuilder>[];
     builders.forEach((Uri uri, LibraryBuilder library) {
       if (library.loader == this) {
-        SourceLibraryBuilder sourceLibrary = library;
-        if (sourceLibrary.isPart) {
-          sourceLibrary.validatePart();
+        if (library.isPart) {
           parts.add(uri);
         } else {
-          sourceLibrary.includeParts();
+          libraries.add(library);
         }
       }
     });
-    parts.forEach(builders.remove);
+    Set<Uri> usedParts = new Set<Uri>();
+    for (SourceLibraryBuilder library in libraries) {
+      library.includeParts(usedParts);
+    }
+    for (Uri uri in parts) {
+      if (usedParts.contains(uri)) {
+        builders.remove(uri);
+      } else {
+        SourceLibraryBuilder part = builders[uri];
+        part.addProblem(messagePartOrphan, 0, 1, part.fileUri);
+        part.validatePart(null, null);
+      }
+    }
     ticker.logMs("Resolved parts");
 
     builders.forEach((Uri uri, LibraryBuilder library) {
@@ -612,7 +657,7 @@
       if (library.loader == this) {
         SourceLibraryBuilder sourceLibrary = library;
         L target = sourceLibrary.build(coreLibrary);
-        if (!library.isPatch) {
+        if (!library.isPatch && !library.isSynthetic) {
           libraries.add(target);
         }
       }
@@ -624,8 +669,7 @@
     Set<Library> libraries = new Set<Library>();
     List<Library> workList = <Library>[];
     builders.forEach((Uri uri, LibraryBuilder library) {
-      if (!library.isPart &&
-          !library.isPatch &&
+      if (!library.isPatch &&
           (library.loader == this || library.fileUri.scheme == "dart")) {
         if (libraries.add(library.target)) {
           workList.add(library.target);
@@ -791,6 +835,9 @@
         result[i++] = ShadowClass.getClassInferenceInfo(cls).builder
           ..prepareTopLevelInference();
       }
+      if (i != result.length) {
+        unexpected("${result.length}", "$i", -1, null);
+      }
       orderedClasses = result;
     }
     typeInferenceEngine.isTypeInferencePrepared = true;
@@ -947,3 +994,117 @@
     typeInferenceEngine = null;
   }
 }
+
+const String defaultDartCoreSource = """
+import 'dart:_internal';
+import 'dart:async';
+
+print(object) {}
+
+class Iterator {}
+
+class Iterable {}
+
+class List extends Iterable {
+  factory List.unmodifiable(elements) => null;
+}
+
+class Map extends Iterable {
+  factory Map.unmodifiable(other) => null;
+}
+
+class NoSuchMethodError {
+  NoSuchMethodError.withInvocation(receiver, invocation);
+}
+
+class Null {}
+
+class Object {
+  noSuchMethod(invocation) => null;
+}
+
+class String {}
+
+class Symbol {}
+
+class Type {}
+
+class _InvocationMirror {
+  _InvocationMirror._withType(_memberName, _type, _typeArguments,
+      _positionalArguments, _namedArguments);
+}
+
+class bool {}
+
+class double extends num {}
+
+class int extends num {}
+
+class num {}
+
+class _SyncIterable {}
+
+class _SyncIterator {
+  var _current;
+  var _yieldEachIterable;
+}
+""";
+
+const String defaultDartAsyncSource = """
+_asyncErrorWrapperHelper(continuation) {}
+
+_asyncStackTraceHelper(async_op) {}
+
+_asyncThenWrapperHelper(continuation) {}
+
+_awaitHelper(object, thenCallback, errorCallback, awaiter) {}
+
+_completeOnAsyncReturn(completer, value) {}
+
+class _AsyncStarStreamController {
+  add(event) {}
+
+  addError(error, stackTrace) {}
+
+  addStream(stream) {}
+
+  close() {}
+
+  get stream => null;
+}
+
+class Completer {
+  factory Completer.sync() => null;
+
+  get future;
+
+  complete([value]);
+
+  completeError(error, [stackTrace]);
+}
+
+class Future {
+  factory Future.microtask(computation) => null;
+}
+
+class FutureOr {
+}
+
+class _AsyncAwaitCompleter implements Completer {
+  get future => null;
+
+  complete([value]) {}
+
+  completeError(error, [stackTrace]) {}
+}
+
+class Stream {}
+
+class _StreamIterator {
+  get current => null;
+
+  moveNext() {}
+
+  cancel() {}
+}
+""";
diff --git a/pkg/front_end/lib/src/fasta/source/stack_listener.dart b/pkg/front_end/lib/src/fasta/source/stack_listener.dart
index cd41814..e388982 100644
--- a/pkg/front_end/lib/src/fasta/source/stack_listener.dart
+++ b/pkg/front_end/lib/src/fasta/source/stack_listener.dart
@@ -9,9 +9,11 @@
 
 import '../fasta_codes.dart'
     show
+        Code,
         LocatedMessage,
         Message,
-        messageNativeClauseShouldBeAnnotation,
+        codeCatchSyntaxExtraParameters,
+        codeNativeClauseShouldBeAnnotation,
         templateInternalProblemStackNotEmpty;
 
 import '../parser.dart'
@@ -195,16 +197,31 @@
   }
 
   @override
+  void handleMixinOn(Token onKeyword, int typeCount) {
+    debugEvent("MixinOn");
+  }
+
+  @override
   void handleClassHeader(Token begin, Token classKeyword, Token nativeToken) {
     debugEvent("ClassHeader");
   }
 
   @override
+  void handleMixinHeader(Token mixinKeyword) {
+    debugEvent("MixinHeader");
+  }
+
+  @override
   void handleRecoverClassHeader() {
     debugEvent("RecoverClassHeader");
   }
 
   @override
+  void handleRecoverMixinHeader() {
+    debugEvent("RecoverMixinHeader");
+  }
+
+  @override
   void handleClassOrMixinImplements(
       Token implementsKeyword, int interfacesCount) {
     debugEvent("ClassImplements");
@@ -339,15 +356,25 @@
   @override
   void handleRecoverableError(
       Message message, Token startToken, Token endToken) {
-    if (message == messageNativeClauseShouldBeAnnotation) {
-      // TODO(danrubel): Ignore this error until we deprecate `native` support.
-      return;
-    }
     debugEvent("Error: ${message.message}");
+    if (isIgnoredError(message.code, startToken)) return;
     addProblem(message, offsetForToken(startToken),
         lengthOfSpan(startToken, endToken));
   }
 
+  bool isIgnoredError(Code code, Token token) {
+    if (code == codeNativeClauseShouldBeAnnotation) {
+      // TODO(danrubel): Ignore this error until we deprecate `native`
+      // support.
+      return true;
+    } else if (code == codeCatchSyntaxExtraParameters) {
+      // Ignored. This error is handled by the BodyBuilder.
+      return true;
+    } else {
+      return false;
+    }
+  }
+
   @override
   void handleUnescapeError(
       Message message, Token token, int stringOffset, int length) {
diff --git a/pkg/front_end/lib/src/fasta/target_implementation.dart b/pkg/front_end/lib/src/fasta/target_implementation.dart
index 3361321..08581aa 100644
--- a/pkg/front_end/lib/src/fasta/target_implementation.dart
+++ b/pkg/front_end/lib/src/fasta/target_implementation.dart
@@ -94,13 +94,14 @@
   /// type String, which is the name of the native method.
   Declaration getNativeAnnotation(Loader loader) {
     if (cachedNativeAnnotation != null) return cachedNativeAnnotation;
-    LibraryBuilder internal = loader.read(Uri.parse("dart:_internal"), -1);
+    LibraryBuilder internal = loader.read(Uri.parse("dart:_internal"), -1,
+        accessor: loader.coreLibrary);
     return cachedNativeAnnotation = internal.getConstructor("ExternalName");
   }
 
   void loadExtraRequiredLibraries(Loader loader) {
     for (String uri in backendTarget.extraRequiredLibraries) {
-      loader.read(Uri.parse(uri), -1);
+      loader.read(Uri.parse(uri), 0, accessor: loader.coreLibrary);
     }
   }
 
diff --git a/pkg/front_end/lib/src/fasta/testing/kernel_chain.dart b/pkg/front_end/lib/src/fasta/testing/kernel_chain.dart
index 81ce898..b7132d0 100644
--- a/pkg/front_end/lib/src/fasta/testing/kernel_chain.dart
+++ b/pkg/front_end/lib/src/fasta/testing/kernel_chain.dart
@@ -2,9 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE.md file.
 
-// TODO(ahe): Copied from closure_conversion branch of kernel, remove this file
-// when closure_conversion is merged with master.
-
 library fasta.testing.kernel_chain;
 
 import 'dart:async' show Future;
@@ -33,14 +30,18 @@
 import 'package:testing/testing.dart'
     show ChainContext, Result, StdioProcess, Step, TestDescription;
 
-import '../../api_prototype/front_end.dart';
+import '../../api_prototype/compilation_message.dart' show CompilationMessage;
+
+import '../../api_prototype/compiler_options.dart' show CompilerOptions;
+
+import '../../api_prototype/kernel_generator.dart' show kernelForProgram;
 
 import '../../base/processed_options.dart' show ProcessedOptions;
 
 import '../../compute_platform_binaries_location.dart'
     show computePlatformBinariesLocation;
 
-import '../compiler_context.dart';
+import '../compiler_context.dart' show CompilerContext;
 
 import '../kernel/verifier.dart' show verifyComponent;
 
diff --git a/pkg/front_end/lib/src/fasta/type_inference/type_inference_engine.dart b/pkg/front_end/lib/src/fasta/type_inference/type_inference_engine.dart
index 48d0b20..6dab19c 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/type_inference_engine.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/type_inference_engine.dart
@@ -10,12 +10,13 @@
         DynamicType,
         FunctionType,
         InterfaceType,
-        Node,
         TypeParameter,
         TypeParameterType,
         TypedefType,
         VariableDeclaration;
+
 import 'package:kernel/class_hierarchy.dart';
+
 import 'package:kernel/core_types.dart';
 
 import '../../base/instrumentation.dart';
@@ -28,8 +29,6 @@
 
 import '../source/source_library_builder.dart';
 
-import 'type_inference_listener.dart' show TypeInferenceListener;
-
 import 'type_inferrer.dart';
 
 import 'type_schema_environment.dart';
@@ -239,17 +238,12 @@
   /// Creates a type inferrer for use inside of a method body declared in a file
   /// with the given [uri].
   TypeInferrer createLocalTypeInferrer(
-      Uri uri,
-      TypeInferenceListener<int, Node, int> listener,
-      InterfaceType thisType,
-      SourceLibraryBuilder library);
+      Uri uri, InterfaceType thisType, SourceLibraryBuilder library);
 
   /// Creates a [TypeInferrer] object which is ready to perform type inference
   /// on the given [field].
   TypeInferrer createTopLevelTypeInferrer(
-      TypeInferenceListener<int, Node, int> listener,
-      InterfaceType thisType,
-      ShadowField field);
+      InterfaceType thisType, ShadowField field);
 
   /// Retrieve the [TypeInferrer] for the given [field], which was created by
   /// a previous call to [createTopLevelTypeInferrer].
diff --git a/pkg/front_end/lib/src/fasta/type_inference/type_inference_listener.dart b/pkg/front_end/lib/src/fasta/type_inference/type_inference_listener.dart
deleted file mode 100644
index 68a2f7a..0000000
--- a/pkg/front_end/lib/src/fasta/type_inference/type_inference_listener.dart
+++ /dev/null
@@ -1,1200 +0,0 @@
-// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE.md file.
-
-import 'package:kernel/ast.dart'
-    show Catch, DartType, FunctionType, Node, TypeParameter;
-import 'package:kernel/ast.dart' show Catch, DartType, FunctionType, Node;
-import 'package:kernel/type_algebra.dart' show Substitution;
-
-import '../../scanner/token.dart' show Token;
-import '../kernel/kernel_shadow_ast.dart'
-    show
-        ExpressionJudgment,
-        InitializerJudgment,
-        LoadLibraryJudgment,
-        LoadLibraryTearOffJudgment,
-        StatementJudgment,
-        SwitchCaseJudgment;
-import '../kernel/kernel_type_variable_builder.dart'
-    show KernelTypeVariableBuilder;
-
-class AsExpressionTokens {
-  final Token asOperator;
-
-  AsExpressionTokens(this.asOperator);
-}
-
-class AssertInitializerTokens {
-  final Token assertKeyword;
-  final Token leftParenthesis;
-  final Token comma;
-  final Token rightParenthesis;
-
-  AssertInitializerTokens(this.assertKeyword, this.leftParenthesis, this.comma,
-      this.rightParenthesis);
-}
-
-class AssertStatementTokens {
-  final Token assertKeyword;
-  final Token leftParenthesis;
-  final Token comma;
-  final Token rightParenthesis;
-  final Token semicolon;
-
-  AssertStatementTokens(this.assertKeyword, this.leftParenthesis, this.comma,
-      this.rightParenthesis, this.semicolon);
-}
-
-class AwaitExpressionTokens {
-  final Token awaitKeyword;
-
-  AwaitExpressionTokens(this.awaitKeyword);
-}
-
-class BlockTokens {
-  final Token leftBracket;
-  final Token rightBracket;
-
-  BlockTokens(this.leftBracket, this.rightBracket);
-}
-
-class BoolLiteralTokens {
-  final Token literal;
-
-  BoolLiteralTokens(this.literal);
-}
-
-class BreakStatementTokens {
-  final Token breakKeyword;
-  final Token semicolon;
-
-  BreakStatementTokens(this.breakKeyword, this.semicolon);
-}
-
-class ContinueStatementTokens {
-  final Token continueKeyword;
-  final Token semicolon;
-
-  ContinueStatementTokens(this.continueKeyword, this.semicolon);
-}
-
-class ConditionalExpressionTokens {
-  final Token question;
-  final Token colon;
-
-  ConditionalExpressionTokens(this.question, this.colon);
-}
-
-class ContinueSwitchStatementTokens {
-  final Token continueKeyword;
-  final Token semicolon;
-
-  ContinueSwitchStatementTokens(this.continueKeyword, this.semicolon);
-}
-
-class DoStatementTokens {
-  final Token doKeyword;
-  final Token whileKeyword;
-  final Token leftParenthesis;
-  final Token rightParenthesis;
-  final Token semicolon;
-
-  DoStatementTokens(this.doKeyword, this.whileKeyword, this.leftParenthesis,
-      this.rightParenthesis, this.semicolon);
-}
-
-class DoubleLiteralTokens {
-  final Token literal;
-
-  DoubleLiteralTokens(this.literal);
-}
-
-class EmptyStatementTokens {
-  final Token semicolon;
-
-  EmptyStatementTokens(this.semicolon);
-}
-
-class ExpressionStatementTokens {
-  final Token semicolon;
-
-  ExpressionStatementTokens(this.semicolon);
-}
-
-class ForInStatementTokens {
-  final Token awaitKeyword;
-  final Token forKeyword;
-  final Token leftParenthesis;
-  final Token inKeyword;
-  final Token rightParenthesis;
-
-  ForInStatementTokens(this.awaitKeyword, this.forKeyword, this.leftParenthesis,
-      this.inKeyword, this.rightParenthesis);
-}
-
-class ForStatementTokens {
-  final Token forKeyword;
-  final Token leftParenthesis;
-  final Token leftSeparator;
-  final Token rightSeparator;
-  final Token rightParenthesis;
-
-  ForStatementTokens(this.forKeyword, this.leftParenthesis, this.leftSeparator,
-      this.rightSeparator, this.rightParenthesis);
-}
-
-class IfNullTokens {
-  final Token operator;
-
-  IfNullTokens(this.operator);
-}
-
-class IfStatementTokens {
-  final Token ifKeyword;
-  final Token leftParenthesis;
-  final Token rightParenthesis;
-  final Token elseKeyword;
-
-  IfStatementTokens(this.ifKeyword, this.leftParenthesis, this.rightParenthesis,
-      this.elseKeyword);
-}
-
-class IntLiteralTokens {
-  final Token literal;
-
-  IntLiteralTokens(this.literal);
-}
-
-class IsExpressionTokens {
-  final Token isOperator;
-
-  IsExpressionTokens(this.isOperator);
-}
-
-class IsNotExpressionTokens {
-  final Token isOperator;
-  final Token notOperator;
-
-  IsNotExpressionTokens(this.isOperator, this.notOperator);
-}
-
-class ListLiteralTokens {
-  final Token constKeyword;
-  final Token leftBracket;
-  final Token rightBracket;
-
-  ListLiteralTokens(this.constKeyword, this.leftBracket, this.rightBracket);
-}
-
-class LogicalExpressionTokens {
-  final Token operatorToken;
-
-  LogicalExpressionTokens(this.operatorToken);
-}
-
-class MapLiteralTokens {
-  final Token constKeyword;
-  final Token leftBracket;
-  final Token rightBracket;
-
-  MapLiteralTokens(this.constKeyword, this.leftBracket, this.rightBracket);
-}
-
-class NotTokens {
-  final Token operator;
-
-  NotTokens(this.operator);
-}
-
-class NullLiteralTokens {
-  final Token literal;
-
-  NullLiteralTokens(this.literal);
-}
-
-class RethrowTokens {
-  final Token rethrowKeyword;
-
-  RethrowTokens(this.rethrowKeyword);
-}
-
-class ReturnStatementTokens {
-  final Token returnKeyword;
-  final Token semicolon;
-
-  ReturnStatementTokens(this.returnKeyword, this.semicolon);
-}
-
-class StringLiteralTokens {
-  final Token literal;
-
-  StringLiteralTokens(this.literal);
-}
-
-class SuperInitializerTokens {
-  final Token superKeyword;
-  final Token period;
-  final Token constructorName;
-
-  SuperInitializerTokens(this.superKeyword, this.period, this.constructorName);
-}
-
-class SwitchCaseTokens {
-  final Token keyword;
-  final Token colon;
-
-  SwitchCaseTokens(this.keyword, this.colon);
-}
-
-class SwitchStatementTokens {
-  final Token switchKeyword;
-  final Token leftParenthesis;
-  final Token rightParenthesis;
-  final Token leftBracket;
-  final Token rightBracket;
-
-  SwitchStatementTokens(this.switchKeyword, this.leftParenthesis,
-      this.rightParenthesis, this.leftBracket, this.rightBracket);
-}
-
-class ThisExpressionTokens {
-  final Token thisKeyword;
-
-  ThisExpressionTokens(this.thisKeyword);
-}
-
-class ThrowTokens {
-  final Token throwKeyword;
-
-  ThrowTokens(this.throwKeyword);
-}
-
-class CatchStatementTokens {
-  final Token onKeyword;
-  final Token catchKeyword;
-  final Token leftParenthesis;
-  final Token comma;
-  final Token rightParenthesis;
-
-  CatchStatementTokens(this.onKeyword, this.catchKeyword, this.leftParenthesis,
-      this.comma, this.rightParenthesis);
-}
-
-class TryFinallyTokens {
-  final Token tryKeyword;
-  final Token finallyKeyword;
-
-  TryFinallyTokens(this.tryKeyword, this.finallyKeyword);
-}
-
-class WhileStatementTokens {
-  final Token whileKeyword;
-  final Token leftParenthesis;
-  final Token rightParenthesis;
-
-  WhileStatementTokens(
-      this.whileKeyword, this.leftParenthesis, this.rightParenthesis);
-}
-
-class YieldStatementTokens {
-  final Token yieldKeyword;
-  final Token star;
-  final Token semicolon;
-
-  YieldStatementTokens(this.yieldKeyword, this.star, this.semicolon);
-}
-
-class NamedExpressionTokens {
-  final Token nameToken;
-  final Token colon;
-
-  NamedExpressionTokens(this.nameToken, this.colon);
-}
-
-abstract class TypeInferenceTokensSaver {
-  AsExpressionTokens asExpressionTokens(Token asOperator);
-  AssertInitializerTokens assertInitializerTokens(Token assertKeyword,
-      Token leftParenthesis, Token comma, Token rightParenthesis);
-  AssertStatementTokens assertStatementTokens(
-      Token assertKeyword,
-      Token leftParenthesis,
-      Token comma,
-      Token rightParenthesis,
-      Token semicolon);
-  AwaitExpressionTokens awaitExpressionTokens(Token awaitKeyword);
-  BlockTokens blockTokens(Token leftBracket, Token rightBracket);
-  BoolLiteralTokens boolLiteralTokens(Token literal);
-  BreakStatementTokens breakStatementTokens(
-      Token breakKeyword, Token semicolon);
-  ContinueStatementTokens continueStatementTokens(
-      Token continueKeyword, Token semicolon);
-  ConditionalExpressionTokens conditionalExpressionTokens(
-      Token question, Token colon);
-  ContinueSwitchStatementTokens continueSwitchStatementTokens(
-      Token continueKeyword, Token semicolon);
-  DoStatementTokens doStatementTokens(Token doKeyword, Token whileKeyword,
-      Token leftParenthesis, Token rightParenthesis, Token semicolon);
-  DoubleLiteralTokens doubleLiteralTokens(Token literal);
-  EmptyStatementTokens emptyStatementTokens(Token semicolon);
-  ExpressionStatementTokens expressionStatementTokens(Token semicolon);
-  ForInStatementTokens forInStatementTokens(
-      Token awaitKeyword,
-      Token forKeyword,
-      Token leftParenthesis,
-      Token inKeyword,
-      Token rightParenthesis);
-  ForStatementTokens forStatementTokens(Token forKeyword, Token leftParenthesis,
-      Token leftSeparator, Token rightSeparator, Token rightParenthesis);
-  IfNullTokens ifNullTokens(Token operator);
-  IfStatementTokens ifStatementTokens(Token ifKeyword, Token leftParenthesis,
-      Token rightParenthesis, Token elseKeyword);
-  IntLiteralTokens intLiteralTokens(Token literal);
-  IsExpressionTokens isExpressionTokens(Token isOperator);
-  IsNotExpressionTokens isNotExpressionTokens(
-      Token isOperator, Token notOperator);
-  ListLiteralTokens listLiteralTokens(
-      Token constKeyword, Token leftBracket, Token rightBracket);
-  LogicalExpressionTokens logicalExpressionTokens(Token operatorToken);
-  MapLiteralTokens mapLiteralTokens(
-      Token constKeyword, Token leftBracket, Token rightBracket);
-  NotTokens notTokens(Token operator);
-  NullLiteralTokens nullLiteralTokens(Token literal);
-  RethrowTokens rethrowTokens(Token rethrowKeyword);
-  ReturnStatementTokens returnStatementTokens(
-      Token returnKeyword, Token semicolon);
-  StringLiteralTokens stringLiteralTokens(Token literal);
-  SuperInitializerTokens superInitializerTokens(
-      Token superKeyword, Token period, Token constructorName);
-  SwitchCaseTokens switchCaseTokens(Token keyword, Token colon);
-  SwitchStatementTokens switchStatementTokens(
-      Token switchKeyword,
-      Token leftParenthesis,
-      Token rightParenthesis,
-      Token leftBracket,
-      Token rightBracket);
-  ThisExpressionTokens thisExpressionTokens(Token thisKeyword);
-  ThrowTokens throwTokens(Token throwKeyword);
-  CatchStatementTokens catchStatementTokens(Token onKeyword, Token catchKeyword,
-      Token leftParenthesis, Token comma, Token rightParenthesis);
-  TryFinallyTokens tryFinallyTokens(Token tryKeyword, Token finallyKeyword);
-  WhileStatementTokens whileStatementTokens(
-      Token whileKeyword, Token leftParenthesis, Token rightParenthesis);
-  YieldStatementTokens yieldStatementTokens(
-      Token yieldKeyword, Token star, Token semicolon);
-  NamedExpressionTokens namedExpressionTokens(Token nameToken, Token colon);
-}
-
-/// Callback interface used by [TypeInferrer] to report the results of type
-/// inference to a client.
-///
-/// The interface is structured as a set of enter/exit methods.  The enter
-/// methods are called as the inferrer recurses down through the AST, and the
-/// exit methods are called on the way back up.  The enter methods take a
-/// [DartType] argument representing the downwards inference context; the exit
-/// methods take [DartType] argument representing the final inferred type.
-///
-/// The default implementation (in this base class) does nothing, however it can
-/// be used to debug type inference by uncommenting the
-/// "with TypeInferenceDebugging" clause below.
-abstract class TypeInferenceListener<Location, Reference, PrefixInfo> {
-  TypeInferenceTokensSaver get typeInferenceTokensSaver;
-
-  void asExpression(
-      ExpressionJudgment judgment,
-      Location location,
-      void expression,
-      AsExpressionTokens tokens,
-      void literalType,
-      DartType inferredType);
-
-  void assertInitializer(InitializerJudgment judgment, Location location,
-      AssertInitializerTokens tokens, void condition, void message);
-
-  void assertStatement(StatementJudgment judgment, Location location,
-      AssertStatementTokens tokens, void condition, void message);
-
-  void awaitExpression(ExpressionJudgment judgment, Location location,
-      AwaitExpressionTokens tokens, void expression, DartType inferredType);
-
-  Object binderForFunctionDeclaration(
-      StatementJudgment judgment, Location location, String name);
-
-  Object binderForStatementLabel(
-      StatementJudgment judgment, int fileOffset, String name);
-
-  Object binderForSwitchLabel(
-      SwitchCaseJudgment judgment, int fileOffset, String name);
-
-  Object binderForTypeVariable(
-      KernelTypeVariableBuilder builder, int fileOffset, String name);
-
-  Object binderForVariableDeclaration(StatementJudgment judgment,
-      int fileOffset, String name, bool forSyntheticToken);
-
-  void block(StatementJudgment judgment, Location location, BlockTokens tokens,
-      List<void> statements);
-
-  void boolLiteral(ExpressionJudgment judgment, Location location,
-      BoolLiteralTokens tokens, bool value, DartType inferredType);
-
-  void breakStatement(StatementJudgment judgment, Location location,
-      BreakStatementTokens tokens, void label, covariant Object labelBinder);
-
-  void cascadeExpression(
-      ExpressionJudgment judgment, Location location, DartType inferredType);
-
-  void catchStatement(
-      Catch judgment,
-      Location location,
-      CatchStatementTokens tokens,
-      void type,
-      void body,
-      covariant Object exceptionBinder,
-      DartType exceptionType,
-      covariant Object stackTraceBinder,
-      DartType stackTraceType);
-
-  void conditionalExpression(
-      ExpressionJudgment judgment,
-      Location location,
-      void condition,
-      ConditionalExpressionTokens tokens,
-      void thenExpression,
-      void elseExpression,
-      DartType inferredType);
-
-  void constructorInvocation(ExpressionJudgment judgment, Location location,
-      Reference expressionTarget, DartType inferredType);
-
-  void continueStatement(StatementJudgment judgment, Location location,
-      ContinueStatementTokens tokens, void label, covariant Object labelBinder);
-
-  void continueSwitchStatement(
-      StatementJudgment judgment,
-      Location location,
-      ContinueSwitchStatementTokens tokens,
-      void label,
-      covariant Object labelBinder);
-
-  void deferredCheck(
-      ExpressionJudgment judgment, Location location, DartType inferredType);
-
-  void doStatement(StatementJudgment judgment, Location location,
-      DoStatementTokens tokens, void body, void condition);
-
-  void doubleLiteral(ExpressionJudgment judgment, Location location,
-      DoubleLiteralTokens tokens, double value, DartType inferredType);
-
-  void emptyStatement(EmptyStatementTokens tokens);
-
-  void expressionStatement(StatementJudgment judgment, Location location,
-      void expression, ExpressionStatementTokens tokens);
-
-  void fieldInitializer(
-      InitializerJudgment judgment,
-      Location location,
-      Token thisKeyword,
-      Token period,
-      Token fieldName,
-      Token equals,
-      void expression,
-      Reference initializerField);
-
-  void forInStatement(
-      StatementJudgment judgment,
-      Location location,
-      ForInStatementTokens tokens,
-      Object loopVariable,
-      void iterator,
-      void body,
-      covariant Object loopVariableBinder,
-      DartType loopVariableType,
-      Location writeLocation,
-      DartType writeVariableType,
-      covariant Object writeVariableBinder,
-      Reference writeTarget);
-
-  void forStatement(
-      StatementJudgment judgment,
-      Location location,
-      ForStatementTokens tokens,
-      List<Object> variableList,
-      void initialization,
-      void condition,
-      void updaters,
-      void body);
-
-  void functionDeclaration(covariant Object binder, FunctionType inferredType);
-
-  void functionExpression(
-      ExpressionJudgment judgment, Location location, DartType inferredType);
-
-  void functionType(Location location, DartType type);
-
-  void functionTypedFormalParameter(Location location, DartType type);
-
-  void ifNull(ExpressionJudgment judgment, Location location, void leftOperand,
-      IfNullTokens tokens, void rightOperand, DartType inferredType);
-
-  void ifStatement(
-      StatementJudgment judgment,
-      Location location,
-      IfStatementTokens tokens,
-      void condition,
-      void thenStatement,
-      void elseStatement);
-
-  void indexAssign(ExpressionJudgment judgment, Location location,
-      Reference writeMember, Reference combiner, DartType inferredType);
-
-  void intLiteral(ExpressionJudgment judgment, Location location,
-      IntLiteralTokens tokens, num value, DartType inferredType);
-
-  void invalidAssignment(ExpressionJudgment judgment, Location location);
-
-  void invalidInitializer(InitializerJudgment judgment, Location location);
-
-  void isExpression(
-      ExpressionJudgment judgment,
-      Location location,
-      void expression,
-      IsExpressionTokens tokens,
-      void literalType,
-      DartType inferredType);
-
-  void isNotExpression(
-      ExpressionJudgment judgment,
-      Location location,
-      void expression,
-      IsNotExpressionTokens tokens,
-      void literalType,
-      DartType inferredType);
-
-  void labeledStatement(List<Object> labels, void statement);
-
-  void listLiteral(
-      ExpressionJudgment judgment,
-      Location location,
-      ListLiteralTokens tokens,
-      covariant Object typeArguments,
-      void elements,
-      DartType inferredType);
-
-  void loadLibrary(LoadLibraryJudgment judgment, Location location,
-      Reference library, FunctionType calleeType, DartType inferredType);
-
-  void loadLibraryTearOff(LoadLibraryTearOffJudgment judgment,
-      Location location, Reference library, DartType inferredType);
-
-  void logicalExpression(
-      ExpressionJudgment judgment,
-      Location location,
-      void leftOperand,
-      LogicalExpressionTokens tokens,
-      void rightOperand,
-      DartType inferredType);
-
-  void mapLiteral(
-      ExpressionJudgment judgment,
-      Location location,
-      MapLiteralTokens tokens,
-      covariant Object typeArguments,
-      List<Object> entries,
-      DartType inferredType);
-
-  void mapLiteralEntry(
-      Object judgment, int fileOffset, void key, Token separator, void value);
-
-  void methodInvocation(
-      ExpressionJudgment judgment,
-      Location resultOffset,
-      List<DartType> argumentsTypes,
-      bool isImplicitCall,
-      Reference interfaceMember,
-      FunctionType calleeType,
-      Substitution substitution,
-      DartType inferredType);
-
-  void methodInvocationCall(
-      ExpressionJudgment judgment,
-      Location resultOffset,
-      List<DartType> argumentsTypes,
-      bool isImplicitCall,
-      FunctionType calleeType,
-      Substitution substitution,
-      DartType inferredType);
-
-  void namedFunctionExpression(ExpressionJudgment judgment,
-      covariant Object binder, DartType inferredType);
-
-  void not(ExpressionJudgment judgment, Location location, NotTokens tokens,
-      void operand, DartType inferredType);
-
-  void nullLiteral(ExpressionJudgment judgment, Location location,
-      NullLiteralTokens tokens, bool isSynthetic, DartType inferredType);
-
-  void propertyAssign(
-      ExpressionJudgment judgment,
-      Location location,
-      Reference writeMember,
-      DartType writeContext,
-      Reference combiner,
-      DartType inferredType);
-
-  void propertyGet(ExpressionJudgment judgment, Location location,
-      bool forSyntheticToken, Reference member, DartType inferredType);
-
-  void propertyGetCall(
-      ExpressionJudgment judgment, Location location, DartType inferredType);
-
-  void redirectingInitializer(
-      InitializerJudgment judgment,
-      Location location,
-      Token thisKeyword,
-      Token period,
-      Token constructorName,
-      covariant Object argumentList,
-      Reference initializerTarget);
-
-  void rethrow_(ExpressionJudgment judgment, Location location,
-      RethrowTokens tokens, DartType inferredType);
-
-  void returnStatement(StatementJudgment judgment, Location location,
-      ReturnStatementTokens tokens, void expression);
-
-  Object statementLabel(covariant Object binder, Token label, Token colon);
-
-  void staticAssign(
-      ExpressionJudgment judgment,
-      Location location,
-      Reference writeMember,
-      DartType writeContext,
-      Reference combiner,
-      DartType inferredType);
-
-  void staticGet(ExpressionJudgment judgment, Location location,
-      Reference expressionTarget, DartType inferredType);
-
-  void staticInvocation(
-      ExpressionJudgment judgment,
-      Location location,
-      Reference expressionTarget,
-      List<DartType> expressionArgumentsTypes,
-      FunctionType calleeType,
-      Substitution substitution,
-      DartType inferredType);
-
-  void storeClassReference(
-      Location location, Reference reference, DartType rawType);
-
-  void storePrefixInfo(Location location, PrefixInfo prefixInfo);
-
-  void storeUnresolved(Location location);
-
-  void stringConcatenation(
-      ExpressionJudgment judgment, Location location, DartType inferredType);
-
-  void stringLiteral(ExpressionJudgment judgment, Location location,
-      StringLiteralTokens tokens, String value, DartType inferredType);
-
-  void superInitializer(InitializerJudgment judgment, Location location,
-      SuperInitializerTokens tokens, covariant Object argumentList);
-
-  Object switchCase(SwitchCaseJudgment switchCase, List<Object> labels,
-      Token keyword, void expression, Token colon, List<void> statements);
-
-  Object switchLabel(covariant Object binder, Token label, Token colon);
-
-  void switchStatement(StatementJudgment judgment, Location location,
-      SwitchStatementTokens tokens, void expression, void members);
-
-  void symbolLiteral(
-      ExpressionJudgment judgment,
-      Location location,
-      Token poundSign,
-      List<Token> components,
-      String value,
-      DartType inferredType);
-
-  void thisExpression(ExpressionJudgment judgment, Location location,
-      ThisExpressionTokens tokens, DartType inferredType);
-
-  void throw_(ExpressionJudgment judgment, Location location,
-      ThrowTokens tokens, void expression, DartType inferredType);
-
-  void tryCatch(StatementJudgment judgment, Location location);
-
-  void tryFinally(StatementJudgment judgment, Location location,
-      TryFinallyTokens tokens, void body, void catchClauses, void finallyBlock);
-
-  void typeLiteral(ExpressionJudgment judgment, Location location,
-      Reference expressionType, DartType inferredType);
-
-  void typeReference(
-      Location location,
-      bool forSyntheticToken,
-      Token leftBracket,
-      List<void> typeArguments,
-      Token rightBracket,
-      Reference reference,
-      covariant Object binder,
-      DartType type);
-
-  void typeVariableDeclaration(
-      Location location, covariant Object binder, TypeParameter typeParameter);
-
-  void variableAssign(
-      ExpressionJudgment judgment,
-      Location location,
-      DartType writeContext,
-      covariant Object writeVariableBinder,
-      Reference combiner,
-      DartType inferredType);
-
-  void variableDeclaration(covariant Object binder, DartType inferredType);
-
-  void variableGet(
-      ExpressionJudgment judgment,
-      Location location,
-      bool forSyntheticToken,
-      bool isInCascade,
-      covariant Object variableBinder,
-      DartType inferredType);
-
-  void voidType(Location location, Token token, DartType type);
-
-  void whileStatement(StatementJudgment judgment, Location location,
-      WhileStatementTokens tokens, void condition, void body);
-
-  void yieldStatement(StatementJudgment judgment, Location location,
-      YieldStatementTokens tokens, void expression);
-}
-
-/// Kernel implementation of TypeInferenceListener; does nothing.
-///
-/// TODO(paulberry): fuse this with KernelFactory.
-class KernelTypeInferenceListener
-    implements TypeInferenceListener<int, Node, int> {
-  @override
-  TypeInferenceTokensSaver get typeInferenceTokensSaver => null;
-
-  @override
-  void asExpression(ExpressionJudgment judgment, location, void expression,
-      AsExpressionTokens tokens, void literalType, DartType inferredType) {}
-
-  @override
-  void assertInitializer(InitializerJudgment judgment, location,
-      AssertInitializerTokens tokens, void condition, void message) {}
-
-  @override
-  void assertStatement(StatementJudgment judgment, location,
-      AssertStatementTokens tokens, void condition, void message) {}
-
-  @override
-  void awaitExpression(ExpressionJudgment judgment, location,
-      AwaitExpressionTokens tokens, void expression, DartType inferredType) {}
-
-  @override
-  void binderForFunctionDeclaration(
-      StatementJudgment judgment, location, String name) {}
-
-  @override
-  void binderForStatementLabel(
-      StatementJudgment judgment, int fileOffset, String name) {}
-
-  @override
-  void binderForSwitchLabel(
-      SwitchCaseJudgment judgment, int fileOffset, String name) {}
-
-  @override
-  void binderForTypeVariable(
-      KernelTypeVariableBuilder builder, int fileOffset, String name) {}
-
-  @override
-  void binderForVariableDeclaration(StatementJudgment judgment, int fileOffset,
-      String name, bool forSyntheticToken) {}
-
-  @override
-  void block(StatementJudgment judgment, location, BlockTokens tokens,
-      List<void> statements) {}
-
-  @override
-  void boolLiteral(ExpressionJudgment judgment, location,
-      BoolLiteralTokens tokens, bool value, DartType inferredType) {}
-
-  @override
-  void breakStatement(StatementJudgment judgment, location,
-      BreakStatementTokens tokens, void label, covariant void labelBinder) {}
-
-  @override
-  void cascadeExpression(
-      ExpressionJudgment judgment, location, DartType inferredType) {}
-
-  @override
-  void catchStatement(
-      Catch judgment,
-      location,
-      CatchStatementTokens tokens,
-      void type,
-      void body,
-      covariant void exceptionBinder,
-      DartType exceptionType,
-      covariant void stackTraceBinder,
-      DartType stackTraceType) {}
-
-  @override
-  void conditionalExpression(
-      ExpressionJudgment judgment,
-      location,
-      void condition,
-      ConditionalExpressionTokens tokens,
-      void thenExpression,
-      void elseExpression,
-      DartType inferredType) {}
-
-  @override
-  void constructorInvocation(ExpressionJudgment judgment, location,
-      expressionTarget, DartType inferredType) {}
-
-  @override
-  void continueStatement(StatementJudgment judgment, location,
-      ContinueStatementTokens tokens, void label, covariant void labelBinder) {}
-
-  @override
-  void continueSwitchStatement(
-      StatementJudgment judgment,
-      location,
-      ContinueSwitchStatementTokens tokens,
-      void label,
-      covariant void labelBinder) {}
-
-  @override
-  void deferredCheck(
-      ExpressionJudgment judgment, location, DartType inferredType) {}
-
-  @override
-  void doStatement(StatementJudgment judgment, location,
-      DoStatementTokens tokens, void body, void condition) {}
-
-  @override
-  void doubleLiteral(ExpressionJudgment judgment, location,
-      DoubleLiteralTokens tokens, double value, DartType inferredType) {}
-
-  @override
-  void emptyStatement(EmptyStatementTokens tokens) {}
-
-  @override
-  void expressionStatement(StatementJudgment judgment, location,
-      void expression, ExpressionStatementTokens tokens) {}
-
-  @override
-  void fieldInitializer(
-      InitializerJudgment judgment,
-      location,
-      Token thisKeyword,
-      Token period,
-      Token fieldName,
-      Token equals,
-      void expression,
-      initializerField) {}
-
-  @override
-  void forInStatement(
-      StatementJudgment judgment,
-      location,
-      ForInStatementTokens tokens,
-      covariant Object loopVariable,
-      void iterator,
-      void body,
-      covariant void loopVariableBinder,
-      DartType loopVariableType,
-      writeLocation,
-      DartType writeVariableType,
-      covariant void writeVariableBinder,
-      writeTarget) {}
-
-  @override
-  void forStatement(
-      StatementJudgment judgment,
-      location,
-      ForStatementTokens tokens,
-      Object variableDeclarationList,
-      void initialization,
-      void condition,
-      void updaters,
-      void body) {}
-
-  @override
-  void functionDeclaration(covariant void binder, FunctionType inferredType) {}
-
-  @override
-  void functionExpression(
-      ExpressionJudgment judgment, location, DartType inferredType) {}
-
-  void functionType(int location, DartType type) {}
-
-  void functionTypedFormalParameter(int location, DartType type) {}
-
-  @override
-  void ifNull(ExpressionJudgment judgment, location, void leftOperand,
-      IfNullTokens tokens, void rightOperand, DartType inferredType) {}
-
-  @override
-  void ifStatement(
-      StatementJudgment judgment,
-      location,
-      IfStatementTokens tokens,
-      void condition,
-      void thenStatement,
-      void elseStatement) {}
-
-  @override
-  void indexAssign(ExpressionJudgment judgment, location, writeMember, combiner,
-      DartType inferredType) {}
-
-  @override
-  void intLiteral(ExpressionJudgment judgment, location,
-      IntLiteralTokens tokens, num value, DartType inferredType) {}
-
-  @override
-  void invalidAssignment(ExpressionJudgment judgment, int location) {}
-
-  @override
-  void invalidInitializer(InitializerJudgment judgment, location) {}
-
-  @override
-  void isExpression(ExpressionJudgment judgment, location, void expression,
-      IsExpressionTokens tokens, void literalType, DartType inferredType) {}
-
-  @override
-  void isNotExpression(ExpressionJudgment judgment, location, void expression,
-      IsNotExpressionTokens tokens, void literalType, DartType inferredType) {}
-
-  @override
-  void labeledStatement(List<Object> labels, void statement) {}
-
-  @override
-  void listLiteral(
-      ExpressionJudgment judgment,
-      location,
-      ListLiteralTokens tokens,
-      covariant Object typeArguments,
-      void elements,
-      DartType inferredType) {}
-
-  @override
-  void loadLibrary(LoadLibraryJudgment judgment, location, library,
-      FunctionType calleeType, DartType inferredType) {}
-
-  @override
-  void loadLibraryTearOff(LoadLibraryTearOffJudgment judgment, location,
-      library, DartType inferredType) {}
-
-  @override
-  void logicalExpression(
-      ExpressionJudgment judgment,
-      location,
-      void leftOperand,
-      LogicalExpressionTokens tokens,
-      void rightOperand,
-      DartType inferredType) {}
-
-  @override
-  void mapLiteral(
-      ExpressionJudgment judgment,
-      location,
-      MapLiteralTokens tokens,
-      Object typeArguments,
-      List<Object> entries,
-      DartType inferredType) {}
-
-  void mapLiteralEntry(
-      Object judgment, int fileOffset, void key, Token separator, void value) {}
-
-  @override
-  void methodInvocation(
-      ExpressionJudgment judgment,
-      resultOffset,
-      List<DartType> argumentsTypes,
-      bool isImplicitCall,
-      interfaceMember,
-      FunctionType calleeType,
-      Substitution substitution,
-      DartType inferredType) {}
-
-  @override
-  void methodInvocationCall(
-      ExpressionJudgment judgment,
-      resultOffset,
-      List<DartType> argumentsTypes,
-      bool isImplicitCall,
-      FunctionType calleeType,
-      Substitution substitution,
-      DartType inferredType) {}
-
-  @override
-  void namedFunctionExpression(ExpressionJudgment judgment,
-      covariant void binder, DartType inferredType) {}
-
-  @override
-  void not(ExpressionJudgment judgment, location, NotTokens tokens,
-      void operand, DartType inferredType) {}
-
-  @override
-  void nullLiteral(ExpressionJudgment judgment, location,
-      NullLiteralTokens tokens, bool isSynthetic, DartType inferredType) {}
-
-  @override
-  void propertyAssign(ExpressionJudgment judgment, location, writeMember,
-      DartType writeContext, combiner, DartType inferredType) {}
-
-  @override
-  void propertyGet(ExpressionJudgment judgment, location,
-      bool forSyntheticToken, member, DartType inferredType) {}
-
-  @override
-  void propertyGetCall(
-      ExpressionJudgment judgment, location, DartType inferredType) {}
-
-  @override
-  void redirectingInitializer(
-      InitializerJudgment judgment,
-      location,
-      Token thisKeyword,
-      Token period,
-      Token constructorName,
-      covariant Object argumentList,
-      initializerTarget) {}
-
-  @override
-  void rethrow_(ExpressionJudgment judgment, location, RethrowTokens tokens,
-      DartType inferredType) {}
-
-  @override
-  void returnStatement(StatementJudgment judgment, location,
-      ReturnStatementTokens tokens, void expression) {}
-
-  @override
-  void statementLabel(covariant void binder, Token label, Token colon) {}
-
-  @override
-  void staticAssign(ExpressionJudgment judgment, location, writeMember,
-      DartType writeContext, combiner, DartType inferredType) {}
-
-  @override
-  void staticGet(ExpressionJudgment judgment, location, expressionTarget,
-      DartType inferredType) {}
-
-  @override
-  void staticInvocation(
-      ExpressionJudgment judgment,
-      location,
-      expressionTarget,
-      List<DartType> expressionArgumentsTypes,
-      FunctionType calleeType,
-      Substitution substitution,
-      DartType inferredType) {}
-
-  @override
-  void storeClassReference(location, reference, DartType rawType) {}
-
-  @override
-  void storePrefixInfo(location, prefixInfo) {}
-
-  @override
-  void storeUnresolved(int location) {}
-
-  @override
-  void stringConcatenation(
-      ExpressionJudgment judgment, location, DartType inferredType) {}
-
-  @override
-  void stringLiteral(ExpressionJudgment judgment, location,
-      StringLiteralTokens tokens, String value, DartType inferredType) {}
-
-  @override
-  void superInitializer(InitializerJudgment judgment, location,
-      SuperInitializerTokens tokens, covariant Object argumentList) {}
-
-  @override
-  void switchCase(SwitchCaseJudgment switchCase, covariant List<Object> labels,
-      Token keyword, void expression, Token colon, List<void> statements) {}
-
-  @override
-  void switchLabel(covariant void binder, Token label, Token colon) {}
-
-  @override
-  void switchStatement(StatementJudgment judgment, location,
-      SwitchStatementTokens tokens, void expression, void members) {}
-
-  @override
-  void symbolLiteral(ExpressionJudgment judgment, location, Token poundSign,
-      List<Token> components, String value, DartType inferredType) {}
-
-  @override
-  void thisExpression(ExpressionJudgment judgment, location,
-      ThisExpressionTokens tokns, DartType inferredType) {}
-
-  @override
-  void throw_(ExpressionJudgment judgment, location, ThrowTokens tokens,
-      void expression, DartType inferredType) {}
-
-  @override
-  void tryCatch(StatementJudgment judgment, location) {}
-
-  @override
-  void tryFinally(StatementJudgment judgment, location, TryFinallyTokens tokens,
-      void body, void catchClauses, void finallyBlock) {}
-
-  @override
-  void typeLiteral(ExpressionJudgment judgment, location, expressionType,
-      DartType inferredType) {}
-
-  @override
-  void typeReference(
-      location,
-      bool forSyntheticToken,
-      Token leftBracket,
-      List<void> typeArguments,
-      Token rightBracket,
-      reference,
-      covariant void binder,
-      DartType type) {}
-
-  @override
-  void typeVariableDeclaration(
-      location, covariant void binder, TypeParameter typeParameter) {}
-
-  @override
-  void variableAssign(
-      ExpressionJudgment judgment,
-      location,
-      DartType writeContext,
-      covariant void writeVariableBinder,
-      combiner,
-      DartType inferredType) {}
-
-  @override
-  void variableDeclaration(covariant void binder, DartType inferredType) {}
-
-  @override
-  void variableGet(
-      ExpressionJudgment judgment,
-      location,
-      bool forSyntheticToken,
-      bool isInCascade,
-      expressionVariable,
-      DartType inferredType) {}
-
-  @override
-  void voidType(location, Token token, DartType type) {}
-
-  @override
-  void whileStatement(StatementJudgment judgment, location,
-      WhileStatementTokens toknes, void condition, void body) {}
-
-  @override
-  void yieldStatement(StatementJudgment judgment, location,
-      YieldStatementTokens tokens, void expression) {}
-}
diff --git a/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart b/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart
index 1d24bbd..61560c5 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart
@@ -22,7 +22,6 @@
         FunctionType,
         Instantiation,
         InterfaceType,
-        InvalidType,
         InvocationExpression,
         Let,
         ListLiteral,
@@ -30,7 +29,6 @@
         Member,
         MethodInvocation,
         Name,
-        Node,
         NullLiteral,
         Procedure,
         ProcedureKind,
@@ -46,7 +44,6 @@
         TreeNode,
         TypeParameter,
         TypeParameterType,
-        Typedef,
         VariableDeclaration,
         VariableGet,
         VoidType;
@@ -65,10 +62,6 @@
         InstrumentationValueForType,
         InstrumentationValueForTypeArgs;
 
-import '../../scanner/token.dart' show Token;
-
-import '../builder/builder.dart' show PrefixBuilder;
-
 import '../fasta_codes.dart'
     show
         LocatedMessage,
@@ -108,9 +101,6 @@
         VariableDeclarationJudgment,
         getExplicitTypeArguments;
 
-import '../kernel/kernel_type_variable_builder.dart'
-    show KernelTypeVariableBuilder;
-
 import '../names.dart' show callName;
 
 import '../problems.dart' show unexpected, unhandled;
@@ -128,9 +118,6 @@
 import 'type_inference_engine.dart'
     show IncludesTypeParametersCovariantly, TypeInferenceEngine;
 
-import 'type_inference_listener.dart'
-    show TypeInferenceListener, TypeInferenceTokensSaver;
-
 import 'type_promotion.dart' show TypePromoter, TypePromoterDisabled;
 
 import 'type_schema.dart' show isKnown, UnknownType;
@@ -252,46 +239,64 @@
 
   bool checkValidReturn(TypeInferrerImpl inferrer, DartType returnType,
       ReturnStatement statement, DartType expressionType) {
+    // The rules for valid returns for functions with return type T and possibly
+    // a return expression with static type S.
+    var flattenedReturnType = isAsync
+        ? inferrer.typeSchemaEnvironment.unfutureType(returnType)
+        : returnType;
     if (statement.expression == null) {
-      if (isAsync) {
-        returnType = inferrer.typeSchemaEnvironment.unfutureType(returnType);
+      // Sync: return; is a valid return if T is void, dynamic, or Null.
+      // Async: return; is a valid return if flatten(T) is void, dynamic, or
+      // Null.
+      if (flattenedReturnType is VoidType ||
+          flattenedReturnType is DynamicType ||
+          flattenedReturnType == inferrer.coreTypes.nullClass.rawType) {
+        return true;
       }
-      if (returnType is! VoidType &&
-          returnType is! DynamicType &&
-          returnType != inferrer.coreTypes.nullClass.rawType) {
-        statement.expression = inferrer.helper.wrapInProblem(
-            new NullLiteral()..fileOffset = statement.fileOffset,
-            messageReturnWithoutExpression,
-            noLength)
-          ..parent = statement;
-        return false;
-      }
-    } else {
-      if (isAsync) {
-        returnType = inferrer.typeSchemaEnvironment.unfutureType(returnType);
-        expressionType =
-            inferrer.typeSchemaEnvironment.unfutureType(expressionType);
-      }
-      if (!isArrow && returnType is VoidType) {
-        if (expressionType is! VoidType &&
-            expressionType is! DynamicType &&
-            expressionType != inferrer.coreTypes.nullClass.rawType) {
-          statement.expression = inferrer.helper.wrapInProblem(
-              statement.expression, messageReturnFromVoidFunction, noLength)
-            ..parent = statement;
-          return false;
-        }
-      } else if (expressionType is VoidType) {
-        if (returnType is! VoidType &&
-            returnType is! DynamicType &&
-            returnType != inferrer.coreTypes.nullClass.rawType) {
-          statement.expression = inferrer.helper.wrapInProblem(
-              statement.expression, messageVoidExpression, noLength)
-            ..parent = statement;
-          return false;
-        }
-      }
+      statement.expression = inferrer.helper.wrapInProblem(
+          new NullLiteral()..fileOffset = statement.fileOffset,
+          messageReturnWithoutExpression,
+          noLength)
+        ..parent = statement;
+      return false;
     }
+
+    // Arrow functions are valid if:
+    // Sync: T is void or return exp; is a valid for a block-bodied function.
+    // Async: flatten(T) is void or return exp; is valid for a block-bodied
+    // function.
+    if (isArrow && flattenedReturnType is VoidType) return true;
+
+    // Sync: invalid if T is void and S is not void, dynamic, or Null
+    // Async: invalid if T is void and flatten(S) is not void, dynamic, or Null.
+    var flattenedExpressionType = isAsync
+        ? inferrer.typeSchemaEnvironment.unfutureType(expressionType)
+        : expressionType;
+    if (returnType is VoidType &&
+        flattenedExpressionType is! VoidType &&
+        flattenedExpressionType is! DynamicType &&
+        flattenedExpressionType != inferrer.coreTypes.nullClass.rawType) {
+      statement.expression = inferrer.helper.wrapInProblem(
+          statement.expression, messageReturnFromVoidFunction, noLength)
+        ..parent = statement;
+      return false;
+    }
+
+    // Sync: invalid if S is void and T is not void, dynamic, or Null.
+    // Async: invalid if flatten(S) is void and flatten(T) is not void, dynamic,
+    // or Null.
+    if (flattenedExpressionType is VoidType &&
+        flattenedReturnType is! VoidType &&
+        flattenedReturnType is! DynamicType &&
+        flattenedReturnType != inferrer.coreTypes.nullClass.rawType) {
+      statement.expression = inferrer.helper
+          .wrapInProblem(statement.expression, messageVoidExpression, noLength)
+            ..parent = statement;
+      return false;
+    }
+
+    // The caller will check that the return expression is assignable to the
+    // return type.
     return true;
   }
 
@@ -444,13 +449,6 @@
   /// performed--this is used for testing.
   Uri get uri;
 
-  Object binderForTypeVariable(
-      KernelTypeVariableBuilder builder, int fileOffset, String name);
-
-  void functionType(int offset, DartType type);
-
-  void functionTypedFormalParameter(int offset, DartType type);
-
   /// Performs full type inference on the given field initializer.
   void inferFieldInitializer<Expression, Statement, Initializer, Type>(
       InferenceHelper helper,
@@ -483,22 +481,6 @@
       InferenceHelper helper,
       kernel.Expression initializer,
       DartType declaredType);
-
-  void storePrefix(Token token, PrefixBuilder prefix);
-
-  void storeUnresolved(Token token);
-
-  void storeTypeReference(int offset, bool forSyntheticToken,
-      TreeNode reference, Object binder, DartType type);
-
-  void storeTypeUse(int offset, Node node);
-
-  void typeVariableDeclaration(
-      int offset, Object binder, TypeParameter typeParameter);
-
-  void voidType(int offset, Token token, DartType type);
-
-  TypeInferenceTokensSaver get tokensSaver;
 }
 
 /// Implementation of [TypeInferrer] which doesn't do any type inference.
@@ -518,14 +500,6 @@
   Uri get uri => null;
 
   @override
-  void binderForTypeVariable(
-      KernelTypeVariableBuilder builder, int fileOffset, String name) {}
-
-  void functionType(int offset, DartType type) {}
-
-  void functionTypedFormalParameter(int offset, DartType type) {}
-
-  @override
   void inferFieldInitializer<Expression, Statement, Initializer, Type>(
       InferenceHelper helper,
       DartType declaredType,
@@ -555,28 +529,6 @@
       InferenceHelper helper,
       kernel.Expression initializer,
       DartType declaredType) {}
-
-  @override
-  void storePrefix(Token token, PrefixBuilder prefix) {}
-
-  @override
-  void storeUnresolved(Token token) {}
-
-  @override
-  void storeTypeReference(int offset, bool forSyntheticToken,
-      TreeNode reference, Object binder, DartType type) {}
-
-  @override
-  void storeTypeUse(int offset, Node node) {}
-
-  @override
-  void typeVariableDeclaration(
-      int offset, Object binder, TypeParameter typeParameter) {}
-
-  @override
-  void voidType(int offset, Token token, DartType type) {}
-
-  TypeInferenceTokensSaver get tokensSaver => null;
 }
 
 /// Derived class containing generic implementations of [TypeInferrer].
@@ -610,8 +562,6 @@
 
   final TypeSchemaEnvironment typeSchemaEnvironment;
 
-  final TypeInferenceListener<int, Node, int> listener;
-
   final InterfaceType thisType;
 
   final SourceLibraryBuilder library;
@@ -630,8 +580,8 @@
   /// if the last invocation didn't require any inference.
   FunctionType lastCalleeType;
 
-  TypeInferrerImpl(this.engine, this.uri, this.listener, bool topLevel,
-      this.thisType, this.library)
+  TypeInferrerImpl(
+      this.engine, this.uri, bool topLevel, this.thisType, this.library)
       : coreTypes = engine.coreTypes,
         strongMode = engine.strongMode,
         classHierarchy = engine.classHierarchy,
@@ -643,20 +593,6 @@
   /// inference.
   TypePromoter get typePromoter;
 
-  @override
-  Object binderForTypeVariable(
-      KernelTypeVariableBuilder builder, int fileOffset, String name) {
-    return listener.binderForTypeVariable(builder, fileOffset, name);
-  }
-
-  void functionType(int offset, DartType type) {
-    listener.functionType(offset, type);
-  }
-
-  void functionTypedFormalParameter(int offset, DartType type) {
-    listener.functionTypedFormalParameter(offset, type);
-  }
-
   bool isAssignable(DartType expectedType, DartType actualType) {
     return typeSchemaEnvironment.isSubtypeOf(expectedType, actualType) ||
         typeSchemaEnvironment.isSubtypeOf(actualType, expectedType);
@@ -1437,7 +1373,7 @@
         inferMetadataKeepingHelper(parameter.annotations);
         if (i >= function.requiredParameterCount &&
             parameter.initializer == null) {
-          parameter.initializer = new NullJudgment(null)..parent = parameter;
+          parameter.initializer = new NullJudgment()..parent = parameter;
         }
         if (parameter.initializer != null) {
           inferExpression(parameter.initializer, parameter.type, false);
@@ -1446,7 +1382,7 @@
       for (var parameter in function.namedParameters) {
         inferMetadataKeepingHelper(parameter.annotations);
         if (parameter.initializer == null) {
-          parameter.initializer = new NullJudgment(null)..parent = parameter;
+          parameter.initializer = new NullJudgment()..parent = parameter;
         }
         inferExpression(parameter.initializer, parameter.type, false);
       }
@@ -1650,19 +1586,7 @@
     }
     handleInvocationContravariance(checkKind, desugaredInvocation, arguments,
         expression, inferredType, functionType, fileOffset);
-    int resultOffset = arguments.fileOffset != -1
-        ? arguments.fileOffset
-        : expression.fileOffset;
-    if (identical(interfaceMember, 'call')) {
-      listener.methodInvocationCall(
-          expression,
-          resultOffset,
-          arguments.types,
-          isImplicitCall,
-          lastCalleeType,
-          lastInferredSubstitution,
-          inferredType);
-    } else {
+    if (!identical(interfaceMember, 'call')) {
       if (strongMode &&
           isImplicitCall &&
           interfaceMember != null &&
@@ -1677,15 +1601,6 @@
             noLength);
         parent?.replaceChild(expression, errorNode);
       }
-      listener.methodInvocation(
-          expression,
-          resultOffset,
-          arguments.types,
-          isImplicitCall,
-          getRealTarget(interfaceMember),
-          lastCalleeType,
-          lastInferredSubstitution,
-          inferredType);
     }
     return new ExpressionInferenceResult(null, inferredType);
   }
@@ -1750,12 +1665,6 @@
       inferredType =
           instantiateTearOff(inferredType, typeContext, replacedExpression);
     }
-    if (identical(interfaceMember, 'call')) {
-      listener.propertyGetCall(expression, expression.fileOffset, inferredType);
-    } else {
-      listener.propertyGet(expression, expression.fileOffset, forSyntheticToken,
-          interfaceMember, inferredType);
-    }
     expression.inferredType = inferredType;
   }
 
@@ -1891,53 +1800,6 @@
     }
   }
 
-  @override
-  void storePrefix(Token token, PrefixBuilder prefix) {
-    listener.storePrefixInfo(token.offset, prefix?.importIndex);
-  }
-
-  @override
-  void storeUnresolved(Token token) {
-    listener.storeUnresolved(token.offset);
-  }
-
-  @override
-  void storeTypeReference(int offset, bool forSyntheticToken,
-      TreeNode reference, Object binder, DartType type) {
-    listener.typeReference(
-        offset, forSyntheticToken, null, null, null, reference, binder, type);
-  }
-
-  @override
-  void storeTypeUse(int offset, Node node) {
-    if (node is Class) {
-      listener.storeClassReference(offset, node, node.rawType);
-    } else if (node is TypeParameter) {
-      // TODO(paulberry): handle this case.
-    } else if (node is FunctionType) {
-      // TODO(paulberry): handle this case.
-    } else if (node is Typedef) {
-      // TODO(paulberry): handle this case.
-    } else if (node is InvalidType) {
-      // TODO(paulberry): handle this case.
-      listener.storeClassReference(offset, null, const DynamicType());
-    } else {
-      // TODO(paulberry): handle this case.
-      return unhandled("${node.runtimeType}", "storeTypeUse", offset, uri);
-    }
-  }
-
-  @override
-  void typeVariableDeclaration(
-      int offset, Object binder, TypeParameter typeParameter) {
-    return listener.typeVariableDeclaration(offset, binder, typeParameter);
-  }
-
-  @override
-  void voidType(int offset, Token token, DartType type) {
-    listener.voidType(offset, token, type);
-  }
-
   DartType wrapFutureOrType(DartType type) {
     if (type is InterfaceType &&
         identical(type.classNode, coreTypes.futureOrClass)) {
@@ -2043,9 +1905,6 @@
     }
     return false;
   }
-
-  TypeInferenceTokensSaver get tokensSaver =>
-      listener?.typeInferenceTokensSaver;
 }
 
 class LegacyModeMixinInferrer implements MixinInferrer {
diff --git a/pkg/front_end/lib/src/incremental/unlinked_unit.dart b/pkg/front_end/lib/src/incremental/unlinked_unit.dart
index 4aba682..c086846 100644
--- a/pkg/front_end/lib/src/incremental/unlinked_unit.dart
+++ b/pkg/front_end/lib/src/incremental/unlinked_unit.dart
@@ -19,7 +19,7 @@
   Token token = scanResult.tokens;
 
   // Parse directives.
-  var listener = new DirectiveListener();
+  var listener = new _UnlinkedDirectiveListener();
   new TopLevelParser(listener).parseUnit(token);
 
   // Parse to record function bodies.
@@ -54,7 +54,7 @@
       imports: listener.imports.map(_toUnlinkedNamespaceDirective).toList(),
       exports: listener.exports.map(_toUnlinkedNamespaceDirective).toList(),
       parts: listener.parts.toList(),
-      hasMixinApplication: parser.hasMixin);
+      hasMixinApplication: listener.hasMixin);
 }
 
 /// Exclude all `native 'xyz';` token sequences.
@@ -107,7 +107,6 @@
 
 /// The [Parser] that skips function bodies and remembers their token ranges.
 class _BodySkippingParser extends Parser {
-  bool hasMixin = false;
   final List<_BodyRange> bodyRanges = [];
 
   _BodySkippingParser() : super(new Listener());
@@ -126,9 +125,20 @@
 
   @override
   Token parseInvalidBlock(Token token) => skipBlock(token);
+}
 
-  Token parseMixinApplicationRest(Token token) {
+class _UnlinkedDirectiveListener extends DirectiveListener {
+  bool hasMixin = false;
+
+  @override
+  void handleClassWithClause(Token withKeyword) {
     hasMixin = true;
-    return super.parseMixinApplicationRest(token);
+    super.handleClassWithClause(withKeyword);
+  }
+
+  @override
+  void handleNamedMixinApplicationWithClause(Token withKeyword) {
+    hasMixin = true;
+    super.handleNamedMixinApplicationWithClause(withKeyword);
   }
 }
diff --git a/pkg/front_end/lib/src/scanner/errors.dart b/pkg/front_end/lib/src/scanner/errors.dart
index ab23b65..f96daa0 100644
--- a/pkg/front_end/lib/src/scanner/errors.dart
+++ b/pkg/front_end/lib/src/scanner/errors.dart
@@ -30,7 +30,7 @@
       const ScannerErrorCode('MISSING_DIGIT', "Decimal digit expected.");
 
   static const ScannerErrorCode MISSING_HEX_DIGIT = const ScannerErrorCode(
-      'MISSING_HEX_DIGIT', "Hexidecimal digit expected.");
+      'MISSING_HEX_DIGIT', "Hexadecimal digit expected.");
 
   static const ScannerErrorCode MISSING_IDENTIFIER =
       const ScannerErrorCode('MISSING_IDENTIFIER', "Expected an identifier.");
diff --git a/pkg/front_end/messages.status b/pkg/front_end/messages.status
index 602e60c..96ef8c84 100644
--- a/pkg/front_end/messages.status
+++ b/pkg/front_end/messages.status
@@ -57,6 +57,7 @@
 ConstConstructorWithNonConstSuper/example: Fail
 ConstEvalContext/analyzerCode: Fail # This is just used for displaying the context.
 ConstEvalContext/example: Fail # This is just used for displaying the context.
+ConstEvalDeferredLibrary/example: Fail
 ConstEvalDuplicateKey/example: Fail
 ConstEvalFailedAssertion/example: Fail
 ConstEvalFailedAssertionWithMessage/example: Fail
@@ -210,7 +211,6 @@
 InvalidContinueTarget/analyzerCode: Fail
 InvalidContinueTarget/example: Fail
 InvalidInitializer/example: Fail
-InvalidInlineFunctionType/analyzerCode: Fail
 InvalidPackageUri/analyzerCode: Fail
 InvalidPackageUri/example: Fail
 InvalidUseOfNullAwareAccess/example: Fail
@@ -271,9 +271,11 @@
 OverrideTypeVariablesMismatch/example: Fail
 PackageNotFound/analyzerCode: Fail
 PackageNotFound/example: Fail
+PackagesFileFormat/analyzerCode: Fail # Analyzer crashes when .packages file has format error
 PartOfLibraryNameMismatch/example: Fail
 PartOfUriMismatch/example: Fail
 PartOfUseUri/example: Fail
+PartOrphan/analyzerCode: Fail # Analyzer can't handle this situation
 PatchClassTypeVariablesMismatch/analyzerCode: Fail
 PatchClassTypeVariablesMismatch/example: Fail
 PatchDeclarationMismatch/analyzerCode: Fail
@@ -328,18 +330,15 @@
 ThisOrSuperAccessInFieldInitializer/example: Fail
 TooFewArguments/example: Fail
 TooManyArguments/example: Fail
-TopLevelOperator/script1: Fail
-TopLevelOperator/script2: Fail
-TopLevelOperator/script3: Fail
 TypeAfterVar/example: Fail
 TypeArgumentMismatch/example: Fail
 TypeArgumentsOnTypeVariable/script1: Fail
 TypeNotFound/example: Fail
 TypeVariableDuplicatedName/example: Fail
-TypeVariableInConstantContext/declaration1: Fail
-TypeVariableInConstantContext/declaration2: Fail
-TypeVariableInConstantContext/declaration3: Fail
-TypeVariableInStaticContext/example: Fail
+TypeVariableInStaticContext/declaration1: Fail # Unfortunate message from outline phase.
+TypeVariableInStaticContext/declaration2: Fail # Unfortunate message from outline phase.
+TypeVariableInStaticContext/declaration3: Fail # Unfortunate message from outline phase.
+TypeVariableInStaticContext/declaration4: Fail # Unfortunate message from outline phase.
 TypeVariableSameNameAsEnclosing/example: Fail
 TypedefNotFunction/example: Fail
 UnexpectedDollarInString/script1: Fail
diff --git a/pkg/front_end/messages.yaml b/pkg/front_end/messages.yaml
index 76aea60..ba5e7d6 100644
--- a/pkg/front_end/messages.yaml
+++ b/pkg/front_end/messages.yaml
@@ -32,6 +32,14 @@
 #
 # Long term, the analyzer and front-end need to share the same error codes. So
 # eventually all error codes should have an `analyzerCode` field.
+# Any error code with an `index` field and an `analyzerCode` field
+# will be auto generated as an Analyzer error code.
+# `index` field values should be unique, consecutive whole numbers starting with 1.
+# If `index` is defined, then `analyzerCode` should be the fully formed
+# name of the corresponding public Analyzer error const
+# (e.g. ParserErrorCode.EQUALITY_CANNOT_BE_EQUALITY_OPERAND)
+# which will be used when generating code in Analyzer for translating
+# fasta error codes to Analyzer error codes.
 #
 # In some cases a mesage is internal to the frontend, and no meaningful
 # analyzer code can be provided. In such cases set `frontendInternal: true`.
@@ -120,6 +128,15 @@
   template: "The variable '#string' is not a constant, only constant expressions are allowed."
   analyzerCode: NON_CONSTANT_VALUE_IN_INITIALIZER
 
+ConstEvalDeferredLibrary:
+  template: >
+    '#name' can't be used in a constant expression because it's marked as
+    'deferred' which means it isn't available until loaded.
+  tip: >
+    Try moving the constant from the deferred library, or removing 'deferred'
+    from the import.
+  analyzerCode: NON_CONSTANT_DEFAULT_VALUE_FROM_DEFERRED_LIBRARY
+
 NotConstantExpression:
   template: "#string is not a constant expression."
   analyzerCode: NOT_CONSTANT_EXPRESSION
@@ -186,8 +203,9 @@
   script: "main();"
 
 ExpectedStatement:
+  index: 29
   template: "Expected a statement."
-  analyzerCode: MISSING_STATEMENT
+  analyzerCode: ParserErrorCode.MISSING_STATEMENT
   statement: "void;"
 
 ExpectedButGot:
@@ -227,33 +245,31 @@
     - "main() { return true }"
 
 MultipleLibraryDirectives:
+  index: 27
   template: "Only one library directive may be declared in a file."
   tip: "Try removing all but one of the library directives."
-  analyzerCode: MULTIPLE_LIBRARY_DIRECTIVES
+  analyzerCode: ParserErrorCode.MULTIPLE_LIBRARY_DIRECTIVES
 
 MultipleExtends:
+  index: 28
   template: "Each class definition can have at most one extends clause."
   tip: "Try choosing one superclass and define your class to implement (or mix in) the others."
-  analyzerCode: MULTIPLE_EXTENDS_CLAUSES
+  analyzerCode: ParserErrorCode.MULTIPLE_EXTENDS_CLAUSES
   script: "class A extends B extends C {}"
 
 MultipleWith:
+  index: 24
   template: "Each class definition can have at most one with clause."
   tip: "Try combining all of the with clauses into a single clause."
-  analyzerCode: MULTIPLE_WITH_CLAUSES
+  analyzerCode: ParserErrorCode.MULTIPLE_WITH_CLAUSES
   script: "class A extends B with C, D with E {}"
 
-WithWithoutExtends:
-  template: "The with clause can't be used without an extends clause."
-  tip: "Try adding an extends clause such as 'extends Object'."
-  analyzerCode: WITH_WITHOUT_EXTENDS
-  script: "class A with B, C {}"
-
 WithBeforeExtends:
+  index: 11
   template: "The extends clause must be before the with clause."
   tip: "Try moving the extends clause before the with clause."
-  analyzerCode: WITH_BEFORE_EXTENDS
-  script: "class A with B extends C {}"
+  analyzerCode: ParserErrorCode.WITH_BEFORE_EXTENDS
+  script: "class B {} class A with B extends C {}"
 
 ImplementsBeforeExtends:
   template: "The extends clause must be before the implements clause."
@@ -299,9 +315,10 @@
   script: "class A implements B implements C, D {}"
 
 MultipleOnClauses:
+  index: 26
   template: "Each mixin definition can have at most one on clause."
   tip: "Try combining all of the on clauses into a single clause."
-  analyzerCode: MULTIPLE_ON_CLAUSES
+  analyzerCode: ParserErrorCode.MULTIPLE_ON_CLAUSES
   script: "mixin A on B on C, D {}"
 
 ImplementsFutureOr:
@@ -344,9 +361,10 @@
   script: "do() {} main() {}"
 
 EqualityCannotBeEqualityOperand:
+  index: 1
   template: "An equality expression can't be an operand of another equality expression."
   tip: "Try re-writing the expression."
-  analyzerCode: EQUALITY_CANNOT_BE_EQUALITY_OPERAND
+  analyzerCode: ParserErrorCode.EQUALITY_CANNOT_BE_EQUALITY_OPERAND
   script:
     - "main() { var b = a < b < c; }"
     - "main() { var b = a == b != c; }"
@@ -416,9 +434,10 @@
     - "class Foo { enum Bar { Bar1, Bar2, Bar3 } }"
 
 TypedefInClass:
+  index: 7
   template: "Typedefs can't be declared inside classes."
   tip: "Try moving the typedef to the top-level."
-  analyzerCode: TYPEDEF_IN_CLASS
+  analyzerCode: ParserErrorCode.TYPEDEF_IN_CLASS
   script:
     - "abstract class C { typedef int F(int x); }"
 
@@ -431,9 +450,10 @@
     - "covariant int m() => 0;"
 
 VarReturnType:
+  index: 12
   template: "The return type can't be 'var'."
   tip: "Try removing the keyword 'var', or replacing it with the name of the return type."
-  analyzerCode: VAR_RETURN_TYPE
+  analyzerCode: ParserErrorCode.VAR_RETURN_TYPE
   script:
     - "class C { var m() {} }"
     - "class C { var C() {} }"
@@ -527,9 +547,10 @@
     - "final covariant f;"
 
 CovariantAfterVar:
+  index: 8
   template: "The modifier 'covariant' should be before the modifier 'var'."
   tip: "Try re-ordering the modifiers."
-  analyzerCode: COVARIANT_AFTER_VAR
+  analyzerCode: ParserErrorCode.COVARIANT_AFTER_VAR
   script:
     - "var covariant f;"
 
@@ -682,38 +703,43 @@
     - "class C { var final x = 5; }"
 
 StaticAfterConst:
+  index: 20
   template: "The modifier 'static' should be before the modifier 'const'."
   tip: "Try re-ordering the modifiers."
-  analyzerCode: STATIC_AFTER_CONST
+  analyzerCode: ParserErrorCode.STATIC_AFTER_CONST
   script:
     - "class C { const static int f; }"
 
 StaticAfterFinal:
+  index: 19
   template: "The modifier 'static' should be before the modifier 'final'."
   tip: "Try re-ordering the modifiers."
-  analyzerCode: STATIC_AFTER_FINAL
+  analyzerCode: ParserErrorCode.STATIC_AFTER_FINAL
   script:
     - "class C { final static int f = 5; }"
 
 StaticAfterVar:
+  index: 18
   template: "The modifier 'static' should be before the modifier 'var'."
   tip: "Try re-ordering the modifiers."
-  analyzerCode: STATIC_AFTER_VAR
+  analyzerCode: ParserErrorCode.STATIC_AFTER_VAR
   script:
     - "class C { var static f; }"
 
 StaticConstructor:
+  index: 4
   template: "Constructors can't be static."
   tip: "Try removing the keyword 'static'."
-  analyzerCode: STATIC_CONSTRUCTOR
+  analyzerCode: ParserErrorCode.STATIC_CONSTRUCTOR
   script:
     - "class C { static C() {} }"
     - "class C { static C.m() {} }"
 
 StaticOperator:
+  index: 17
   template: "Operators can't be static."
   tip: "Try removing the keyword 'static'."
-  analyzerCode: STATIC_OPERATOR
+  analyzerCode: ParserErrorCode.STATIC_OPERATOR
   script:
     - "class C { static operator +(int x) => x + 1; }"
 
@@ -732,9 +758,10 @@
   analyzerCode: LABEL_IN_OUTER_SCOPE
 
 ContinueOutsideOfLoop:
+  index: 2
   template: "A continue statement can't be used outside of a loop or switch statement."
   tip: "Try removing the continue statement."
-  analyzerCode: CONTINUE_OUTSIDE_OF_LOOP
+  analyzerCode: ParserErrorCode.CONTINUE_OUTSIDE_OF_LOOP
   script:
     - "main() { continue; }"
 
@@ -778,9 +805,10 @@
     - "for (int a = 0 in <int>[10]) {}"
 
 InvalidAwaitFor:
+  index: 9
   template: "The keyword 'await' isn't allowed for a normal 'for' statement."
   tip: "Try removing the keyword, or use a for-each statement."
-  analyzerCode: INVALID_AWAIT_IN_FOR
+  analyzerCode: ParserErrorCode.INVALID_AWAIT_IN_FOR
   script:
     - "f() async {await for (int i = 0; i < 5; i++) {}}"
 
@@ -793,7 +821,7 @@
 InvalidVoid:
   template: "Type 'void' can't be used here because it isn't a return type."
   tip: "Try removing 'void' keyword or replace it with 'var', 'final', or a type."
-  analyzerCode: INVALID_USE_OF_VOID
+  analyzerCode: EXPECTED_TYPE_NAME
   script:
     - "void x; main() {}"
     - "foo(void x) {} main() { foo(null); }"
@@ -869,14 +897,14 @@
     - "'\\u{110000}'"
 
 InvalidHexEscape:
-  template: "An escape sequence starting with '\\x' must be followed by 2 hexidecimal digits."
+  template: "An escape sequence starting with '\\x' must be followed by 2 hexadecimal digits."
   analyzerCode: INVALID_HEX_ESCAPE
   expression:
     - "'\\x0'"
     - "'\\x0y'"
 
 InvalidUnicodeEscape:
-  template: "An escape sequence starting with '\\u' must be followed by 4 hexidecimal digits or from 1 to 6 digits between '{' and '}'."
+  template: "An escape sequence starting with '\\u' must be followed by 4 hexadecimal digits or from 1 to 6 digits between '{' and '}'."
   analyzerCode: INVALID_UNICODE_ESCAPE
   expression:
     - "'\\u'"
@@ -1032,8 +1060,9 @@
   analyzerCode: RETURN_IN_GENERATOR
 
 InvalidInlineFunctionType:
-  template: "Invalid inline function type."
+  template: "Inline function types cannot be used for parameters in a generic function type."
   tip: "Try changing the inline function type (as in 'int f()') to a prefixed function type using the `Function` keyword (as in 'int Function() f')."
+  analyzerCode: INVALID_INLINE_FUNCTION_TYPE
   declaration: "typedef F = Function(int f(String x));"
 
 SetterNotSync:
@@ -1105,6 +1134,13 @@
     - "try {} catch () {}"
     - "try {} catch (e,) {}"
 
+CatchSyntaxExtraParameters:
+  template: "'catch' must be followed by '(identifier)' or '(identifier, identifier)'."
+  tip: "No types are needed, the first is given by 'on', the second is always 'StackTrace'."
+  analyzerCode: CATCH_SYNTAX
+  statement:
+    - "try {} catch (e, s, x) {}"
+
 SuperNullAware:
   template: "'super' can't be null."
   tip: "Try replacing '?.' with '.'"
@@ -1394,9 +1430,10 @@
   analyzerCode: NAMED_FUNCTION_EXPRESSION
 
 NativeClauseShouldBeAnnotation:
+  index: 23
   template: "Native clause in this form is deprecated."
   tip: "Try removing this native clause and adding @native() or @native('native-name') before the declaration."
-  analyzerCode: NATIVE_CLAUSE_SHOULD_BE_ANNOTATION
+  analyzerCode: ParserErrorCode.NATIVE_CLAUSE_SHOULD_BE_ANNOTATION
 
 ReturnTypeFunctionExpression:
   template: "A function expression can't have a return type."
@@ -1502,9 +1539,10 @@
   severity: IGNORED
 
 MissingPrefixInDeferredImport:
+  index: 30
   template: "Deferred imports should have a prefix."
   tip: "Try adding a prefix to the import."
-  analyzerCode: MISSING_PREFIX_IN_DEFERRED_IMPORT
+  analyzerCode: ParserErrorCode.MISSING_PREFIX_IN_DEFERRED_IMPORT
 
 DeferredAfterPrefix:
   template: "The deferred keyword should come immediately before the prefix ('as' clause)."
@@ -1528,9 +1566,10 @@
   analyzerCode: DUPLICATE_PREFIX
 
 PrefixAfterCombinator:
+  index: 6
   template: "The prefix ('as' clause) should come before any show/hide combinators."
   tip: "Try moving the prefix before the combinators."
-  analyzerCode: PREFIX_AFTER_COMBINATOR
+  analyzerCode: ParserErrorCode.PREFIX_AFTER_COMBINATOR
 
 DuplicatedExport:
   template: "'#name' is exported from both '#uri' and '#uri2'."
@@ -1737,11 +1776,11 @@
   analyzerCode: INVALID_METHOD_OVERRIDE_TYPE_PARAMETERS
 
 OverriddenMethodCause:
-  template: "This is the overriden method ('#name')."
+  template: "This is the overridden method ('#name')."
   severity: CONTEXT
 
 OverrideMismatchNamedParameter:
-  template: "The method '#name' doesn't have the named parameter '#name2' of overriden method '#name3'."
+  template: "The method '#name' doesn't have the named parameter '#name2' of overridden method '#name3'."
   severity: ERROR_LEGACY_WARNING
   analyzerCode: INVALID_OVERRIDE_NAMED
 
@@ -1802,16 +1841,18 @@
     - "enum E {}"
 
 ExternalClass:
+  index: 3
   template: "Classes can't be declared to be 'external'."
   tip: "Try removing the keyword 'external'."
-  analyzerCode: EXTERNAL_CLASS
+  analyzerCode: ParserErrorCode.EXTERNAL_CLASS
   script:
     - "external class C {}"
 
 ExternalEnum:
+  index: 5
   template: "Enums can't be declared to be 'external'."
   tip: "Try removing the keyword 'external'."
-  analyzerCode: EXTERNAL_ENUM
+  analyzerCode: ParserErrorCode.EXTERNAL_ENUM
   script:
     - "external enum E {ONE}"
 
@@ -1852,9 +1893,10 @@
     - "part 'a.dart'; library l;"
 
 ImportAfterPart:
+  index: 10
   template: "Import directives must preceed part directives."
   tip: "Try moving the import directives before the part directives."
-  analyzerCode: IMPORT_DIRECTIVE_AFTER_PART_DIRECTIVE
+  analyzerCode: ParserErrorCode.IMPORT_DIRECTIVE_AFTER_PART_DIRECTIVE
   script:
     - "part 'foo.dart'; import 'bar.dart';"
 
@@ -1881,11 +1923,18 @@
     - "part of l; part 'f.dart';"
 
 PartOfTwice:
+  index: 25
   template: "Only one part-of directive may be declared in a file."
   tip: "Try removing all but one of the part-of directives."
-  analyzerCode: MULTIPLE_PART_OF_DIRECTIVES
+  analyzerCode: ParserErrorCode.MULTIPLE_PART_OF_DIRECTIVES
   script:
-    - "part of l; part of m;"
+    main.dart: |
+      part "part.dart";
+      main() {}
+    other.dart: ""
+    part.dart: |
+      part of "other.dart";
+      part of "main.dart";
 
 PartTwice:
   template: "Can't use '#uri' as a part more than once."
@@ -1915,16 +1964,18 @@
     - "factory class C {}"
 
 RedirectionInNonFactory:
+  index: 21
   template: "Only factory constructor can specify '=' redirection."
   tip: "Try making this a factory constructor, or remove the redirection."
-  analyzerCode: REDIRECTION_IN_NON_FACTORY_CONSTRUCTOR
+  analyzerCode: ParserErrorCode.REDIRECTION_IN_NON_FACTORY_CONSTRUCTOR
   script:
     - "class C { C() = D; }"
 
 TopLevelOperator:
+  index: 14
   template: "Operators must be declared within a class."
   tip: "Try removing the operator, moving it to a class, or converting it to be a function."
-  analyzerCode: TOP_LEVEL_OPERATOR
+  analyzerCode: ParserErrorCode.TOP_LEVEL_OPERATOR
   script:
     - "operator +(bool x, bool y) => x | y;"
     - "bool operator +(bool x, bool y) => x | y;"
@@ -1963,8 +2014,60 @@
   tip: "Try removing the 'part of' declaration, or using '#uri' as a part."
   analyzerCode: IMPORT_OF_NON_LIBRARY
   script:
-    part.dart: "part of mainlib;"
-    main.dart: "library mainlib; import 'part.dart';"
+    main.dart: |
+      import "part.dart";
+      import "lib.dart";
+      main() {}
+
+    part.dart: |
+      part of "lib.dart";
+
+    lib.dart: |
+      part "part.dart";
+
+PartInPart:
+  template: "A file that's a part of a library can't have parts itself."
+  tip: "Try moving the 'part' declaration to the containing library."
+  analyzerCode: NON_PART_OF_DIRECTIVE_IN_PART
+  script:
+    main.dart: |
+      part "part.dart";
+      main() {}
+
+    part.dart: |
+      part of "main.dart";
+      part "part_part.dart";
+
+    part_part.dart: |
+      part of "part.dart";
+
+PartInPartLibraryContext:
+  template: "This is the containing library."
+  severity: CONTEXT
+
+PartOrphan:
+  template: "This part doesn't have a containing library."
+  tip: "Try removing the 'part of' declaration."
+  script: "part of none; main() {}"
+
+PartExport:
+  template: "Can't export this file because it contains a 'part of' declaration."
+  analyzerCode: EXPORT_OF_NON_LIBRARY
+  script:
+    main.dart: |
+      export "part.dart";
+      import "lib.dart";
+      main() {}
+
+    part.dart: |
+      part of "lib.dart";
+
+    lib.dart: |
+      part "part.dart";
+
+PartExportContext:
+  template: "This is the file that can't be exported."
+  severity: CONTEXT
 
 SupertypeIsFunction:
   template: "Can't use a function type as supertype."
@@ -1978,10 +2081,11 @@
   severity: CONTEXT
 
 TypeArgumentsOnTypeVariable:
+  index: 13
   template: "Can't use type arguments with type variable '#name'."
   tip: "Try removing the type arguments."
   severity: ERROR_LEGACY_WARNING
-  analyzerCode: TYPE_ARGUMENTS_ON_TYPE_VARIABLE
+  analyzerCode: ParserErrorCode.TYPE_ARGUMENTS_ON_TYPE_VARIABLE
   script:
     - "dynamic<T>(x) => 0"
 
@@ -2137,16 +2241,18 @@
   severity: CONTEXT
 
 SwitchHasCaseAfterDefault:
+  index: 16
   template: "The default case should be the last case in a switch statement."
   tip: "Try moving the default case after the other case clauses."
-  analyzerCode: SWITCH_HAS_CASE_AFTER_DEFAULT_CASE
+  analyzerCode: ParserErrorCode.SWITCH_HAS_CASE_AFTER_DEFAULT_CASE
   script:
     - "class C { foo(int a) {switch (a) {default: return 0; case 1: return 1;}} }"
 
 SwitchHasMultipleDefaults:
+  index: 15
   template: "The 'default' case can only be declared once."
   tip: "Try removing all but one default case."
-  analyzerCode: SWITCH_HAS_MULTIPLE_DEFAULT_CASES
+  analyzerCode: ParserErrorCode.SWITCH_HAS_MULTIPLE_DEFAULT_CASES
   script:
     - "class C { foo(int a) {switch (a) {default: return 0; default: return 1;}} }"
 
@@ -2168,6 +2274,37 @@
   template: "Type variables can't be used in static members."
   severity: ERROR_LEGACY_WARNING
   analyzerCode: TYPE_PARAMETER_REFERENCED_BY_STATIC
+  declaration:
+    - |
+      class C<T> {
+        static List<T> staticMethod() {}
+      }
+    - |
+      class C<T> {
+        static T staticMethod() {}
+      }
+    - |
+      class C<T> {
+        static staticMethod(List<T> argument) {}
+      }
+    - |
+      class C<T> {
+        static staticMethod(T argument) {}
+      }
+    - |
+      class C<T> {
+        static staticMethod() {
+          List<T> t = null;
+          return t;
+        }
+      }
+    - |
+      class C<T> {
+        static staticMethod() {
+          T t = null;
+          return t;
+        }
+      }
 
 TypeVariableInConstantContext:
   template: "Type variables can't be used as constants."
@@ -2256,9 +2393,10 @@
     - "class C { C() : x(3) {} }"
 
 RedirectingConstructorWithBody:
+  index: 22
   template: "Redirecting constructors can't have a body."
   tip: "Try removing the body, or not making this a redirecting constructor."
-  analyzerCode: REDIRECTING_CONSTRUCTOR_WITH_BODY
+  analyzerCode: ParserErrorCode.REDIRECTING_CONSTRUCTOR_WITH_BODY
   script:
     - "class C { C() : this.x() {} }"
 
@@ -2287,9 +2425,6 @@
   script:
     - "main(){ ++f(); }"
 
-CannotReadPackagesFile:
-  template: "Unable to read '.packages' file:\n  #string."
-
 CannotReadSdkSpecification:
   template: "Unable to read the 'libraries.json' specification file:\n  #string."
 
@@ -2698,3 +2833,26 @@
         factory A.f({int x = 42}) = A.g;
         A.g() {}
       }
+
+UntranslatableUri:
+  template: "Not found: '#uri'"
+  analyzerCode: URI_DOES_NOT_EXIST
+  script: |
+    import "dart:non_existing_library";
+
+    main() {
+    }
+
+CantReadFile:
+  template: "Error when reading '#uri': #string"
+  analyzerCode: URI_DOES_NOT_EXIST
+  external: test/packages_format_error_test.dart
+  script: |
+    import "non_existing_file.dart";
+
+    main() {
+    }
+
+PackagesFileFormat:
+  template: "Problem in packages configuration file: #string"
+  external: test/packages_format_error_test.dart
diff --git a/pkg/front_end/pubspec.yaml b/pkg/front_end/pubspec.yaml
index 77c908e..f87dfc4 100644
--- a/pkg/front_end/pubspec.yaml
+++ b/pkg/front_end/pubspec.yaml
@@ -1,7 +1,7 @@
 name: front_end
 # Currently, front_end API is not stable and users should not
 # depend on semver semantics when depending on this package.
-version: 0.1.4
+version: 0.1.5
 author: Dart Team <misc@dartlang.org>
 description: Front end for compilation of Dart code.
 homepage: https://github.com/dart-lang/sdk/tree/master/pkg/front_end
@@ -11,14 +11,14 @@
   charcode: '^1.1.1'
   convert: '^2.0.1'
   crypto: '^2.0.2'
-  kernel: 0.3.4
+  kernel: 0.3.5
   meta: '^1.1.1'
   package_config: '^1.0.1'
   path: '^1.3.9'
   source_span: '^1.2.3'
   yaml: '^2.1.12'
 dev_dependencies:
-  analyzer: '>=0.31.0 <0.33.0'
+  analyzer: '^0.33.0-alpha.0'
   args: '>=0.13.0 <2.0.0'
   build_integration:
     path: ../build_integration
diff --git a/pkg/front_end/test/fasta/generator_to_string_test.dart b/pkg/front_end/test/fasta/generator_to_string_test.dart
index 4beec7d..b8baa33 100644
--- a/pkg/front_end/test/fasta/generator_to_string_test.dart
+++ b/pkg/front_end/test/fasta/generator_to_string_test.dart
@@ -228,9 +228,7 @@
         "ParenthesizedExpressionGenerator(offset: 4, expression: expression,"
         " plainNameForRead: null, value: null)",
         new ParenthesizedExpressionGenerator(helper, token, expression));
-    check(
-        "TypeUseGenerator(offset: 4, expression: T,"
-        " plainNameForRead: foo, value: null)",
+    check("TypeUseGenerator(offset: 4, declaration: T, plainNameForRead: foo)",
         new KernelTypeUseGenerator(helper, token, declaration, "foo"));
     check("UnresolvedNameGenerator(offset: 4, name: bar)",
         new KernelUnresolvedNameGenerator(helper, token, name));
diff --git a/pkg/front_end/test/fasta/messages_test.dart b/pkg/front_end/test/fasta/messages_test.dart
index 54290a5..839bc54 100644
--- a/pkg/front_end/test/fasta/messages_test.dart
+++ b/pkg/front_end/test/fasta/messages_test.dart
@@ -183,6 +183,10 @@
             externalTest = node.value;
             break;
 
+          case "index":
+            // index is validated during generation
+            break;
+
           default:
             unknownKeys.add(key);
         }
diff --git a/pkg/front_end/test/fasta/parser/type_info_test.dart b/pkg/front_end/test/fasta/parser/type_info_test.dart
index ea5dfdc..90db70b 100644
--- a/pkg/front_end/test/fasta/parser/type_info_test.dart
+++ b/pkg/front_end/test/fasta/parser/type_info_test.dart
@@ -1390,19 +1390,6 @@
       'endTypeVariable > 0 extends',
       'endTypeVariables < >',
     ]);
-    expectComplexTypeParam('<S super T>', expectedCalls: [
-      'beginTypeVariables <',
-      'beginMetadataStar S',
-      'endMetadataStar 0',
-      'handleIdentifier S typeVariableDeclaration',
-      'beginTypeVariable S',
-      'handleTypeVariablesDefined T 1',
-      'handleIdentifier T typeReference',
-      'handleNoTypeArguments >',
-      'handleType T',
-      'endTypeVariable > 0 super',
-      'endTypeVariables < >',
-    ]);
     expectComplexTypeParam('<S extends List<T>>', expectedCalls: [
       'beginTypeVariables <',
       'beginMetadataStar S',
@@ -1517,6 +1504,24 @@
     ]);
   }
 
+  void test_computeTypeParam_complex_extends_void() {
+    expectComplexTypeParam('<T extends void>', expectedErrors: [
+      error(codeInvalidVoid, 11, 4),
+    ], expectedCalls: [
+      'beginTypeVariables <',
+      'beginMetadataStar T',
+      'endMetadataStar 0',
+      'handleIdentifier T typeVariableDeclaration',
+      'beginTypeVariable T',
+      'handleTypeVariablesDefined void 1',
+      'handleIdentifier void typeReference',
+      'handleNoTypeArguments >',
+      'handleType void',
+      'endTypeVariable > 0 extends',
+      'endTypeVariables < >'
+    ]);
+  }
+
   void test_computeTypeParam_complex_recovery() {
     expectComplexTypeParam('<S Function()>', expectedErrors: [
       error(codeUnexpectedToken, 3, 8),
diff --git a/pkg/front_end/test/fasta/testing/suite.dart b/pkg/front_end/test/fasta/testing/suite.dart
index 26527d4..02bf15a 100644
--- a/pkg/front_end/test/fasta/testing/suite.dart
+++ b/pkg/front_end/test/fasta/testing/suite.dart
@@ -6,23 +6,20 @@
 
 import 'dart:async' show Future;
 
-import 'dart:io' show File, Platform;
-
 import 'dart:convert' show jsonDecode;
 
-import 'package:front_end/src/api_prototype/standard_file_system.dart'
-    show StandardFileSystem;
-
-import 'package:front_end/src/base/libraries_specification.dart'
-    show TargetLibrariesSpecification;
-
-import 'package:front_end/src/fasta/testing/validating_instrumentation.dart'
-    show ValidatingInstrumentation;
-
-import 'package:front_end/src/fasta/uri_translator_impl.dart';
+import 'dart:io' show File, Platform;
 
 import 'package:kernel/ast.dart' show Library, Component;
 
+import 'package:kernel/class_hierarchy.dart' show ClassHierarchy;
+
+import 'package:kernel/core_types.dart' show CoreTypes;
+
+import 'package:kernel/kernel.dart' show loadComponentFromBytes;
+
+import 'package:kernel/target/targets.dart' show TargetFlags;
+
 import 'package:testing/testing.dart'
     show
         Chain,
@@ -34,9 +31,17 @@
         TestDescription,
         StdioProcess;
 
+import 'package:vm/target/vm.dart' show VmTarget;
+
 import 'package:front_end/src/api_prototype/compiler_options.dart'
     show CompilerOptions;
 
+import 'package:front_end/src/api_prototype/standard_file_system.dart'
+    show StandardFileSystem;
+
+import 'package:front_end/src/base/libraries_specification.dart'
+    show TargetLibrariesSpecification;
+
 import 'package:front_end/src/base/processed_options.dart'
     show ProcessedOptions;
 
@@ -48,27 +53,23 @@
 import 'package:front_end/src/fasta/deprecated_problems.dart'
     show deprecated_InputError;
 
+import 'package:front_end/src/fasta/dill/dill_target.dart' show DillTarget;
+
+import 'package:front_end/src/fasta/kernel/kernel_target.dart'
+    show KernelTarget;
+
 import 'package:front_end/src/fasta/testing/kernel_chain.dart'
     show MatchExpectation, Print, TypeCheck, Verify, WriteDill;
 
+import 'package:front_end/src/fasta/testing/validating_instrumentation.dart'
+    show ValidatingInstrumentation;
+
 import 'package:front_end/src/fasta/ticker.dart' show Ticker;
 
 import 'package:front_end/src/fasta/uri_translator.dart' show UriTranslator;
 
-import 'package:front_end/src/fasta/kernel/kernel_target.dart'
-    show KernelTarget;
-
-import 'package:front_end/src/fasta/dill/dill_target.dart' show DillTarget;
-
-import 'package:kernel/kernel.dart' show loadComponentFromBytes;
-
-import 'package:kernel/target/targets.dart' show TargetFlags;
-
-import 'package:kernel/class_hierarchy.dart' show ClassHierarchy;
-
-import 'package:kernel/core_types.dart' show CoreTypes;
-
-import 'package:vm/target/vm.dart' show VmTarget;
+import 'package:front_end/src/fasta/uri_translator_impl.dart'
+    show UriTranslatorImpl;
 
 export 'package:testing/testing.dart' show Chain, runMe;
 
diff --git a/pkg/front_end/test/incremental_load_from_dill_test.dart b/pkg/front_end/test/incremental_load_from_dill_test.dart
index 70f828e..68f91f0 100644
--- a/pkg/front_end/test/incremental_load_from_dill_test.dart
+++ b/pkg/front_end/test/incremental_load_from_dill_test.dart
@@ -35,6 +35,8 @@
 
 import 'package:kernel/target/targets.dart' show TargetFlags;
 
+import 'package:kernel/text/ast_to_text.dart' show componentToString;
+
 import "package:testing/testing.dart"
     show Chain, ChainContext, Result, Step, TestDescription, runMe;
 
@@ -277,6 +279,7 @@
     util.throwOnEmptyMixinBodies(component);
     print("Compile took ${stopwatch.elapsedMilliseconds} ms");
     newestWholeComponent = serializeComponent(component);
+    print("*****\n\ncomponent:\n${componentToString(component)}\n\n\n");
     if (component.libraries.length != world["expectedLibraryCount"]) {
       throw "Expected ${world["expectedLibraryCount"]} libraries, "
           "got ${component.libraries.length}";
@@ -317,6 +320,7 @@
       performErrorAndWarningCheck(
           world, gotError, formattedErrors, gotWarning, formattedWarnings);
       List<int> thisWholeComponent = serializeComponent(component2);
+      print("*****\n\ncomponent2:\n${componentToString(component2)}\n\n\n");
       checkIsEqual(newestWholeComponent, thisWholeComponent);
     }
   }
diff --git a/pkg/front_end/test/packages_format_error_test.dart b/pkg/front_end/test/packages_format_error_test.dart
new file mode 100644
index 0000000..f960378
--- /dev/null
+++ b/pkg/front_end/test/packages_format_error_test.dart
@@ -0,0 +1,43 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:async_helper/async_helper.dart' show asyncTest;
+
+import 'package:expect/expect.dart' show Expect;
+
+import 'package:front_end/src/api_prototype/compiler_options.dart'
+    show CompilerOptions, FormattedMessage;
+
+import 'package:front_end/src/api_prototype/memory_file_system.dart'
+    show MemoryFileSystem;
+
+import 'package:front_end/src/base/processed_options.dart'
+    show ProcessedOptions;
+
+import 'package:front_end/src/fasta/compiler_context.dart' show CompilerContext;
+
+main() {
+  Uri root = Uri.parse("org-dartlang-test:///");
+  MemoryFileSystem fs = new MemoryFileSystem(root);
+  Uri packages = root.resolve(".packages");
+  fs.entityForUri(packages).writeAsStringSync("bad\n");
+  List<FormattedMessage> messages = <FormattedMessage>[];
+  CompilerContext c =
+      new CompilerContext(new ProcessedOptions(new CompilerOptions()
+        ..fileSystem = fs
+        ..onProblem = (message, severity, context) {
+          messages.add(message);
+        }));
+  asyncTest(() async {
+    await c
+        .runInContext<void>((_) => c.options.createPackagesFromFile(packages));
+    Expect.stringEquals("PackagesFileFormat", messages.single.code.name);
+    messages.clear();
+
+    await c.runInContext<void>(
+        (_) => c.options.createPackagesFromFile(root.resolve("missing-file")));
+    Expect.stringEquals("CantReadFile", messages.single.code.name);
+    messages.clear();
+  });
+}
diff --git a/pkg/front_end/test/scanner_test.dart b/pkg/front_end/test/scanner_test.dart
index 9ad98df..9eb2956 100644
--- a/pkg/front_end/test/scanner_test.dart
+++ b/pkg/front_end/test/scanner_test.dart
@@ -302,11 +302,11 @@
     _assertToken(TokenType.HASH, "#");
   }
 
-  void test_hexidecimal() {
+  void test_hexadecimal() {
     _assertToken(TokenType.HEXADECIMAL, "0x1A2B3C");
   }
 
-  void test_hexidecimal_missingDigit() {
+  void test_hexadecimal_missingDigit() {
     _assertError(ScannerErrorCode.MISSING_HEX_DIGIT, 1, "0x");
   }
 
diff --git a/pkg/front_end/test/src/base/processed_options_test.dart b/pkg/front_end/test/src/base/processed_options_test.dart
index 2e74c1d..13c42fa 100644
--- a/pkg/front_end/test/src/base/processed_options_test.dart
+++ b/pkg/front_end/test/src/base/processed_options_test.dart
@@ -320,7 +320,7 @@
     var uriTranslator = await processed.getUriTranslator();
     expect(uriTranslator.packages.asMap(), isEmpty);
     expect(errors.single.message,
-        startsWith(_stringPrefixOf(templateCannotReadPackagesFile)));
+        startsWith(_stringPrefixOf(templateCantReadFile)));
   }
 
   test_validateOptions_noInputs() async {
@@ -344,9 +344,8 @@
       ..onError = (e) => errors.add(e);
     var options = new ProcessedOptions(raw, [Uri.parse('foo.dart')]);
     var result = await options.validateOptions();
-    expect(errors.single.message,
-        startsWith(_stringPrefixOf(templateInputFileNotFound)));
-    expect(result, isFalse);
+    expect(errors, isEmpty);
+    expect(result, isTrue);
   }
 
   test_validateOptions_root_exists() async {
diff --git a/pkg/front_end/testcases/compile.status b/pkg/front_end/testcases/compile.status
index ba0d63c..8f7efbe 100644
--- a/pkg/front_end/testcases/compile.status
+++ b/pkg/front_end/testcases/compile.status
@@ -6,28 +6,16 @@
 # testing generating Kernel ASTs directly, that is, code in
 # pkg/fasta/lib/src/kernel/.
 
-rasta/unsupported_platform_library: RuntimeError # OK, this must report an error at runtime.
-
 DeltaBlue: Fail # Fasta and dartk disagree on static initializers
+ambiguous_exports: RuntimeError # Expected, this file exports two main methods.
 bug31124: RuntimeError # Test has an intentional error
 call: Fail # Test can't run.
+co19_language_metadata_syntax_t04: RuntimeError # Fasta doesn't recover well
+constructor_const_inference: RuntimeError # Test exercises strong mode semantics.  See also Issue #33813.
+external_import: RuntimeError # Expected -- test uses import which doesn't exist.
 fallthrough: Fail # Missing FallThroughError.
 function_type_recovery: Fail
-invocations: Fail
-micro: Fail # External method marked abstract.
-named_parameters: Fail # Missing types and unnecessary default values.
-optional: Fail # Unnecessary default values.
-redirecting_factory: Fail # Missing types on constructor parameters.
-redirecting_factory_chain_test: Fail # Missing support for RedirectingFactoryConstructor.
-redirecting_factory_simple_test: Fail # Missing support for RedirectingFactoryConstructor.
-redirecting_factory_typeargs_test: Fail # Missing support for RedirectingFactoryConstructor.
-redirecting_factory_typeparam_test: Fail # Missing support for RedirectingFactoryConstructor.
-redirecting_factory_typeparambounds_test: Fail # Missing support for RedirectingFactoryConstructor.
-statements: Fail # Make async tranformer optional for golden file testing.
-type_variable_as_super: Fail
-uninitialized_fields: Fail # Fasta and dartk disagree on static initializers
-void_methods: Fail # Bad return from setters.
-
+incomplete_field_formal_parameter: Fail # Fasta doesn't recover well
 inference/bug31436: RuntimeError # Test exercises Dart 2.0 semantics
 inference/constructors_too_many_positional_arguments: Fail
 inference/downwards_inference_annotations_locals: Fail # Issue #30031
@@ -41,11 +29,13 @@
 inference/unsafe_block_closure_inference_function_call_explicit_dynamic_param_via_expr1: Fail
 inference/unsafe_block_closure_inference_function_call_explicit_type_param_via_expr1: Fail
 inference/unsafe_block_closure_inference_function_call_explicit_type_param_via_expr2: RuntimeError
-
 instantiate_to_bound/body_typedef_super_bounded_type: Fail # Issue 33444
 instantiate_to_bound/non_simple_class_parametrized_typedef_cycle: RuntimeError # May be related to Issue 33479
 instantiate_to_bound/typedef_super_bounded_type: Fail # Issue 33444
-
+invocations: Fail
+micro: Fail # External method marked abstract.
+named_parameters: Fail # Missing types and unnecessary default values.
+optional: Fail # Unnecessary default values.
 rasta/abstract_constructor: Fail
 rasta/bad_constructor_redirection: Fail
 rasta/bad_continue: Fail
@@ -62,7 +52,10 @@
 rasta/constant_get_and_invoke: Fail
 rasta/deferred_lib: Fail
 rasta/deferred_load: Fail
+rasta/duplicated_mixin: RuntimeError # Expected, this file has no main method.
+rasta/export: RuntimeError # Expected, this file has no main method.
 rasta/external_factory_redirection: Fail
+rasta/foo: RuntimeError # Expected, this file has no main method.
 rasta/for_loop: Fail
 rasta/generic_factory: Fail
 rasta/issue_000001: Fail
@@ -98,15 +91,20 @@
 rasta/unresolved_constructor: Fail
 rasta/unresolved_for_in: RuntimeError # Test contains a compile-time error, signaled at run time in the JIT VM
 rasta/unresolved_recovery: Fail
-
+redirecting_factory: Fail # Missing types on constructor parameters.
+redirecting_factory_chain_test: Fail # Missing support for RedirectingFactoryConstructor.
+redirecting_factory_const_inference: RuntimeError # Test exercises strong mode semantics.  See also Issue #33813.
+redirecting_factory_simple_test: Fail # Missing support for RedirectingFactoryConstructor.
+redirecting_factory_typeargs_test: Fail # Missing support for RedirectingFactoryConstructor.
+redirecting_factory_typeparam_test: Fail # Missing support for RedirectingFactoryConstructor.
+redirecting_factory_typeparambounds_test: Fail # Missing support for RedirectingFactoryConstructor.
 regress/issue_29975: Fail # Issue 29975.
 regress/issue_29976: RuntimeError # Issue 29976.
 regress/issue_29982: Fail # Issue 29982.
 regress/issue_30836: RuntimeError # Issue 30836.
-regress/issue_33452: RuntimeError # Test has an intentional error
 regress/issue_32972: RuntimeError
+regress/issue_33452: RuntimeError # Test has an intentional error
 regress/issue_34225: RuntimeError
-
 runtime_checks/implicit_downcast_constructor_initializer: RuntimeError # Test exercises strong mode semantics
 runtime_checks/implicit_downcast_do: RuntimeError # Test exercises strong mode semantics
 runtime_checks/implicit_downcast_for_condition: RuntimeError # Test exercises strong mode semantics
@@ -119,15 +117,7 @@
 runtime_checks_new/mixin_forwarding_stub_getter: RuntimeError # Test exercises strong mode semantics
 runtime_checks_new/mixin_forwarding_stub_setter: RuntimeError # Test exercises strong mode semantics
 runtime_checks_new/stub_checked_via_target: RuntimeError # Test exercises strong mode semantics
-constructor_const_inference: RuntimeError # Test exercises strong mode semantics.  See also Issue #33813.
-redirecting_factory_const_inference: RuntimeError # Test exercises strong mode semantics.  See also Issue #33813.
-
-ambiguous_exports: RuntimeError # Expected, this file exports two main methods.
-rasta/duplicated_mixin: RuntimeError # Expected, this file has no main method.
-rasta/export: RuntimeError # Expected, this file has no main method.
-rasta/foo: RuntimeError # Expected, this file has no main method.
-
-incomplete_field_formal_parameter: Fail # Fasta doesn't recover well
-
-co19_language_metadata_syntax_t04: RuntimeError # Fasta doesn't recover well
-external_import: RuntimeError # Expected -- test uses import which doesn't exist.
+statements: Fail # Make async tranformer optional for golden file testing.
+type_variable_as_super: Fail
+uninitialized_fields: Fail # Fasta and dartk disagree on static initializers
+void_methods: Fail # Bad return from setters.
diff --git a/pkg/front_end/testcases/deferred_type_annotation.dart b/pkg/front_end/testcases/deferred_type_annotation.dart
new file mode 100644
index 0000000..a3b00f5
--- /dev/null
+++ b/pkg/front_end/testcases/deferred_type_annotation.dart
@@ -0,0 +1,9 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for 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 'deferred_lib.dart' deferred as d;
+
+bad(d.C x) {}
+
+main() {}
diff --git a/pkg/front_end/testcases/deferred_type_annotation.dart.direct.expect b/pkg/front_end/testcases/deferred_type_annotation.dart.direct.expect
new file mode 100644
index 0000000..8e7b027
--- /dev/null
+++ b/pkg/front_end/testcases/deferred_type_annotation.dart.direct.expect
@@ -0,0 +1,6 @@
+library;
+import self as self;
+import "./deferred_lib.dart" as def;
+
+static method bad(def::C x) → dynamic {}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/deferred_type_annotation.dart.direct.transformed.expect b/pkg/front_end/testcases/deferred_type_annotation.dart.direct.transformed.expect
new file mode 100644
index 0000000..8e7b027
--- /dev/null
+++ b/pkg/front_end/testcases/deferred_type_annotation.dart.direct.transformed.expect
@@ -0,0 +1,6 @@
+library;
+import self as self;
+import "./deferred_lib.dart" as def;
+
+static method bad(def::C x) → dynamic {}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/deferred_type_annotation.dart.outline.expect b/pkg/front_end/testcases/deferred_type_annotation.dart.outline.expect
new file mode 100644
index 0000000..15a1fa3
--- /dev/null
+++ b/pkg/front_end/testcases/deferred_type_annotation.dart.outline.expect
@@ -0,0 +1,8 @@
+library;
+import self as self;
+import "./deferred_lib.dart" as def;
+
+static method bad(def::C x) → dynamic
+  ;
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/deferred_type_annotation.dart.strong.expect b/pkg/front_end/testcases/deferred_type_annotation.dart.strong.expect
new file mode 100644
index 0000000..c92a44c
--- /dev/null
+++ b/pkg/front_end/testcases/deferred_type_annotation.dart.strong.expect
@@ -0,0 +1,13 @@
+// Errors:
+//
+// pkg/front_end/testcases/deferred_type_annotation.dart:7:5: Error: The type '#lib1::C' is deferred loaded via prefix 'd' and can't be used as a type annotation.
+// Try removing 'deferred' from the import of 'd' or use a supertype of '#lib1::C' that isn't deferred.
+// bad(d.C x) {}
+//     ^^^
+
+library;
+import self as self;
+import "./deferred_lib.dart" as def;
+
+static method bad(def::C x) → dynamic {}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/deferred_type_annotation.dart.strong.transformed.expect b/pkg/front_end/testcases/deferred_type_annotation.dart.strong.transformed.expect
new file mode 100644
index 0000000..c92a44c
--- /dev/null
+++ b/pkg/front_end/testcases/deferred_type_annotation.dart.strong.transformed.expect
@@ -0,0 +1,13 @@
+// Errors:
+//
+// pkg/front_end/testcases/deferred_type_annotation.dart:7:5: Error: The type '#lib1::C' is deferred loaded via prefix 'd' and can't be used as a type annotation.
+// Try removing 'deferred' from the import of 'd' or use a supertype of '#lib1::C' that isn't deferred.
+// bad(d.C x) {}
+//     ^^^
+
+library;
+import self as self;
+import "./deferred_lib.dart" as def;
+
+static method bad(def::C x) → dynamic {}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/deleting_file.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/deleting_file.yaml
index 970db47..2933c37 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/deleting_file.yaml
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/deleting_file.yaml
@@ -24,7 +24,7 @@
     expectedLibraryCount: 2
   - entry: main.dart
     errors: true
-    warnings: false
+    warnings: true
     invalidate:
       - b.dart
     sources:
@@ -37,7 +37,7 @@
     expectedLibraryCount: 1
   - entry: main.dart
     errors: true
-    warnings: false
+    warnings: true
     checkInvalidatedFiles: false
     worldType: updated
     invalidate:
@@ -52,7 +52,7 @@
     expectedLibraryCount: 1
   - entry: main.dart
     errors: true
-    warnings: false
+    warnings: true
     checkInvalidatedFiles: false
     worldType: updated
     invalidate:
@@ -64,4 +64,4 @@
           print("Hello no. 1");
           b();
         }
-    expectedLibraryCount: 1
\ No newline at end of file
+    expectedLibraryCount: 1
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/invaldation_across_compile_time_error.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/invalidation_across_compile_time_error.yaml
similarity index 96%
rename from pkg/front_end/testcases/incremental_initialize_from_dill/invaldation_across_compile_time_error.yaml
rename to pkg/front_end/testcases/incremental_initialize_from_dill/invalidation_across_compile_time_error.yaml
index f1213e3..c627364 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/invaldation_across_compile_time_error.yaml
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/invalidation_across_compile_time_error.yaml
@@ -40,7 +40,7 @@
     sources:
       main.dart: |
         import "b.dart";
-        import "nonexistin.dart";
+        import "nonexisting.dart";
         main() {
           print("hello");
           b();
@@ -52,7 +52,7 @@
           c();
         }
     errors: true
-    expectedLibraryCount: 1
+    expectedLibraryCount: 3
   - entry: main.dart
     worldType: updated
     expectInitializeFromDill: false
@@ -66,4 +66,4 @@
           print("hello");
           b();
         }
-    expectedLibraryCount: 3
\ No newline at end of file
+    expectedLibraryCount: 3
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/updated_package_4.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/updated_package_4.yaml
index 84a4e54..b59c18e 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/updated_package_4.yaml
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/updated_package_4.yaml
@@ -32,4 +32,5 @@
     sources:
       .packages:
     errors: true
-    expectedLibraryCount: 1
\ No newline at end of file
+    warnings: true
+    expectedLibraryCount: 1
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_class_parametrized_typedef_cycle.dart.strong.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_class_parametrized_typedef_cycle.dart.strong.expect
new file mode 100644
index 0000000..6649d48
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_class_parametrized_typedef_cycle.dart.strong.expect
@@ -0,0 +1,18 @@
+// Errors:
+//
+// pkg/front_end/testcases/instantiate_to_bound/non_simple_class_parametrized_typedef_cycle.dart:11:9: Error: Generic type 'Fisk' can't be used without type arguments in the bounds of its own type variables. It is referenced indirectly through 'Hest'.
+// Try providing type arguments to 'Hest' here or to some other raw types in the bounds along the reference chain.
+// typedef Fisk = void Function<TypeY extends Hest>();
+//         ^^^^
+
+library;
+import self as self;
+import "dart:core" as core;
+
+typedef Fisk = <TypeY extends core::Object = dynamic>() → void;
+class Hest<TypeX extends <TypeY extends core::Object = dynamic>() → void = <TypeY extends core::Object = dynamic>() → void> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_class_parametrized_typedef_cycle.dart.strong.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_class_parametrized_typedef_cycle.dart.strong.transformed.expect
new file mode 100644
index 0000000..6649d48
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_class_parametrized_typedef_cycle.dart.strong.transformed.expect
@@ -0,0 +1,18 @@
+// Errors:
+//
+// pkg/front_end/testcases/instantiate_to_bound/non_simple_class_parametrized_typedef_cycle.dart:11:9: Error: Generic type 'Fisk' can't be used without type arguments in the bounds of its own type variables. It is referenced indirectly through 'Hest'.
+// Try providing type arguments to 'Hest' here or to some other raw types in the bounds along the reference chain.
+// typedef Fisk = void Function<TypeY extends Hest>();
+//         ^^^^
+
+library;
+import self as self;
+import "dart:core" as core;
+
+typedef Fisk = <TypeY extends core::Object = dynamic>() → void;
+class Hest<TypeX extends <TypeY extends core::Object = dynamic>() → void = <TypeY extends core::Object = dynamic>() → void> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_class_typedef_cycle.dart.strong.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_class_typedef_cycle.dart.strong.expect
index ed6b34a..af1c74a 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/non_simple_class_typedef_cycle.dart.strong.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_class_typedef_cycle.dart.strong.expect
@@ -4,16 +4,12 @@
 // Try providing type arguments to 'Hest' here or to some other raw types in the bounds along the reference chain.
 // typedef void Fisk<TypeY extends Hest>();
 //              ^^^^
-//
-// pkg/front_end/testcases/instantiate_to_bound/non_simple_class_typedef_cycle.dart:10:14: Error: The typedef 'Fisk' has a reference to itself.
-// typedef void Fisk<TypeY extends Hest>();
-//              ^
 
 library;
 import self as self;
 import "dart:core" as core;
 
-typedef Fisk<TypeY extends self::Hest<() → void> = dynamic> = () → void;
+typedef Fisk<TypeY extends core::Object = dynamic> = () → void;
 class Hest<TypeX extends () → void = () → void> extends core::Object {
   synthetic constructor •() → void
     : super core::Object::•()
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_class_typedef_cycle.dart.strong.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_class_typedef_cycle.dart.strong.transformed.expect
index ed6b34a..af1c74a 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/non_simple_class_typedef_cycle.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_class_typedef_cycle.dart.strong.transformed.expect
@@ -4,16 +4,12 @@
 // Try providing type arguments to 'Hest' here or to some other raw types in the bounds along the reference chain.
 // typedef void Fisk<TypeY extends Hest>();
 //              ^^^^
-//
-// pkg/front_end/testcases/instantiate_to_bound/non_simple_class_typedef_cycle.dart:10:14: Error: The typedef 'Fisk' has a reference to itself.
-// typedef void Fisk<TypeY extends Hest>();
-//              ^
 
 library;
 import self as self;
 import "dart:core" as core;
 
-typedef Fisk<TypeY extends self::Hest<() → void> = dynamic> = () → void;
+typedef Fisk<TypeY extends core::Object = dynamic> = () → void;
 class Hest<TypeX extends () → void = () → void> extends core::Object {
   synthetic constructor •() → void
     : super core::Object::•()
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_co_inductive.dart.strong.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_co_inductive.dart.strong.expect
index 8e72408..41104fc 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/non_simple_co_inductive.dart.strong.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_co_inductive.dart.strong.expect
@@ -9,7 +9,7 @@
 import self as self;
 import "dart:core" as core;
 
-class Hest<TypeX extends self::Hest<dynamic> = dynamic> extends core::Object {
+class Hest<TypeX extends core::Object = dynamic> extends core::Object {
   synthetic constructor •() → void
     : super core::Object::•()
     ;
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_co_inductive.dart.strong.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_co_inductive.dart.strong.transformed.expect
index 8e72408..41104fc 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/non_simple_co_inductive.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_co_inductive.dart.strong.transformed.expect
@@ -9,7 +9,7 @@
 import self as self;
 import "dart:core" as core;
 
-class Hest<TypeX extends self::Hest<dynamic> = dynamic> extends core::Object {
+class Hest<TypeX extends core::Object = dynamic> extends core::Object {
   synthetic constructor •() → void
     : super core::Object::•()
     ;
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_co_inductive_for_each.dart.strong.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_co_inductive_for_each.dart.strong.expect
index 9f68d44..4163521 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/non_simple_co_inductive_for_each.dart.strong.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_co_inductive_for_each.dart.strong.expect
@@ -14,7 +14,7 @@
 import self as self;
 import "dart:core" as core;
 
-class Hest<TypeX extends self::Hest<dynamic, dynamic> = dynamic, TypeY extends self::Hest<dynamic, dynamic> = dynamic> extends core::Object {
+class Hest<TypeX extends core::Object = dynamic, TypeY extends core::Object = dynamic> extends core::Object {
   synthetic constructor •() → void
     : super core::Object::•()
     ;
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_co_inductive_for_each.dart.strong.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_co_inductive_for_each.dart.strong.transformed.expect
index 9f68d44..4163521 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/non_simple_co_inductive_for_each.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_co_inductive_for_each.dart.strong.transformed.expect
@@ -14,7 +14,7 @@
 import self as self;
 import "dart:core" as core;
 
-class Hest<TypeX extends self::Hest<dynamic, dynamic> = dynamic, TypeY extends self::Hest<dynamic, dynamic> = dynamic> extends core::Object {
+class Hest<TypeX extends core::Object = dynamic, TypeY extends core::Object = dynamic> extends core::Object {
   synthetic constructor •() → void
     : super core::Object::•()
     ;
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_co_inductive_no_dup.dart.strong.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_co_inductive_no_dup.dart.strong.expect
index 89d0cb6..2616a8e 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/non_simple_co_inductive_no_dup.dart.strong.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_co_inductive_no_dup.dart.strong.expect
@@ -9,7 +9,7 @@
 import self as self;
 import "dart:core" as core;
 
-class Hest<TypeX extends core::Map<self::Hest<dynamic>, self::Hest<dynamic>> = dynamic> extends core::Object {
+class Hest<TypeX extends core::Object = dynamic> extends core::Object {
   synthetic constructor •() → void
     : super core::Object::•()
     ;
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_co_inductive_no_dup.dart.strong.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_co_inductive_no_dup.dart.strong.transformed.expect
index 89d0cb6..2616a8e 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/non_simple_co_inductive_no_dup.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_co_inductive_no_dup.dart.strong.transformed.expect
@@ -9,7 +9,7 @@
 import self as self;
 import "dart:core" as core;
 
-class Hest<TypeX extends core::Map<self::Hest<dynamic>, self::Hest<dynamic>> = dynamic> extends core::Object {
+class Hest<TypeX extends core::Object = dynamic> extends core::Object {
   synthetic constructor •() → void
     : super core::Object::•()
     ;
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_many_libs_same_name_cycle.dart.strong.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_many_libs_same_name_cycle.dart.strong.expect
index 835bb6a..6d5ff15 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/non_simple_many_libs_same_name_cycle.dart.strong.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_many_libs_same_name_cycle.dart.strong.expect
@@ -7,10 +7,9 @@
 
 library;
 import self as self;
-import "./non_simple_many_libs_same_name_cycle_lib.dart" as non;
 import "dart:core" as core;
 
-class Hest<TypeX extends non::Hest<self::Hest<dynamic>> = dynamic> extends core::Object {
+class Hest<TypeX extends core::Object = dynamic> extends core::Object {
   synthetic constructor •() → void
     : super core::Object::•()
     ;
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_many_libs_same_name_cycle.dart.strong.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_many_libs_same_name_cycle.dart.strong.transformed.expect
index 835bb6a..6d5ff15 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/non_simple_many_libs_same_name_cycle.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_many_libs_same_name_cycle.dart.strong.transformed.expect
@@ -7,10 +7,9 @@
 
 library;
 import self as self;
-import "./non_simple_many_libs_same_name_cycle_lib.dart" as non;
 import "dart:core" as core;
 
-class Hest<TypeX extends non::Hest<self::Hest<dynamic>> = dynamic> extends core::Object {
+class Hest<TypeX extends core::Object = dynamic> extends core::Object {
   synthetic constructor •() → void
     : super core::Object::•()
     ;
diff --git a/pkg/front_end/testcases/rasta/unsupported_platform_library.dart b/pkg/front_end/testcases/rasta/unsupported_platform_library.dart
index ca1de9b..fa8123d 100644
--- a/pkg/front_end/testcases/rasta/unsupported_platform_library.dart
+++ b/pkg/front_end/testcases/rasta/unsupported_platform_library.dart
@@ -4,3 +4,5 @@
 
 import 'dart:html';
 import 'dart:io';
+
+main() {}
diff --git a/pkg/front_end/testcases/rasta/unsupported_platform_library.dart.direct.expect b/pkg/front_end/testcases/rasta/unsupported_platform_library.dart.direct.expect
index 7073760..0c3e32a 100644
--- a/pkg/front_end/testcases/rasta/unsupported_platform_library.dart.direct.expect
+++ b/pkg/front_end/testcases/rasta/unsupported_platform_library.dart.direct.expect
@@ -1,6 +1,10 @@
+// Errors:
+//
+// pkg/front_end/testcases/rasta/unsupported_platform_library.dart:5:8: Error: Not found: 'dart:html'
+// import 'dart:html';
+//        ^
+
 library;
 import self as self;
 
-static method #main() → dynamic {
-  throw "dart:html:1: Error: Not found: dart:html.";
-}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/rasta/unsupported_platform_library.dart.direct.transformed.expect b/pkg/front_end/testcases/rasta/unsupported_platform_library.dart.direct.transformed.expect
index 7073760..0c3e32a 100644
--- a/pkg/front_end/testcases/rasta/unsupported_platform_library.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/rasta/unsupported_platform_library.dart.direct.transformed.expect
@@ -1,6 +1,10 @@
+// Errors:
+//
+// pkg/front_end/testcases/rasta/unsupported_platform_library.dart:5:8: Error: Not found: 'dart:html'
+// import 'dart:html';
+//        ^
+
 library;
 import self as self;
 
-static method #main() → dynamic {
-  throw "dart:html:1: Error: Not found: dart:html.";
-}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/rasta/unsupported_platform_library.dart.outline.expect b/pkg/front_end/testcases/rasta/unsupported_platform_library.dart.outline.expect
index cc97b3e..6a28c0d 100644
--- a/pkg/front_end/testcases/rasta/unsupported_platform_library.dart.outline.expect
+++ b/pkg/front_end/testcases/rasta/unsupported_platform_library.dart.outline.expect
@@ -1,2 +1,5 @@
 library;
 import self as self;
+
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/rasta/unsupported_platform_library.dart.strong.expect b/pkg/front_end/testcases/rasta/unsupported_platform_library.dart.strong.expect
new file mode 100644
index 0000000..0c3e32a
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/unsupported_platform_library.dart.strong.expect
@@ -0,0 +1,10 @@
+// Errors:
+//
+// pkg/front_end/testcases/rasta/unsupported_platform_library.dart:5:8: Error: Not found: 'dart:html'
+// import 'dart:html';
+//        ^
+
+library;
+import self as self;
+
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/rasta/unsupported_platform_library.dart.strong.transformed.expect b/pkg/front_end/testcases/rasta/unsupported_platform_library.dart.strong.transformed.expect
new file mode 100644
index 0000000..0c3e32a
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/unsupported_platform_library.dart.strong.transformed.expect
@@ -0,0 +1,10 @@
+// Errors:
+//
+// pkg/front_end/testcases/rasta/unsupported_platform_library.dart:5:8: Error: Not found: 'dart:html'
+// import 'dart:html';
+//        ^
+
+library;
+import self as self;
+
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/regress/issue_31188.dart.strong.expect b/pkg/front_end/testcases/regress/issue_31188.dart.strong.expect
index c9a4233..968f42b 100644
--- a/pkg/front_end/testcases/regress/issue_31188.dart.strong.expect
+++ b/pkg/front_end/testcases/regress/issue_31188.dart.strong.expect
@@ -12,13 +12,13 @@
 // type T = Map<A, B>
 // ^
 //
-// pkg/front_end/testcases/regress/issue_31188.dart:7:1: Error: 'type' isn't a type.
-// type T = Map<A, B>
-// ^^^^
-//
 // pkg/front_end/testcases/regress/issue_31188.dart:7:14: Error: Getter not found: 'A'.
 // type T = Map<A, B>
 //              ^
+//
+// pkg/front_end/testcases/regress/issue_31188.dart:7:1: Error: 'type' isn't a type.
+// type T = Map<A, B>
+// ^^^^
 
 library;
 import self as self;
diff --git a/pkg/front_end/testcases/regress/issue_31188.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_31188.dart.strong.transformed.expect
index b9f1830..2d9d977 100644
--- a/pkg/front_end/testcases/regress/issue_31188.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_31188.dart.strong.transformed.expect
@@ -12,13 +12,13 @@
 // type T = Map<A, B>
 // ^
 //
-// pkg/front_end/testcases/regress/issue_31188.dart:7:1: Error: 'type' isn't a type.
-// type T = Map<A, B>
-// ^^^^
-//
 // pkg/front_end/testcases/regress/issue_31188.dart:7:14: Error: Getter not found: 'A'.
 // type T = Map<A, B>
 //              ^
+//
+// pkg/front_end/testcases/regress/issue_31188.dart:7:1: Error: 'type' isn't a type.
+// type T = Map<A, B>
+// ^^^^
 
 library;
 import self as self;
diff --git a/pkg/front_end/testcases/strong.status b/pkg/front_end/testcases/strong.status
index 587ecbc..c1ac933 100644
--- a/pkg/front_end/testcases/strong.status
+++ b/pkg/front_end/testcases/strong.status
@@ -111,7 +111,6 @@
 inference_new/infer_field_override_getter_overrides_setter: TypeCheckError
 
 instantiate_to_bound/body_typedef_super_bounded_type: Fail # Issue 33444
-instantiate_to_bound/non_simple_class_parametrized_typedef_cycle: Crash # Issue 33479
 instantiate_to_bound/typedef_super_bounded_type: Fail # Issue 33444
 
 rasta/abstract_constructor: Fail
@@ -191,7 +190,6 @@
 rasta/unresolved_constructor: Fail
 rasta/unresolved_for_in: Fail
 rasta/unresolved_recovery: Fail
-rasta/unsupported_platform_library: Fail
 
 regress/issue_29975: Fail # Issue 29975.
 regress/issue_29976: TypeCheckError # Issue 29976.
diff --git a/pkg/front_end/testcases/type_variable_uses.dart.direct.expect b/pkg/front_end/testcases/type_variable_uses.dart.direct.expect
index a22eb9c..d9bcae3 100644
--- a/pkg/front_end/testcases/type_variable_uses.dart.direct.expect
+++ b/pkg/front_end/testcases/type_variable_uses.dart.direct.expect
@@ -1,85 +1,21 @@
 // Errors:
 //
-// pkg/front_end/testcases/type_variable_uses.dart:8:11: Error: Type variables can't be used in static members.
-//     print(T);
-//           ^
-//
-// pkg/front_end/testcases/type_variable_uses.dart:12:13: Error: Not a constant expression.
-//     const C<T>();
-//             ^
-//
-// pkg/front_end/testcases/type_variable_uses.dart:12:13: Error: Type variables can't be used in static members.
-//     const C<T>();
-//             ^
-//
-// pkg/front_end/testcases/type_variable_uses.dart:13:12: Error: Not a constant expression.
-//     const <T>[];
-//            ^
-//
-// pkg/front_end/testcases/type_variable_uses.dart:13:12: Error: Type variables can't be used in static members.
-//     const <T>[];
-//            ^
-//
-// pkg/front_end/testcases/type_variable_uses.dart:14:14: Error: Not a constant expression.
-//     const <C<T>>[];
-//              ^
-//
-// pkg/front_end/testcases/type_variable_uses.dart:14:14: Error: Type variables can't be used in static members.
-//     const <C<T>>[];
-//              ^
-//
-// pkg/front_end/testcases/type_variable_uses.dart:15:20: Error: Not a constant expression.
-//     const <Object>[T];
-//                    ^
-//
-// pkg/front_end/testcases/type_variable_uses.dart:15:20: Error: Type variables can't be used in static members.
-//     const <Object>[T];
-//                    ^
-//
-// pkg/front_end/testcases/type_variable_uses.dart:16:28: Error: Not a constant expression.
-//     const <Object>[const C<T>()];
-//                            ^
-//
-// pkg/front_end/testcases/type_variable_uses.dart:16:28: Error: Type variables can't be used in static members.
-//     const <Object>[const C<T>()];
-//                            ^
-//
-// pkg/front_end/testcases/type_variable_uses.dart:24:13: Error: Not a constant expression.
-//     const C<T>();
-//             ^
-//
 // pkg/front_end/testcases/type_variable_uses.dart:24:13: Error: Type variables can't be used as constants.
 //     const C<T>();
 //             ^
 //
-// pkg/front_end/testcases/type_variable_uses.dart:25:12: Error: Not a constant expression.
-//     const <T>[];
-//            ^
-//
 // pkg/front_end/testcases/type_variable_uses.dart:25:12: Error: Type variables can't be used as constants.
 //     const <T>[];
 //            ^
 //
-// pkg/front_end/testcases/type_variable_uses.dart:26:14: Error: Not a constant expression.
-//     const <C<T>>[];
-//              ^
-//
 // pkg/front_end/testcases/type_variable_uses.dart:26:14: Error: Type variables can't be used as constants.
 //     const <C<T>>[];
 //              ^
 //
-// pkg/front_end/testcases/type_variable_uses.dart:27:20: Error: Not a constant expression.
-//     const <Object>[T];
-//                    ^
-//
 // pkg/front_end/testcases/type_variable_uses.dart:27:20: Error: Type variables can't be used as constants.
 //     const <Object>[T];
 //                    ^
 //
-// pkg/front_end/testcases/type_variable_uses.dart:28:28: Error: Not a constant expression.
-//     const <Object>[const C<T>()];
-//                            ^
-//
 // pkg/front_end/testcases/type_variable_uses.dart:28:28: Error: Type variables can't be used as constants.
 //     const <Object>[const C<T>()];
 //                            ^
@@ -108,11 +44,11 @@
     self::C::T t;
     self::C<self::C::T> l;
     self::C<self::C<self::C::T>> ll;
-    const self::C::•<self::C::T>();
-    const <self::C::T>[];
-    const <self::C<self::C::T>>[];
-    const <core::Object>[self::C::T];
-    const <core::Object>[const self::C::•<self::C::T>()];
+    const self::C::•<invalid-type>();
+    const <invalid-type>[];
+    const <self::C<invalid-type>>[];
+    const <core::Object>[invalid-type];
+    const <core::Object>[const self::C::•<invalid-type>()];
   }
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/type_variable_uses.dart.direct.transformed.expect b/pkg/front_end/testcases/type_variable_uses.dart.direct.transformed.expect
index a22eb9c..d9bcae3 100644
--- a/pkg/front_end/testcases/type_variable_uses.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/type_variable_uses.dart.direct.transformed.expect
@@ -1,85 +1,21 @@
 // Errors:
 //
-// pkg/front_end/testcases/type_variable_uses.dart:8:11: Error: Type variables can't be used in static members.
-//     print(T);
-//           ^
-//
-// pkg/front_end/testcases/type_variable_uses.dart:12:13: Error: Not a constant expression.
-//     const C<T>();
-//             ^
-//
-// pkg/front_end/testcases/type_variable_uses.dart:12:13: Error: Type variables can't be used in static members.
-//     const C<T>();
-//             ^
-//
-// pkg/front_end/testcases/type_variable_uses.dart:13:12: Error: Not a constant expression.
-//     const <T>[];
-//            ^
-//
-// pkg/front_end/testcases/type_variable_uses.dart:13:12: Error: Type variables can't be used in static members.
-//     const <T>[];
-//            ^
-//
-// pkg/front_end/testcases/type_variable_uses.dart:14:14: Error: Not a constant expression.
-//     const <C<T>>[];
-//              ^
-//
-// pkg/front_end/testcases/type_variable_uses.dart:14:14: Error: Type variables can't be used in static members.
-//     const <C<T>>[];
-//              ^
-//
-// pkg/front_end/testcases/type_variable_uses.dart:15:20: Error: Not a constant expression.
-//     const <Object>[T];
-//                    ^
-//
-// pkg/front_end/testcases/type_variable_uses.dart:15:20: Error: Type variables can't be used in static members.
-//     const <Object>[T];
-//                    ^
-//
-// pkg/front_end/testcases/type_variable_uses.dart:16:28: Error: Not a constant expression.
-//     const <Object>[const C<T>()];
-//                            ^
-//
-// pkg/front_end/testcases/type_variable_uses.dart:16:28: Error: Type variables can't be used in static members.
-//     const <Object>[const C<T>()];
-//                            ^
-//
-// pkg/front_end/testcases/type_variable_uses.dart:24:13: Error: Not a constant expression.
-//     const C<T>();
-//             ^
-//
 // pkg/front_end/testcases/type_variable_uses.dart:24:13: Error: Type variables can't be used as constants.
 //     const C<T>();
 //             ^
 //
-// pkg/front_end/testcases/type_variable_uses.dart:25:12: Error: Not a constant expression.
-//     const <T>[];
-//            ^
-//
 // pkg/front_end/testcases/type_variable_uses.dart:25:12: Error: Type variables can't be used as constants.
 //     const <T>[];
 //            ^
 //
-// pkg/front_end/testcases/type_variable_uses.dart:26:14: Error: Not a constant expression.
-//     const <C<T>>[];
-//              ^
-//
 // pkg/front_end/testcases/type_variable_uses.dart:26:14: Error: Type variables can't be used as constants.
 //     const <C<T>>[];
 //              ^
 //
-// pkg/front_end/testcases/type_variable_uses.dart:27:20: Error: Not a constant expression.
-//     const <Object>[T];
-//                    ^
-//
 // pkg/front_end/testcases/type_variable_uses.dart:27:20: Error: Type variables can't be used as constants.
 //     const <Object>[T];
 //                    ^
 //
-// pkg/front_end/testcases/type_variable_uses.dart:28:28: Error: Not a constant expression.
-//     const <Object>[const C<T>()];
-//                            ^
-//
 // pkg/front_end/testcases/type_variable_uses.dart:28:28: Error: Type variables can't be used as constants.
 //     const <Object>[const C<T>()];
 //                            ^
@@ -108,11 +44,11 @@
     self::C::T t;
     self::C<self::C::T> l;
     self::C<self::C<self::C::T>> ll;
-    const self::C::•<self::C::T>();
-    const <self::C::T>[];
-    const <self::C<self::C::T>>[];
-    const <core::Object>[self::C::T];
-    const <core::Object>[const self::C::•<self::C::T>()];
+    const self::C::•<invalid-type>();
+    const <invalid-type>[];
+    const <self::C<invalid-type>>[];
+    const <core::Object>[invalid-type];
+    const <core::Object>[const self::C::•<invalid-type>()];
   }
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/type_variable_uses.dart.strong.expect b/pkg/front_end/testcases/type_variable_uses.dart.strong.expect
index 83deeb2..705fe6b 100644
--- a/pkg/front_end/testcases/type_variable_uses.dart.strong.expect
+++ b/pkg/front_end/testcases/type_variable_uses.dart.strong.expect
@@ -20,82 +20,42 @@
 //     C<C<T>> ll;
 //         ^
 //
-// pkg/front_end/testcases/type_variable_uses.dart:12:13: Error: Not a constant expression.
-//     const C<T>();
-//             ^
-//
 // pkg/front_end/testcases/type_variable_uses.dart:12:13: Error: Type variables can't be used in static members.
 //     const C<T>();
 //             ^
 //
-// pkg/front_end/testcases/type_variable_uses.dart:13:12: Error: Not a constant expression.
-//     const <T>[];
-//            ^
-//
 // pkg/front_end/testcases/type_variable_uses.dart:13:12: Error: Type variables can't be used in static members.
 //     const <T>[];
 //            ^
 //
-// pkg/front_end/testcases/type_variable_uses.dart:14:14: Error: Not a constant expression.
-//     const <C<T>>[];
-//              ^
-//
 // pkg/front_end/testcases/type_variable_uses.dart:14:14: Error: Type variables can't be used in static members.
 //     const <C<T>>[];
 //              ^
 //
-// pkg/front_end/testcases/type_variable_uses.dart:15:20: Error: Not a constant expression.
-//     const <Object>[T];
-//                    ^
-//
 // pkg/front_end/testcases/type_variable_uses.dart:15:20: Error: Type variables can't be used in static members.
 //     const <Object>[T];
 //                    ^
 //
-// pkg/front_end/testcases/type_variable_uses.dart:16:28: Error: Not a constant expression.
-//     const <Object>[const C<T>()];
-//                            ^
-//
 // pkg/front_end/testcases/type_variable_uses.dart:16:28: Error: Type variables can't be used in static members.
 //     const <Object>[const C<T>()];
 //                            ^
 //
-// pkg/front_end/testcases/type_variable_uses.dart:24:13: Error: Not a constant expression.
-//     const C<T>();
-//             ^
-//
 // pkg/front_end/testcases/type_variable_uses.dart:24:13: Error: Type variables can't be used as constants.
 //     const C<T>();
 //             ^
 //
-// pkg/front_end/testcases/type_variable_uses.dart:25:12: Error: Not a constant expression.
-//     const <T>[];
-//            ^
-//
 // pkg/front_end/testcases/type_variable_uses.dart:25:12: Error: Type variables can't be used as constants.
 //     const <T>[];
 //            ^
 //
-// pkg/front_end/testcases/type_variable_uses.dart:26:14: Error: Not a constant expression.
-//     const <C<T>>[];
-//              ^
-//
 // pkg/front_end/testcases/type_variable_uses.dart:26:14: Error: Type variables can't be used as constants.
 //     const <C<T>>[];
 //              ^
 //
-// pkg/front_end/testcases/type_variable_uses.dart:27:20: Error: Not a constant expression.
-//     const <Object>[T];
-//                    ^
-//
 // pkg/front_end/testcases/type_variable_uses.dart:27:20: Error: Type variables can't be used as constants.
 //     const <Object>[T];
 //                    ^
 //
-// pkg/front_end/testcases/type_variable_uses.dart:28:28: Error: Not a constant expression.
-//     const <Object>[const C<T>()];
-//                            ^
-//
 // pkg/front_end/testcases/type_variable_uses.dart:28:28: Error: Type variables can't be used as constants.
 //     const <Object>[const C<T>()];
 //                            ^
@@ -124,11 +84,11 @@
     self::C::T t;
     self::C<self::C::T> l;
     self::C<self::C<self::C::T>> ll;
-    const self::C::•<self::C::T>();
-    const <self::C::T>[];
-    const <self::C<self::C::T>>[];
-    const <core::Object>[self::C::T];
-    const <core::Object>[const self::C::•<self::C::T>()];
+    const self::C::•<invalid-type>();
+    const <invalid-type>[];
+    const <self::C<invalid-type>>[];
+    const <core::Object>[invalid-type];
+    const <core::Object>[const self::C::•<invalid-type>()];
   }
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/type_variable_uses.dart.strong.transformed.expect b/pkg/front_end/testcases/type_variable_uses.dart.strong.transformed.expect
index 83deeb2..705fe6b 100644
--- a/pkg/front_end/testcases/type_variable_uses.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/type_variable_uses.dart.strong.transformed.expect
@@ -20,82 +20,42 @@
 //     C<C<T>> ll;
 //         ^
 //
-// pkg/front_end/testcases/type_variable_uses.dart:12:13: Error: Not a constant expression.
-//     const C<T>();
-//             ^
-//
 // pkg/front_end/testcases/type_variable_uses.dart:12:13: Error: Type variables can't be used in static members.
 //     const C<T>();
 //             ^
 //
-// pkg/front_end/testcases/type_variable_uses.dart:13:12: Error: Not a constant expression.
-//     const <T>[];
-//            ^
-//
 // pkg/front_end/testcases/type_variable_uses.dart:13:12: Error: Type variables can't be used in static members.
 //     const <T>[];
 //            ^
 //
-// pkg/front_end/testcases/type_variable_uses.dart:14:14: Error: Not a constant expression.
-//     const <C<T>>[];
-//              ^
-//
 // pkg/front_end/testcases/type_variable_uses.dart:14:14: Error: Type variables can't be used in static members.
 //     const <C<T>>[];
 //              ^
 //
-// pkg/front_end/testcases/type_variable_uses.dart:15:20: Error: Not a constant expression.
-//     const <Object>[T];
-//                    ^
-//
 // pkg/front_end/testcases/type_variable_uses.dart:15:20: Error: Type variables can't be used in static members.
 //     const <Object>[T];
 //                    ^
 //
-// pkg/front_end/testcases/type_variable_uses.dart:16:28: Error: Not a constant expression.
-//     const <Object>[const C<T>()];
-//                            ^
-//
 // pkg/front_end/testcases/type_variable_uses.dart:16:28: Error: Type variables can't be used in static members.
 //     const <Object>[const C<T>()];
 //                            ^
 //
-// pkg/front_end/testcases/type_variable_uses.dart:24:13: Error: Not a constant expression.
-//     const C<T>();
-//             ^
-//
 // pkg/front_end/testcases/type_variable_uses.dart:24:13: Error: Type variables can't be used as constants.
 //     const C<T>();
 //             ^
 //
-// pkg/front_end/testcases/type_variable_uses.dart:25:12: Error: Not a constant expression.
-//     const <T>[];
-//            ^
-//
 // pkg/front_end/testcases/type_variable_uses.dart:25:12: Error: Type variables can't be used as constants.
 //     const <T>[];
 //            ^
 //
-// pkg/front_end/testcases/type_variable_uses.dart:26:14: Error: Not a constant expression.
-//     const <C<T>>[];
-//              ^
-//
 // pkg/front_end/testcases/type_variable_uses.dart:26:14: Error: Type variables can't be used as constants.
 //     const <C<T>>[];
 //              ^
 //
-// pkg/front_end/testcases/type_variable_uses.dart:27:20: Error: Not a constant expression.
-//     const <Object>[T];
-//                    ^
-//
 // pkg/front_end/testcases/type_variable_uses.dart:27:20: Error: Type variables can't be used as constants.
 //     const <Object>[T];
 //                    ^
 //
-// pkg/front_end/testcases/type_variable_uses.dart:28:28: Error: Not a constant expression.
-//     const <Object>[const C<T>()];
-//                            ^
-//
 // pkg/front_end/testcases/type_variable_uses.dart:28:28: Error: Type variables can't be used as constants.
 //     const <Object>[const C<T>()];
 //                            ^
@@ -124,11 +84,11 @@
     self::C::T t;
     self::C<self::C::T> l;
     self::C<self::C<self::C::T>> ll;
-    const self::C::•<self::C::T>();
-    const <self::C::T>[];
-    const <self::C<self::C::T>>[];
-    const <core::Object>[self::C::T];
-    const <core::Object>[const self::C::•<self::C::T>()];
+    const self::C::•<invalid-type>();
+    const <invalid-type>[];
+    const <self::C<invalid-type>>[];
+    const <core::Object>[invalid-type];
+    const <core::Object>[const self::C::•<invalid-type>()];
   }
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/tool/_fasta/generate_messages.dart b/pkg/front_end/tool/_fasta/generate_messages.dart
index ea27462..e95b6ad 100644
--- a/pkg/front_end/tool/_fasta/generate_messages.dart
+++ b/pkg/front_end/tool/_fasta/generate_messages.dart
@@ -45,6 +45,10 @@
 part of fasta.codes;
 """);
 
+  bool hasError = false;
+  int largestIndex = 0;
+  final indexNameMap = new Map<int, String>();
+
   List<String> keys = yaml.keys.cast<String>().toList()..sort();
   for (String name in keys) {
     var description = yaml[name];
@@ -55,9 +59,52 @@
     if (map == null) {
       throw "No 'template:' in key $name.";
     }
-    sb.writeln(compileTemplate(name, map['template'], map['tip'],
+    var index = map['index'];
+    if (index != null) {
+      if (index is! int || index < 1) {
+        print('Error: Expected positive int for "index:" field in $name,'
+            ' but found $index');
+        hasError = true;
+        index = -1;
+        // Continue looking for other problems.
+      } else {
+        String otherName = indexNameMap[index];
+        if (otherName != null) {
+          print('Error: The "index:" field must be unique, '
+              'but is the same for $otherName and $name');
+          hasError = true;
+          // Continue looking for other problems.
+        } else {
+          indexNameMap[index] = name;
+          if (largestIndex < index) {
+            largestIndex = index;
+          }
+        }
+      }
+    }
+    sb.writeln(compileTemplate(name, index, map['template'], map['tip'],
         map['analyzerCode'], map['severity']));
   }
+  if (largestIndex > indexNameMap.length) {
+    print('Error: The "index:" field values should be unique, consecutive'
+        ' whole numbers starting with 1.');
+    hasError = true;
+    // Fall through to print more information.
+  }
+  if (hasError) {
+    exitCode = 1;
+    print('The largest index is $largestIndex');
+    final sortedIndices = indexNameMap.keys.toList()..sort();
+    int nextAvailableIndex = largestIndex + 1;
+    for (int index = 1; index <= sortedIndices.length; ++index) {
+      if (sortedIndices[index - 1] != index) {
+        nextAvailableIndex = index;
+        break;
+      }
+    }
+    print('The next available index is ${nextAvailableIndex}');
+    return '';
+  }
 
   return new DartFormatter().format("$sb");
 }
@@ -65,7 +112,7 @@
 final RegExp placeholderPattern =
     new RegExp("#\([-a-zA-Z0-9_]+\)(?:%\([0-9]*\)\.\([0-9]+\))?");
 
-String compileTemplate(String name, String template, String tip,
+String compileTemplate(String name, int index, String template, String tip,
     String analyzerCode, String severity) {
   if (template == null) {
     print('Error: missing template for message: $name');
@@ -262,7 +309,11 @@
   }
 
   List<String> codeArguments = <String>[];
-  if (analyzerCode != null) {
+  if (index != null) {
+    codeArguments.add('index: $index');
+  } else if (analyzerCode != null) {
+    // If "index:" is defined, then "analyzerCode:" should not be generated
+    // in the front end. See comment in messages.yaml
     codeArguments.add('analyzerCode: "$analyzerCode"');
   }
   if (severity != null) {
diff --git a/pkg/front_end/tool/fasta_perf.dart b/pkg/front_end/tool/fasta_perf.dart
index ea099cd..4b9fb26 100644
--- a/pkg/front_end/tool/fasta_perf.dart
+++ b/pkg/front_end/tool/fasta_perf.dart
@@ -243,23 +243,7 @@
     options.sdkSummary = sdkRoot.resolve('outline.dill');
   }
 
-  var entrypoints = [
-    entryUri,
-    // These extra libraries are added to match the same set of libraries
-    // scanned by default by the VM and the other benchmarks.
-    Uri.parse('dart:async'),
-    Uri.parse('dart:collection'),
-    Uri.parse('dart:convert'),
-    Uri.parse('dart:core'),
-    Uri.parse('dart:developer'),
-    Uri.parse('dart:_internal'),
-    Uri.parse('dart:io'),
-    Uri.parse('dart:isolate'),
-    Uri.parse('dart:math'),
-    Uri.parse('dart:mirrors'),
-    Uri.parse('dart:typed_data'),
-  ];
-  var program = await kernelForComponent(entrypoints, options);
+  var program = await kernelForComponent([entryUri], options);
 
   timer.stop();
   var name = 'kernel_gen_e2e${compileSdk ? "" : "_sum"}';
diff --git a/pkg/kernel/binary.md b/pkg/kernel/binary.md
index 8f800cc..9aa8b60 100644
--- a/pkg/kernel/binary.md
+++ b/pkg/kernel/binary.md
@@ -131,7 +131,7 @@
 
 type ComponentFile {
   UInt32 magic = 0x90ABCDEF;
-  UInt32 formatVersion = 11;
+  UInt32 formatVersion = 12;
   Library[] libraries;
   UriSource sourceMap;
   List<CanonicalName> canonicalNames;
@@ -865,39 +865,45 @@
   StringReference value;
 }
 
-type MapConstant extends Constant {
+type SymbolConstant extends Constant {
   Byte tag = 5;
+  Option<LibraryReference> library;
+  StringReference name;
+}
+
+type MapConstant extends Constant {
+  Byte tag = 6;
   DartType keyType;
   DartType valueType;
   List<[ConstantReference, ConstantReference]> keyValueList;
 }
 
 type ListConstant extends Constant {
-  Byte tag = 6;
+  Byte tag = 7;
   DartType type;
   List<ConstantReference> values;
 }
 
 type InstanceConstant extends Constant {
-  Byte tag = 7;
+  Byte tag = 8;
   CanonicalNameReference class;
   List<DartType> typeArguments;
   List<[FieldReference, ConstantReference]> values;
 }
 
 type PartialInstantiationConstant extends Constant {
-  Byte tag = 8;
+  Byte tag = 9;
   ConstantReference tearOffConstant;
   List<DartType> typeArguments;
 }
 
 type TearOffConstant extends Constant {
-  Byte tag = 9;
+  Byte tag = 10;
   CanonicalNameReference staticProcedureReference;
 }
 
 type TypeLiteralConstant extends Constant {
-  Byte tag = 10;
+  Byte tag = 11;
   DartType type;
 }
 
diff --git a/pkg/kernel/lib/ast.dart b/pkg/kernel/lib/ast.dart
index 59c4823..03a709a 100644
--- a/pkg/kernel/lib/ast.dart
+++ b/pkg/kernel/lib/ast.dart
@@ -5073,6 +5073,34 @@
   DartType getType(TypeEnvironment types) => types.stringType;
 }
 
+class SymbolConstant extends Constant {
+  final String name;
+  final Reference libraryReference;
+
+  SymbolConstant(this.name, this.libraryReference);
+
+  visitChildren(Visitor v) {}
+
+  accept(ConstantVisitor v) => v.visitSymbolConstant(this);
+  acceptReference(Visitor v) => v.visitSymbolConstantReference(this);
+
+  String toString() {
+    return libraryReference != null
+        ? '#${libraryReference.asLibrary.importUri}::$name'
+        : '#$name';
+  }
+
+  int get hashCode => name.hashCode ^ libraryReference.hashCode;
+
+  bool operator ==(Object other) =>
+      identical(this, other) ||
+      (other is SymbolConstant &&
+          other.name == name &&
+          other.libraryReference == libraryReference);
+
+  DartType getType(TypeEnvironment types) => types.symbolType;
+}
+
 class MapConstant extends Constant {
   final DartType keyType;
   final DartType valueType;
diff --git a/pkg/kernel/lib/binary/ast_from_binary.dart b/pkg/kernel/lib/binary/ast_from_binary.dart
index db54b4a..70684ea 100644
--- a/pkg/kernel/lib/binary/ast_from_binary.dart
+++ b/pkg/kernel/lib/binary/ast_from_binary.dart
@@ -206,6 +206,12 @@
         return new DoubleConstant(readDouble());
       case ConstantTag.StringConstant:
         return new StringConstant(readStringReference());
+      case ConstantTag.SymbolConstant:
+        Reference libraryReference;
+        if (readAndCheckOptionTag()) {
+          libraryReference = readLibraryReference();
+        }
+        return new SymbolConstant(readStringReference(), libraryReference);
       case ConstantTag.MapConstant:
         final DartType keyType = readDartType();
         final DartType valueType = readDartType();
diff --git a/pkg/kernel/lib/binary/ast_to_binary.dart b/pkg/kernel/lib/binary/ast_to_binary.dart
index 528aeb95..7c0795a 100644
--- a/pkg/kernel/lib/binary/ast_to_binary.dart
+++ b/pkg/kernel/lib/binary/ast_to_binary.dart
@@ -164,6 +164,10 @@
     } else if (constant is StringConstant) {
       writeByte(ConstantTag.StringConstant);
       writeStringReference(constant.value);
+    } else if (constant is SymbolConstant) {
+      writeByte(ConstantTag.SymbolConstant);
+      writeOptionalReference(constant.libraryReference);
+      writeStringReference(constant.name);
     } else if (constant is MapConstant) {
       writeByte(ConstantTag.MapConstant);
       writeDartType(constant.keyType);
@@ -1877,6 +1881,16 @@
   }
 
   @override
+  void visitSymbolConstant(SymbolConstant node) {
+    throw new UnsupportedError('serialization of SymbolConstants');
+  }
+
+  @override
+  void visitSymbolConstantReference(SymbolConstant node) {
+    throw new UnsupportedError('serialization of SymbolConstant references');
+  }
+
+  @override
   void visitPartialInstantiationConstant(PartialInstantiationConstant node) {
     throw new UnsupportedError(
         'serialization of PartialInstantiationConstants ');
@@ -1997,6 +2011,8 @@
 
     if (constant is StringConstant) {
       stringIndexer.put(constant.value);
+    } else if (constant is SymbolConstant) {
+      stringIndexer.put(constant.name);
     } else if (constant is DoubleConstant) {
       stringIndexer.put('${constant.value}');
     } else if (constant is IntConstant) {
diff --git a/pkg/kernel/lib/binary/tag.dart b/pkg/kernel/lib/binary/tag.dart
index beb113c..aea6b2a 100644
--- a/pkg/kernel/lib/binary/tag.dart
+++ b/pkg/kernel/lib/binary/tag.dart
@@ -127,7 +127,7 @@
   /// Internal version of kernel binary format.
   /// Bump it when making incompatible changes in kernel binaries.
   /// Keep in sync with runtime/vm/kernel_binary.h, pkg/kernel/binary.md.
-  static const int BinaryFormatVersion = 11;
+  static const int BinaryFormatVersion = 12;
 }
 
 abstract class ConstantTag {
@@ -136,10 +136,11 @@
   static const int IntConstant = 2;
   static const int DoubleConstant = 3;
   static const int StringConstant = 4;
-  static const int MapConstant = 5;
-  static const int ListConstant = 6;
-  static const int InstanceConstant = 7;
-  static const int PartialInstantiationConstant = 8;
-  static const int TearOffConstant = 9;
-  static const int TypeLiteralConstant = 10;
+  static const int SymbolConstant = 5;
+  static const int MapConstant = 6;
+  static const int ListConstant = 7;
+  static const int InstanceConstant = 8;
+  static const int PartialInstantiationConstant = 9;
+  static const int TearOffConstant = 10;
+  static const int TypeLiteralConstant = 11;
 }
diff --git a/pkg/kernel/lib/target/targets.dart b/pkg/kernel/lib/target/targets.dart
index 38e7c2e..7d2f6bd 100644
--- a/pkg/kernel/lib/target/targets.dart
+++ b/pkg/kernel/lib/target/targets.dart
@@ -194,6 +194,12 @@
   Component configureComponent(Component component) => component;
 
   String toString() => 'Target($name)';
+
+  Class concreteListLiteralClass(CoreTypes coreTypes) => null;
+  Class concreteConstListLiteralClass(CoreTypes coreTypes) => null;
+
+  Class concreteMapLiteralClass(CoreTypes coreTypes) => null;
+  Class concreteConstMapLiteralClass(CoreTypes coreTypes) => null;
 }
 
 class NoneTarget extends Target {
diff --git a/pkg/kernel/lib/transformations/constants.dart b/pkg/kernel/lib/transformations/constants.dart
index d13f8ca..2d20281 100644
--- a/pkg/kernel/lib/transformations/constants.dart
+++ b/pkg/kernel/lib/transformations/constants.dart
@@ -1025,8 +1025,9 @@
   }
 
   visitSymbolLiteral(SymbolLiteral node) {
-    final value = canonicalize(new StringConstant(node.value));
-    return canonicalize(backend.buildSymbolConstant(value));
+    final libraryReference =
+        node.value.startsWith('_') ? libraryOf(node).reference : null;
+    return canonicalize(new SymbolConstant(node.value, libraryReference));
   }
 
   visitInstantiation(Instantiation node) {
@@ -1045,6 +1046,12 @@
         'Only tear-off constants can be partially instantiated.');
   }
 
+  @override
+  visitCheckLibraryIsLoaded(CheckLibraryIsLoaded node) {
+    errorReporter.deferredLibrary(contextChain, node, node.import.name);
+    throw const _AbortCurrentEvaluation();
+  }
+
   // Helper methods:
 
   void ensureIsSubtype(Constant constant, DartType type, TreeNode node) {
@@ -1187,6 +1194,15 @@
     }
     return value;
   }
+
+  Library libraryOf(TreeNode node) {
+    // The tree structure of the kernel AST ensures we always have an enclosing
+    // library.
+    while (true) {
+      if (node is Library) return node;
+      node = node.parent;
+    }
+  }
 }
 
 /// Holds the necessary information for a constant object, namely
@@ -1264,8 +1280,6 @@
       List<DartType> typeArguments,
       List<Constant> positionalArguments,
       Map<String, Constant> namedArguments);
-  Constant buildSymbolConstant(StringConstant value);
-
   Constant lowerListConstant(ListConstant constant);
   Constant lowerMapConstant(MapConstant constant);
 }
@@ -1297,6 +1311,7 @@
   failedAssertion(List<TreeNode> context, TreeNode node, String message);
   nonConstantVariableGet(
       List<TreeNode> context, TreeNode node, String variableName);
+  deferredLibrary(List<TreeNode> context, TreeNode node, String importName);
 }
 
 abstract class ErrorReporterBase implements ErrorReporter {
@@ -1408,6 +1423,14 @@
         'expression.',
         node);
   }
+
+  deferredLibrary(List<TreeNode> context, TreeNode node, String importName) {
+    report(
+        context,
+        'Deferred "$importName" cannot be used inside a constant '
+        'expression',
+        node);
+  }
 }
 
 class _SimpleErrorReporter extends ErrorReporterBase {
diff --git a/pkg/kernel/lib/visitor.dart b/pkg/kernel/lib/visitor.dart
index 13ae2ad..3133b20 100644
--- a/pkg/kernel/lib/visitor.dart
+++ b/pkg/kernel/lib/visitor.dart
@@ -269,6 +269,7 @@
   R visitIntConstant(IntConstant node) => defaultConstant(node);
   R visitDoubleConstant(DoubleConstant node) => defaultConstant(node);
   R visitStringConstant(StringConstant node) => defaultConstant(node);
+  R visitSymbolConstant(SymbolConstant node) => defaultConstant(node);
   R visitMapConstant(MapConstant node) => defaultConstant(node);
   R visitListConstant(ListConstant node) => defaultConstant(node);
   R visitInstanceConstant(InstanceConstant node) => defaultConstant(node);
@@ -321,6 +322,7 @@
   R visitIntConstant(IntConstant node) => defaultConstant(node);
   R visitDoubleConstant(DoubleConstant node) => defaultConstant(node);
   R visitStringConstant(StringConstant node) => defaultConstant(node);
+  R visitSymbolConstant(SymbolConstant node) => defaultConstant(node);
   R visitMapConstant(MapConstant node) => defaultConstant(node);
   R visitListConstant(ListConstant node) => defaultConstant(node);
   R visitInstanceConstant(InstanceConstant node) => defaultConstant(node);
@@ -345,6 +347,8 @@
       defaultConstantReference(node);
   R visitStringConstantReference(StringConstant node) =>
       defaultConstantReference(node);
+  R visitSymbolConstantReference(SymbolConstant node) =>
+      defaultConstantReference(node);
   R visitMapConstantReference(MapConstant node) =>
       defaultConstantReference(node);
   R visitListConstantReference(ListConstant node) =>
diff --git a/pkg/kernel/lib/vm/constants_native_effects.dart b/pkg/kernel/lib/vm/constants_native_effects.dart
index 0de29be..44f43eb 100644
--- a/pkg/kernel/lib/vm/constants_native_effects.dart
+++ b/pkg/kernel/lib/vm/constants_native_effects.dart
@@ -91,13 +91,6 @@
     throw 'No native effect registered for constant evaluation: $nativeName';
   }
 
-  Constant buildSymbolConstant(StringConstant value) {
-    return new InstanceConstant(
-        internalSymbolClass.reference,
-        const <DartType>[],
-        <Reference, Constant>{symbolNameField.reference: value});
-  }
-
   Constant lowerMapConstant(MapConstant constant) {
     // The _ImmutableMap class is implemented via one field pointing to a list
     // of key/value pairs -- see runtime/lib/immutable_map.dart!
diff --git a/pkg/kernel/pubspec.yaml b/pkg/kernel/pubspec.yaml
index 88429db..ef538e2 100644
--- a/pkg/kernel/pubspec.yaml
+++ b/pkg/kernel/pubspec.yaml
@@ -1,7 +1,7 @@
 name: kernel
 # Currently, kernel API is not stable and users should
 # not depend on semver semantics when depending on this package.
-version: 0.3.4
+version: 0.3.5
 author: Dart Team <misc@dartlang.org>
 description: Dart IR (Intermediate Representation)
 homepage: https://github.com/dart-lang/sdk/tree/master/pkg/kernel
@@ -13,8 +13,8 @@
   logging: ^0.11.2
   package_config: ^1.0.0
 dev_dependencies:
-  analyzer: '>=0.31.0 <0.33.0'
-  front_end: 0.1.4
+  analyzer: '^0.33.0-alpha.0'
+  front_end: 0.1.5
   test: ^0.12.15+6
   stack_trace: ^1.6.6
   test_reflective_loader: ^0.1.0
diff --git a/pkg/pkg.status b/pkg/pkg.status
index be355c6..70629d2 100644
--- a/pkg/pkg.status
+++ b/pkg/pkg.status
@@ -26,7 +26,6 @@
 analyzer/test/src/task/strong/checker_test: Slow, Pass
 analyzer_plugin/test/plugin/folding_mixin_test: Slow, Pass
 analyzer_plugin/tool/spec/check_all_test: Skip # Issue 29133
-dart_messages/test/dart_messages_test: Skip # Requires a package root.
 dev_compiler/test/options/*: Skip # test needs fixes
 dev_compiler/test/sourcemap/*: SkipByDesign # Skip sourcemap tests
 dev_compiler/test/sourcemap/testfiles/*: SkipByDesign # Skip dev_compiler codegen tests
@@ -133,6 +132,7 @@
 analysis_server/test/integration/analysis/package_root_test: Pass, RuntimeError # Issue 33382
 
 [ $system == windows ]
+analysis_server/test/integration/analysis/get_errors_nonStandard_sdk_test: Skip
 front_end/test/fasta/ast_builder_test: Pass, Slow, Timeout
 front_end/test/fasta/bootstrap_test: Skip # Issue 31902
 front_end/test/fasta/strong_test: Pass, Slow, Timeout
@@ -149,7 +149,6 @@
 analyzer/tool/task_dependency_graph/check_test: SkipByDesign # Uses dart:io.
 analyzer_cli/*: SkipByDesign # Uses dart:io.
 compiler/tool/*: SkipByDesign # Only meant to run on vm
-dart_messages/test/dart_messages_test: Skip # Uses dart:io.
 front_end/tool/*: SkipByDesign # Only meant to run on vm
 http_server/test/*: Fail, OK # Uses dart:io.
 kernel/test/*: SkipByDesign # Uses dart:io and bigints.
diff --git a/pkg/smith/lib/configuration.dart b/pkg/smith/lib/configuration.dart
index 6fdc73d..ea0b8d1 100644
--- a/pkg/smith/lib/configuration.dart
+++ b/pkg/smith/lib/configuration.dart
@@ -584,6 +584,7 @@
   static const precompiler = const Compiler._('precompiler');
   static const dart2js = const Compiler._('dart2js');
   static const dart2analyzer = const Compiler._('dart2analyzer');
+  static const compareAnalyzerCfe = const Compiler._('compare_analyzer_cfe');
   static const dartdevc = const Compiler._('dartdevc');
   static const dartdevk = const Compiler._('dartdevk');
   static const appJit = const Compiler._('app_jit');
@@ -601,6 +602,7 @@
     precompiler,
     dart2js,
     dart2analyzer,
+    compareAnalyzerCfe,
     dartdevc,
     dartdevk,
     appJit,
@@ -653,6 +655,7 @@
         ];
 
       case Compiler.dart2analyzer:
+      case Compiler.compareAnalyzerCfe:
         return const [Runtime.none];
       case Compiler.appJit:
       case Compiler.appJitk:
@@ -683,6 +686,7 @@
       case Compiler.dartdevk:
         return Runtime.chrome;
       case Compiler.dart2analyzer:
+      case Compiler.compareAnalyzerCfe:
         return Runtime.none;
       case Compiler.appJit:
       case Compiler.appJitk:
@@ -705,6 +709,7 @@
   Mode get defaultMode {
     switch (this) {
       case Compiler.dart2analyzer:
+      case Compiler.compareAnalyzerCfe:
       case Compiler.dart2js:
       case Compiler.dartdevc:
       case Compiler.dartdevk:
diff --git a/pkg/vm/bin/kernel_service.dart b/pkg/vm/bin/kernel_service.dart
index 704b7a8..e472da9 100644
--- a/pkg/vm/bin/kernel_service.dart
+++ b/pkg/vm/bin/kernel_service.dart
@@ -547,9 +547,6 @@
 }
 
 train(String scriptUri, String platformKernelPath) {
-  // TODO(28532): Enable on Windows.
-  if (Platform.isWindows) return;
-
   var tag = kTrainTag;
   var responsePort = new RawReceivePort();
   responsePort.handler = (response) {
diff --git a/pkg/vm/lib/bytecode/assembler.dart b/pkg/vm/lib/bytecode/assembler.dart
index 469682e..82b3c2a 100644
--- a/pkg/vm/lib/bytecode/assembler.dart
+++ b/pkg/vm/lib/bytecode/assembler.dart
@@ -221,6 +221,22 @@
     emitWord(_encodeD(Opcode.kPushConstant, rd));
   }
 
+  void emitPushNull() {
+    emitWord(_encode0(Opcode.kPushNull));
+  }
+
+  void emitPushTrue() {
+    emitWord(_encode0(Opcode.kPushTrue));
+  }
+
+  void emitPushFalse() {
+    emitWord(_encode0(Opcode.kPushFalse));
+  }
+
+  void emitPushInt(int rx) {
+    emitWord(_encodeX(Opcode.kPushInt, rx));
+  }
+
   void emitStoreLocal(int rx) {
     emitWord(_encodeX(Opcode.kStoreLocal, rx));
   }
diff --git a/pkg/vm/lib/bytecode/constant_pool.dart b/pkg/vm/lib/bytecode/constant_pool.dart
index 662f140..7560885 100644
--- a/pkg/vm/lib/bytecode/constant_pool.dart
+++ b/pkg/vm/lib/bytecode/constant_pool.dart
@@ -65,7 +65,8 @@
 
 type ConstantICData extends ConstantPoolEntry {
   Byte tag = 7;
-  Byte invocationKind; // Index in InvocationKind enum.
+  Byte flags(invocationKindBit0, invocationKindBit1, isDynamic);
+             // Where invocationKind is index into InvocationKind.
   Name targetName;
   ConstantIndex argDesc;
 }
@@ -161,6 +162,12 @@
   Byte tag = 24;
 }
 
+type ConstantSymbol extends ConstantPoolEntry {
+  Byte tag = 25;
+  Option<LibraryReference> library;
+  StringReference name;
+}
+
 */
 
 enum ConstantTag {
@@ -189,6 +196,7 @@
   kSubtypeTestCache,
   kPartialTearOffInstantiation,
   kEmptyTypeArguments,
+  kSymbol,
 }
 
 abstract class ConstantPoolEntry {
@@ -261,6 +269,8 @@
         return new ConstantPartialTearOffInstantiation.readFromBinary(source);
       case ConstantTag.kEmptyTypeArguments:
         return new ConstantEmptyTypeArguments.readFromBinary(source);
+      case ConstantTag.kSymbol:
+        return new ConstantSymbol.readFromBinary(source);
     }
     throw 'Unexpected constant tag $tag';
   }
@@ -485,30 +495,43 @@
 }
 
 class ConstantICData extends ConstantPoolEntry {
-  final InvocationKind invocationKind;
+  static const int invocationKindMask = 3;
+  static const int flagDynamic = 1 << 2;
+
+  final int _flags;
   final Name targetName;
   final int argDescConstantIndex;
 
   ConstantICData(
-      this.invocationKind, this.targetName, this.argDescConstantIndex);
+      InvocationKind invocationKind, this.targetName, this.argDescConstantIndex,
+      {bool isDynamic: false})
+      : assert(invocationKind.index <= invocationKindMask),
+        _flags = invocationKind.index | (isDynamic ? flagDynamic : 0);
+
+  InvocationKind get invocationKind =>
+      InvocationKind.values[_flags & invocationKindMask];
+
+  bool get isDynamic => (_flags & flagDynamic) != 0;
 
   @override
   ConstantTag get tag => ConstantTag.kICData;
 
   @override
   void writeValueToBinary(BinarySink sink) {
-    sink.writeByte(invocationKind.index);
+    sink.writeByte(_flags);
     sink.writeName(targetName);
     sink.writeUInt30(argDescConstantIndex);
   }
 
   ConstantICData.readFromBinary(BinarySource source)
-      : invocationKind = InvocationKind.values[source.readByte()],
+      : _flags = source.readByte(),
         targetName = source.readName(),
         argDescConstantIndex = source.readUInt();
 
   @override
-  String toString() => 'ICData ${_invocationKindToString(invocationKind)}'
+  String toString() => 'ICData '
+      '${isDynamic ? 'dynamic ' : ''}'
+      '${_invocationKindToString(invocationKind)}'
       'target-name \'$targetName\', arg-desc CP#$argDescConstantIndex';
 
   // ConstantICData entries are created per call site and should not be merged,
@@ -1086,6 +1109,41 @@
   bool operator ==(other) => other is ConstantEmptyTypeArguments;
 }
 
+class ConstantSymbol extends ConstantPoolEntry {
+  final Reference _libraryRef;
+  final String value;
+
+  ConstantSymbol(this._libraryRef, this.value);
+
+  @override
+  ConstantTag get tag => ConstantTag.kSymbol;
+
+  Library get library => _libraryRef?.asLibrary;
+
+  @override
+  void writeValueToBinary(BinarySink sink) {
+    sink.writeCanonicalNameReference(library?.canonicalName);
+    sink.writeStringReference(value);
+  }
+
+  ConstantSymbol.readFromBinary(BinarySource source)
+      : _libraryRef = source.readCanonicalNameReference()?.getReference(),
+        value = source.readStringReference();
+
+  @override
+  String toString() => 'Symbol '
+      '${library != null ? '$library::' : ''}\'$value\'';
+
+  @override
+  int get hashCode => value.hashCode;
+
+  @override
+  bool operator ==(other) =>
+      other is ConstantSymbol &&
+      this.value == other.value &&
+      this.library == other.library;
+}
+
 /// Reserved constant pool entry.
 class _ReservedConstantPoolEntry extends ConstantPoolEntry {
   const _ReservedConstantPoolEntry();
diff --git a/pkg/vm/lib/bytecode/dbc.dart b/pkg/vm/lib/bytecode/dbc.dart
index 000d960..8fd6b05 100644
--- a/pkg/vm/lib/bytecode/dbc.dart
+++ b/pkg/vm/lib/bytecode/dbc.dart
@@ -43,6 +43,8 @@
 // 12. JumpIfNotZeroTypeArgs instruction jumps if number of passed
 //     function type arguments is not zero.
 //
+// 13. PushNull, PushTrue, PushFalse, PushInt instructions added.
+//
 
 enum Opcode {
   kTrap,
@@ -65,6 +67,10 @@
   kLoadClassId,
   kLoadClassIdTOS,
   kPushConstant,
+  kPushNull,
+  kPushTrue,
+  kPushFalse,
+  kPushInt,
   kStoreLocal,
   kPopLocal,
   kIndirectStaticCall,
@@ -320,6 +326,14 @@
       Encoding.k0, const [Operand.none, Operand.none, Operand.none]),
   Opcode.kPushConstant: const Format(
       Encoding.kD, const [Operand.lit, Operand.none, Operand.none]),
+  Opcode.kPushNull: const Format(
+      Encoding.k0, const [Operand.none, Operand.none, Operand.none]),
+  Opcode.kPushTrue: const Format(
+      Encoding.k0, const [Operand.none, Operand.none, Operand.none]),
+  Opcode.kPushFalse: const Format(
+      Encoding.k0, const [Operand.none, Operand.none, Operand.none]),
+  Opcode.kPushInt: const Format(
+      Encoding.kX, const [Operand.imm, Operand.none, Operand.none]),
   Opcode.kStoreLocal: const Format(
       Encoding.kX, const [Operand.xeg, Operand.none, Operand.none]),
   Opcode.kPopLocal: const Format(
diff --git a/pkg/vm/lib/bytecode/gen_bytecode.dart b/pkg/vm/lib/bytecode/gen_bytecode.dart
index 1b228dd..7de7ecd 100644
--- a/pkg/vm/lib/bytecode/gen_bytecode.dart
+++ b/pkg/vm/lib/bytecode/gen_bytecode.dart
@@ -68,6 +68,7 @@
   Member enclosingMember;
   FunctionNode enclosingFunction;
   FunctionNode parentFunction;
+  bool isClosure;
   Set<TypeParameter> classTypeParameters;
   Set<TypeParameter> functionTypeParameters;
   List<DartType> instantiatorTypeArguments;
@@ -149,7 +150,7 @@
       } else {
         node.function?.body?.accept(this);
         // TODO(alexmarkov): figure out when 'return null' should be generated.
-        _genPushNull();
+        asm.emitPushNull();
       }
       _genReturnTOS();
       end(node);
@@ -295,17 +296,27 @@
     arguments.named.forEach((NamedExpression ne) => ne.value.accept(this));
   }
 
-  void _genPushNull() {
-    final cpIndex = cp.add(const ConstantNull());
-    asm.emitPushConstant(cpIndex);
+  void _genPushBool(bool value) {
+    if (value) {
+      asm.emitPushTrue();
+    } else {
+      asm.emitPushFalse();
+    }
   }
 
   void _genPushInt(int value) {
-    int cpIndex = cp.add(new ConstantInt(value));
-    asm.emitPushConstant(cpIndex);
+    if (value.bitLength + 1 <= 16) {
+      asm.emitPushInt(value);
+    } else {
+      int cpIndex = cp.add(new ConstantInt(value));
+      asm.emitPushConstant(cpIndex);
+    }
   }
 
   Constant _evaluateConstantExpression(Expression expr) {
+    if (expr is ConstantExpression) {
+      return expr.constant;
+    }
     final constant = constantEvaluator.evaluate(expr);
     if (constant == null) {
       // Compile-time error is already reported. Proceed with compilation
@@ -318,7 +329,15 @@
 
   void _genPushConstExpr(Expression expr) {
     final constant = _evaluateConstantExpression(expr);
-    asm.emitPushConstant(constant.accept(constantEmitter));
+    if (constant is NullConstant) {
+      asm.emitPushNull();
+    } else if (constant is BoolConstant) {
+      _genPushBool(constant.value);
+    } else if (constant is IntConstant) {
+      _genPushInt(constant.value);
+    } else {
+      asm.emitPushConstant(constant.accept(constantEmitter));
+    }
   }
 
   void _genReturnTOS() {
@@ -397,13 +416,13 @@
       assert(instantiatorTypeArguments != null);
       _genPushInstantiatorTypeArguments();
     } else {
-      _genPushNull();
+      asm.emitPushNull();
     }
     if (functionTypeParameters != null &&
         types.any((t) => containsTypeVariable(t, functionTypeParameters))) {
       _genPushFunctionTypeArguments();
     } else {
-      _genPushNull();
+      asm.emitPushNull();
     }
   }
 
@@ -420,7 +439,7 @@
         asm.emitLoadTypeArgumentsField(cpIndex);
       }
     } else {
-      _genPushNull();
+      asm.emitPushNull();
     }
   }
 
@@ -498,7 +517,7 @@
     if (locals.hasFunctionTypeArgsVar) {
       asm.emitPush(locals.functionTypeArgsVarIndexInFrame);
     } else {
-      _genPushNull();
+      asm.emitPushNull();
     }
   }
 
@@ -560,7 +579,7 @@
   }
 
   void _genJumpIfFalse(bool negated, Label dest) {
-    asm.emitPushConstant(cp.add(new ConstantBool(true)));
+    asm.emitPushTrue();
     if (negated) {
       asm.emitIfEqStrictTOS(); // if ((!condition) == true) ...
     } else {
@@ -594,7 +613,7 @@
   void _genInstanceOf(DartType type) {
     if (typeEnvironment.isTop(type)) {
       asm.emitDrop1();
-      asm.emitPushConstant(cp.add(new ConstantBool(true)));
+      asm.emitPushTrue();
       return;
     }
 
@@ -603,8 +622,8 @@
     if (hasFreeTypeParameters([type])) {
       _genPushInstantiatorAndFunctionTypeArguments([type]);
     } else {
-      _genPushNull(); // Instantiator type arguments.
-      _genPushNull(); // Function type arguments.
+      asm.emitPushNull(); // Instantiator type arguments.
+      asm.emitPushNull(); // Function type arguments.
     }
     asm.emitPushConstant(cp.add(new ConstantType(type)));
     final argDescIndex = cp.add(new ConstantArgDesc(4));
@@ -618,6 +637,7 @@
     enclosingMember = node;
     enclosingFunction = node.function;
     parentFunction = null;
+    isClosure = false;
     hasErrors = false;
     final isFactory = node is Procedure && node.isFactory;
     if (node.isInstanceMember || node is Constructor || isFactory) {
@@ -684,11 +704,11 @@
     Label done = new Label();
 
     _genLoadVar(member.function.positionalParameters[0]);
-    _genPushNull();
+    asm.emitPushNull();
     asm.emitIfNeStrictTOS();
     asm.emitJump(done);
 
-    asm.emitPushConstant(cp.add(new ConstantBool(false)));
+    asm.emitPushFalse();
     _genReturnTOS();
 
     asm.bind(done);
@@ -704,6 +724,7 @@
     enclosingMember = null;
     enclosingFunction = null;
     parentFunction = null;
+    isClosure = null;
     classTypeParameters = null;
     functionTypeParameters = null;
     instantiatorTypeArguments = null;
@@ -724,9 +745,6 @@
   }
 
   void _genPrologue(Node node, FunctionNode function) {
-    final bool isClosure =
-        node is FunctionDeclaration || node is FunctionExpression;
-
     if (locals.hasOptionalParameters) {
       final int numOptionalPositional = function.positionalParameters.length -
           function.requiredParameterCount;
@@ -780,7 +798,7 @@
         asm.emitCheckFunctionTypeArgs(function.typeParameters.length,
             locals.functionTypeArgsVarIndexInFrame);
 
-        _handleDefaultTypeArguments(function, isClosure, done);
+        _handleDefaultTypeArguments(function, done);
 
         asm.bind(done);
       }
@@ -827,7 +845,7 @@
   }
 
   void _handleDefaultTypeArguments(
-      FunctionNode function, bool isClosure, Label doneCheckingTypeArguments) {
+      FunctionNode function, Label doneCheckingTypeArguments) {
     bool hasNonDynamicDefaultTypes = function.typeParameters.any(
         (p) => p.defaultType != null && p.defaultType != const DynamicType());
     if (!hasNonDynamicDefaultTypes) {
@@ -860,7 +878,6 @@
 
     if (locals.hasCapturedParameters) {
       // Copy captured parameters to their respective locations in the context.
-      final isClosure = parentFunction != null;
       if (!isClosure) {
         if (locals.hasFactoryTypeArgsVar) {
           _copyParamIfCaptured(locals.factoryTypeArgsVar);
@@ -886,23 +903,166 @@
     }
   }
 
-  void _checkArguments(FunctionNode function) {
-    for (var typeParam in function.typeParameters) {
-      if (!typeEnvironment.isTop(typeParam.bound)) {
-        final DartType type = new TypeParameterType(typeParam);
-        _genPushInstantiatorAndFunctionTypeArguments([type, typeParam.bound]);
-        asm.emitPushConstant(cp.add(new ConstantType(type)));
-        asm.emitPushConstant(cp.add(new ConstantType(typeParam.bound)));
-        asm.emitPushConstant(cp.add(new ConstantString(typeParam.name)));
-        asm.emitAssertSubtype();
+  // TODO(alexmarkov): Revise if we need to AOT-compile from bytecode.
+  bool get canSkipTypeChecksForNonCovariantArguments =>
+      !isClosure && enclosingMember.name.name != 'call';
+
+  Member _getForwardingStubSuperTarget() {
+    if (!isClosure) {
+      final member = enclosingMember;
+      if (member.isInstanceMember &&
+          member is Procedure &&
+          member.isForwardingStub) {
+        return member.forwardingStubSuperTarget;
       }
     }
-    function.positionalParameters.forEach(_genArgumentTypeCheck);
-    locals.sortedNamedParameters.forEach(_genArgumentTypeCheck);
+    return null;
   }
 
-  void _genArgumentTypeCheck(VariableDeclaration variable) {
-    if (typeEnvironment.isTop(variable.type)) {
+  // Types in a target of a forwarding stub are encoded in terms of target type
+  // parameters. Substitute them with host type parameters to be able
+  // to use them (e.g. instantiate) in the context of host.
+  Substitution _getForwardingSubstitution(
+      FunctionNode host, Member forwardingTarget) {
+    if (forwardingTarget == null) {
+      return null;
+    }
+    final Class targetClass = forwardingTarget.enclosingClass;
+    final Supertype instantiatedTargetClass =
+        hierarchy.getClassAsInstanceOf(enclosingClass, targetClass);
+    if (instantiatedTargetClass == null) {
+      throw 'Class $targetClass is not found among implemented interfaces of'
+          ' $enclosingClass (for forwarding stub $enclosingMember)';
+    }
+    assert(instantiatedTargetClass.classNode == targetClass);
+    assert(instantiatedTargetClass.typeArguments.length ==
+        targetClass.typeParameters.length);
+    final Map<TypeParameter, DartType> map =
+        new Map<TypeParameter, DartType>.fromIterables(
+            targetClass.typeParameters, instantiatedTargetClass.typeArguments);
+    if (forwardingTarget.function != null) {
+      final targetTypeParameters = forwardingTarget.function.typeParameters;
+      assert(host.typeParameters.length == targetTypeParameters.length);
+      for (int i = 0; i < targetTypeParameters.length; ++i) {
+        map[targetTypeParameters[i]] =
+            new TypeParameterType(host.typeParameters[i]);
+      }
+    }
+    return Substitution.fromMap(map);
+  }
+
+  /// If member being compiled is a forwarding stub, then returns type
+  /// parameter bounds to check for the forwarding stub target.
+  Map<TypeParameter, DartType> _getForwardingBounds(FunctionNode function,
+      Member forwardingTarget, Substitution forwardingSubstitution) {
+    if (function.typeParameters.isEmpty || forwardingTarget == null) {
+      return null;
+    }
+    final forwardingBounds = <TypeParameter, DartType>{};
+    for (int i = 0; i < function.typeParameters.length; ++i) {
+      DartType bound = forwardingSubstitution
+          .substituteType(forwardingTarget.function.typeParameters[i].bound);
+      forwardingBounds[function.typeParameters[i]] = bound;
+    }
+    return forwardingBounds;
+  }
+
+  /// If member being compiled is a forwarding stub, then returns parameter
+  /// types to check for the forwarding stub target.
+  Map<VariableDeclaration, DartType> _getForwardingParameterTypes(
+      FunctionNode function,
+      Member forwardingTarget,
+      Substitution forwardingSubstitution) {
+    if (forwardingTarget == null) {
+      return null;
+    }
+
+    if (forwardingTarget is Field) {
+      if ((enclosingMember as Procedure).isGetter) {
+        return const <VariableDeclaration, DartType>{};
+      } else {
+        // Forwarding stub for a covariant field setter.
+        assert((enclosingMember as Procedure).isSetter);
+        assert(function.typeParameters.isEmpty &&
+            function.positionalParameters.length == 1 &&
+            function.namedParameters.length == 0);
+        return <VariableDeclaration, DartType>{
+          function.positionalParameters.single:
+              forwardingSubstitution.substituteType(forwardingTarget.type)
+        };
+      }
+    }
+
+    final forwardingParams = <VariableDeclaration, DartType>{};
+    for (int i = 0; i < function.positionalParameters.length; ++i) {
+      DartType type = forwardingSubstitution.substituteType(
+          forwardingTarget.function.positionalParameters[i].type);
+      forwardingParams[function.positionalParameters[i]] = type;
+    }
+    for (var hostParam in function.namedParameters) {
+      VariableDeclaration targetParam = forwardingTarget
+          .function.namedParameters
+          .firstWhere((p) => p.name == hostParam.name);
+      forwardingParams[hostParam] =
+          forwardingSubstitution.substituteType(targetParam.type);
+    }
+    return forwardingParams;
+  }
+
+  void _checkArguments(FunctionNode function) {
+    // When checking arguments of a forwarding stub, we need to use parameter
+    // types (and bounds of type parameters) from stub's target.
+    // These more accurate type checks is the sole purpose of a forwarding stub.
+    final forwardingTarget = _getForwardingStubSuperTarget();
+    final forwardingSubstitution =
+        _getForwardingSubstitution(function, forwardingTarget);
+    final forwardingBounds = _getForwardingBounds(
+        function, forwardingTarget, forwardingSubstitution);
+    final forwardingParamTypes = _getForwardingParameterTypes(
+        function, forwardingTarget, forwardingSubstitution);
+
+    for (var typeParam in function.typeParameters) {
+      _genTypeParameterBoundCheck(typeParam, forwardingBounds);
+    }
+    for (var param in function.positionalParameters) {
+      _genArgumentTypeCheck(param, forwardingParamTypes);
+    }
+    for (var param in locals.sortedNamedParameters) {
+      _genArgumentTypeCheck(param, forwardingParamTypes);
+    }
+  }
+
+  void _genTypeParameterBoundCheck(TypeParameter typeParam,
+      Map<TypeParameter, DartType> forwardingTypeParameterBounds) {
+    if (canSkipTypeChecksForNonCovariantArguments &&
+        !typeParam.isGenericCovariantImpl) {
+      return;
+    }
+    final DartType bound = (forwardingTypeParameterBounds != null)
+        ? forwardingTypeParameterBounds[typeParam]
+        : typeParam.bound;
+    if (typeEnvironment.isTop(bound)) {
+      return;
+    }
+    final DartType type = new TypeParameterType(typeParam);
+    _genPushInstantiatorAndFunctionTypeArguments([type, bound]);
+    asm.emitPushConstant(cp.add(new ConstantType(type)));
+    asm.emitPushConstant(cp.add(new ConstantType(bound)));
+    asm.emitPushConstant(cp.add(new ConstantString(typeParam.name)));
+    asm.emitAssertSubtype();
+  }
+
+  void _genArgumentTypeCheck(VariableDeclaration variable,
+      Map<VariableDeclaration, DartType> forwardingParameterTypes) {
+    if (canSkipTypeChecksForNonCovariantArguments &&
+        !variable.isCovariant &&
+        !variable.isGenericCovariantImpl) {
+      return;
+    }
+    final DartType type = (forwardingParameterTypes != null)
+        ? forwardingParameterTypes[variable]
+        : variable.type;
+    if (typeEnvironment.isTop(type)) {
       return;
     }
     if (locals.isCaptured(variable)) {
@@ -910,7 +1070,7 @@
     } else {
       asm.emitPush(locals.getVarIndexInFrame(variable));
     }
-    _genAssertAssignable(variable.type, name: variable.name);
+    _genAssertAssignable(type, name: variable.name);
     asm.emitDrop1();
   }
 
@@ -947,6 +1107,8 @@
 
     final savedParentFunction = parentFunction;
     parentFunction = enclosingFunction;
+    final savedIsClosure = isClosure;
+    isClosure = true;
     enclosingFunction = function;
 
     if (function.typeParameters.isNotEmpty) {
@@ -985,7 +1147,7 @@
     function.body.accept(this);
 
     // TODO(alexmarkov): figure out when 'return null' should be generated.
-    _genPushNull();
+    asm.emitPushNull();
     _genReturnTOS();
 
     if (locals.isSyncYieldingFrame) {
@@ -1001,6 +1163,7 @@
 
     enclosingFunction = parentFunction;
     parentFunction = savedParentFunction;
+    isClosure = savedIsClosure;
 
     locals.leaveScope();
 
@@ -1021,7 +1184,7 @@
 
     // if (switch_var != 0) goto continuationLabel
     _genPushInt(0);
-    asm.emitIfNeStrictNumTOS();
+    asm.emitIfNeStrictTOS();
     asm.emitJump(continuationLabel);
 
     // Proceed to normal entry.
@@ -1049,7 +1212,7 @@
       if (i != yieldPoints.length - 1) {
         asm.emitPush(switchVarIndexInFrame);
         _genPushInt(index);
-        asm.emitIfEqStrictNumTOS();
+        asm.emitIfEqStrictTOS();
       }
 
       asm.emitJump(yieldPoints[i]);
@@ -1254,7 +1417,7 @@
     _createArgumentsArray(temp, typeArgs, args, storeLastArgumentToTemp);
 
     // Argument 3 for _allocateInvocationMirror(): isSuperInvocation flag.
-    asm.emitPushConstant(cp.add(new ConstantBool(true)));
+    asm.emitPushTrue();
 
     _genStaticCall(allocateInvocationMirror, new ConstantArgDesc(4), 4);
 
@@ -1290,14 +1453,12 @@
 
   @override
   visitBoolLiteral(BoolLiteral node) {
-    final cpIndex = cp.add(new ConstantBool.fromLiteral(node));
-    asm.emitPushConstant(cpIndex);
+    _genPushBool(node.value);
   }
 
   @override
   visitIntLiteral(IntLiteral node) {
-    final cpIndex = cp.add(new ConstantInt.fromLiteral(node));
-    asm.emitPushConstant(cpIndex);
+    _genPushInt(node.value);
   }
 
   @override
@@ -1508,7 +1669,7 @@
     final isOR = (node.operator == '||');
 
     bool negated = _genCondition(node.left);
-    asm.emitPushConstant(cp.add(new ConstantBool(true)));
+    asm.emitPushTrue();
     if (negated != isOR) {
       // OR: if (condition == true)
       // AND: if ((!condition) == true)
@@ -1528,7 +1689,7 @@
     asm.emitJump(done);
 
     asm.bind(shortCircuit);
-    asm.emitPushConstant(cp.add(new ConstantBool(isOR)));
+    _genPushBool(isOR);
     asm.emitPopLocal(temp);
 
     asm.bind(done);
@@ -1583,8 +1744,9 @@
     // TODO(alexmarkov): fast path smi ops
     final argDescIndex =
         cp.add(new ConstantArgDesc.fromArguments(args, hasReceiver: true));
-    final icdataIndex = cp.add(
-        new ConstantICData(InvocationKind.method, node.name, argDescIndex));
+    final icdataIndex = cp.add(new ConstantICData(
+        InvocationKind.method, node.name, argDescIndex,
+        isDynamic: node.interfaceTarget == null));
     final totalArgCount = args.positional.length +
         args.named.length +
         1 /* receiver */ +
@@ -1596,8 +1758,9 @@
   visitPropertyGet(PropertyGet node) {
     node.receiver.accept(this);
     final argDescIndex = cp.add(new ConstantArgDesc(1));
-    final icdataIndex = cp.add(
-        new ConstantICData(InvocationKind.getter, node.name, argDescIndex));
+    final icdataIndex = cp.add(new ConstantICData(
+        InvocationKind.getter, node.name, argDescIndex,
+        isDynamic: node.interfaceTarget == null));
     asm.emitInstanceCall(1, icdataIndex);
   }
 
@@ -1614,8 +1777,9 @@
     }
 
     final argDescIndex = cp.add(new ConstantArgDesc(2));
-    final icdataIndex = cp.add(
-        new ConstantICData(InvocationKind.setter, node.name, argDescIndex));
+    final icdataIndex = cp.add(new ConstantICData(
+        InvocationKind.setter, node.name, argDescIndex,
+        isDynamic: node.interfaceTarget == null));
     asm.emitInstanceCall(2, icdataIndex);
     asm.emitDrop1();
 
@@ -1699,8 +1863,7 @@
 
   @override
   visitNullLiteral(NullLiteral node) {
-    final cpIndex = cp.add(const ConstantNull());
-    asm.emitPushConstant(cpIndex);
+    asm.emitPushNull();
   }
 
   @override
@@ -1772,7 +1935,7 @@
         assert(args.types.isEmpty);
         // VM needs type arguments for every invocation of a factory
         // constructor. TODO(alexmarkov): Clean this up.
-        _genPushNull();
+        asm.emitPushNull();
       }
       args =
           new Arguments(node.arguments.positional, named: node.arguments.named);
@@ -1807,7 +1970,7 @@
       node.expressions.single.accept(this);
       _genStaticCall(interpolateSingle, new ConstantArgDesc(1), 1);
     } else {
-      _genPushNull();
+      asm.emitPushNull();
       _genPushInt(node.expressions.length);
       asm.emitCreateArrayTOS();
 
@@ -1902,7 +2065,7 @@
   }
 
   void _genFutureNull() {
-    _genPushNull();
+    asm.emitPushNull();
     _genStaticCall(futureValue, new ConstantArgDesc(1), 1);
   }
 
@@ -1930,7 +2093,7 @@
     if (node.message != null) {
       node.message.accept(this);
     } else {
-      _genPushNull();
+      asm.emitPushNull();
     }
 
     _genStaticCall(throwNewAssertionError, new ConstantArgDesc(3), 3);
@@ -2454,7 +2617,7 @@
       if (node.initializer != null) {
         node.initializer.accept(this);
       } else {
-        _genPushNull();
+        asm.emitPushNull();
       }
       if (isCaptured) {
         asm.emitStoreContextVar(locals.getVarIndexInContext(node));
@@ -2574,8 +2737,7 @@
 
   @override
   visitConstantExpression(ConstantExpression node) {
-    int cpIndex = node.constant.accept(constantEmitter);
-    asm.emitPushConstant(cpIndex);
+    _genPushConstExpr(node);
   }
 }
 
@@ -2607,6 +2769,10 @@
       cp.add(new ConstantString(node.value));
 
   @override
+  int visitSymbolConstant(SymbolConstant node) =>
+      cp.add(new ConstantSymbol(node.libraryReference, node.name));
+
+  @override
   int visitListConstant(ListConstant node) => cp.add(new ConstantList(
       node.typeArgument,
       new List<int>.from(node.entries.map((Constant c) => c.accept(this)))));
diff --git a/pkg/vm/lib/constants_error_reporter.dart b/pkg/vm/lib/constants_error_reporter.dart
index 50d1d6d..3b7fb1d 100644
--- a/pkg/vm/lib/constants_error_reporter.dart
+++ b/pkg/vm/lib/constants_error_reporter.dart
@@ -105,6 +105,12 @@
     reportIt(context, message, node);
   }
 
+  deferredLibrary(List<TreeNode> context, TreeNode node, String importName) {
+    final message =
+        codes.templateConstEvalDeferredLibrary.withArguments(importName);
+    reportIt(context, message, node);
+  }
+
   reportIt(List<TreeNode> context, codes.Message message, TreeNode node) {
     final Uri uri = getFileUri(node);
     final int fileOffset = getFileOffset(node);
diff --git a/pkg/vm/lib/frontend_server.dart b/pkg/vm/lib/frontend_server.dart
index 6397f17..f8ea33f 100644
--- a/pkg/vm/lib/frontend_server.dart
+++ b/pkg/vm/lib/frontend_server.dart
@@ -98,7 +98,12 @@
       hide: true)
   ..addMultiOption('define',
       abbr: 'D',
-      help: 'The values for the environment constants (e.g. -Dkey=value).');
+      help: 'The values for the environment constants (e.g. -Dkey=value).')
+  ..addFlag('embed-source-text',
+      help: 'Includes sources into generated dill file. Having sources'
+          ' allows to effectively use observatory to debug produced'
+          ' application, produces better stack traces on exceptions.',
+      defaultsTo: true);
 
 String usage = '''
 Usage: server [options] [input.dart]
@@ -260,6 +265,7 @@
       ..strongMode = options['strong']
       ..sdkSummary = sdkRoot.resolve(platformKernelDill)
       ..verbose = options['verbose']
+      ..embedSourceText = options['embed-source-text']
       ..onProblem =
           (message, Severity severity, List<FormattedMessage> context) {
         bool printMessage;
diff --git a/pkg/vm/lib/kernel_front_end.dart b/pkg/vm/lib/kernel_front_end.dart
index ac3dd10..3b86390 100644
--- a/pkg/vm/lib/kernel_front_end.dart
+++ b/pkg/vm/lib/kernel_front_end.dart
@@ -121,7 +121,8 @@
     }
 
     if (useGlobalTypeFlowAnalysis) {
-      globalTypeFlow.transformComponent(coreTypes, component, entryPoints);
+      globalTypeFlow.transformComponent(
+          compilerOptions.target, coreTypes, component, entryPoints);
     } else {
       devirtualization.transformComponent(coreTypes, component);
     }
diff --git a/pkg/vm/lib/target/vm.dart b/pkg/vm/lib/target/vm.dart
index 0889b46..8b75174 100644
--- a/pkg/vm/lib/target/vm.dart
+++ b/pkg/vm/lib/target/vm.dart
@@ -20,6 +20,11 @@
 class VmTarget extends Target {
   final TargetFlags flags;
 
+  Class _growableList;
+  Class _immutableList;
+  Class _internalLinkedHashMap;
+  Class _immutableMap;
+
   VmTarget(this.flags);
 
   @override
@@ -292,4 +297,28 @@
     callSiteAnnotator.addRepositoryTo(component);
     return super.configureComponent(component);
   }
+
+  @override
+  Class concreteListLiteralClass(CoreTypes coreTypes) {
+    return _growableList ??=
+        coreTypes.index.getClass('dart:core', '_GrowableList');
+  }
+
+  @override
+  Class concreteConstListLiteralClass(CoreTypes coreTypes) {
+    return _immutableList ??=
+        coreTypes.index.getClass('dart:core', '_ImmutableList');
+  }
+
+  @override
+  Class concreteMapLiteralClass(CoreTypes coreTypes) {
+    return _internalLinkedHashMap ??=
+        coreTypes.index.getClass('dart:collection', '_InternalLinkedHashMap');
+  }
+
+  @override
+  Class concreteConstMapLiteralClass(CoreTypes coreTypes) {
+    return _immutableMap ??=
+        coreTypes.index.getClass('dart:core', '_ImmutableMap');
+  }
 }
diff --git a/pkg/vm/lib/transformations/call_site_annotator.dart b/pkg/vm/lib/transformations/call_site_annotator.dart
index c2ca324..66f1cfe 100644
--- a/pkg/vm/lib/transformations/call_site_annotator.dart
+++ b/pkg/vm/lib/transformations/call_site_annotator.dart
@@ -54,13 +54,23 @@
     env.thisType = null;
   }
 
+  void annotateWithType(TreeNode node, Expression receiver) {
+    try {
+      _metadata.mapping[node] = new CallSiteAttributesMetadata(
+          receiverType: receiver.getStaticType(env));
+    } catch (e) {
+      // TODO(dartbug.com/34496) Currently getStaticType is unreliable due to
+      // various issues with AST welltypedness. As a workaround we just
+      // swallow the exception.
+    }
+  }
+
   @override
   visitPropertySet(PropertySet node) {
     super.visitPropertySet(node);
 
     if (hasGenericCovariantParameters(node.interfaceTarget)) {
-      _metadata.mapping[node] = new CallSiteAttributesMetadata(
-          receiverType: node.receiver.getStaticType(env));
+      annotateWithType(node, node.receiver);
     }
   }
 
@@ -72,8 +82,7 @@
     // or not it's a statically-checked call.
     if (node.name.name == 'call' ||
         hasGenericCovariantParameters(node.interfaceTarget)) {
-      _metadata.mapping[node] = new CallSiteAttributesMetadata(
-          receiverType: node.receiver.getStaticType(env));
+      annotateWithType(node, node.receiver);
     }
   }
 
diff --git a/pkg/vm/lib/transformations/type_flow/analysis.dart b/pkg/vm/lib/transformations/type_flow/analysis.dart
index 3ba77a7..d11f83c 100644
--- a/pkg/vm/lib/transformations/type_flow/analysis.dart
+++ b/pkg/vm/lib/transformations/type_flow/analysis.dart
@@ -9,6 +9,7 @@
 import 'dart:core' hide Type;
 import 'dart:math' show max;
 
+import 'package:kernel/target/targets.dart' show Target;
 import 'package:kernel/ast.dart' hide Statement, StatementVisitor;
 import 'package:kernel/class_hierarchy.dart' show ClosedWorldClassHierarchy;
 import 'package:kernel/library_index.dart' show LibraryIndex;
@@ -163,7 +164,8 @@
       case CallKind.PropertyGet:
         assertx(args.values.length == firstParamIndex);
         assertx(args.names.isEmpty);
-        return fieldValue.getValue(typeFlowAnalysis);
+        return fieldValue.getValue(
+            typeFlowAnalysis, field.isStatic ? null : args.values[0]);
 
       case CallKind.PropertySet:
         assertx(args.values.length == firstParamIndex + 1);
@@ -176,7 +178,8 @@
         // Call via field.
         // TODO(alexmarkov): support function types and use inferred type
         // to get more precise return type.
-        final receiver = fieldValue.getValue(typeFlowAnalysis);
+        final receiver = fieldValue.getValue(
+            typeFlowAnalysis, field.isStatic ? null : args.values[0]);
         if (receiver != const EmptyType()) {
           typeFlowAnalysis.applyCall(/* callSite = */ null,
               DynamicSelector.kCall, new Args.withReceiver(args, receiver),
@@ -185,7 +188,7 @@
         return new Type.nullableAny();
 
       case CallKind.FieldInitializer:
-        assertx(args.values.isEmpty);
+        assertx(args.values.length == firstParamIndex);
         assertx(args.names.isEmpty);
         Type initializerResult = typeFlowAnalysis
             .getSummary(field)
@@ -685,7 +688,6 @@
   final Field field;
   final Type staticType;
   Type value;
-  _DirectInvocation _initializerInvocation;
 
   _FieldValue(this.field) : staticType = new Type.fromStatic(field.type) {
     if (field.initializer == null && _isDefaultValueOfFieldObservable()) {
@@ -717,22 +719,22 @@
     });
   }
 
-  void ensureInitialized(TypeFlowAnalysis typeFlowAnalysis) {
+  void ensureInitialized(TypeFlowAnalysis typeFlowAnalysis, Type receiverType) {
     if (field.initializer != null) {
-      if (_initializerInvocation == null) {
-        _initializerInvocation = typeFlowAnalysis._invocationsCache
-            .getInvocation(
-                new DirectSelector(field, callKind: CallKind.FieldInitializer),
-                new Args<Type>(const <Type>[]));
-      }
+      assertx(field.isStatic == (receiverType == null));
+      final args = !field.isStatic ? <Type>[receiverType] : const <Type>[];
+      final initializerInvocation = typeFlowAnalysis._invocationsCache
+          .getInvocation(
+              new DirectSelector(field, callKind: CallKind.FieldInitializer),
+              new Args<Type>(args));
 
       // It may update the field value.
-      typeFlowAnalysis.workList.processInvocation(_initializerInvocation);
+      typeFlowAnalysis.workList.processInvocation(initializerInvocation);
     }
   }
 
-  Type getValue(TypeFlowAnalysis typeFlowAnalysis) {
-    ensureInitialized(typeFlowAnalysis);
+  Type getValue(TypeFlowAnalysis typeFlowAnalysis, Type receiverType) {
+    ensureInitialized(typeFlowAnalysis, receiverType);
     addDependentInvocation(typeFlowAnalysis.currentInvocation);
     return value;
   }
@@ -1174,9 +1176,11 @@
 }
 
 class TypeFlowAnalysis implements EntryPointsListener, CallHandler {
+  final Target target;
   final TypeEnvironment environment;
   final LibraryIndex libraryIndex;
-  final NativeCodeOracle nativeCodeOracle;
+  final PragmaAnnotationParser annotationMatcher;
+  NativeCodeOracle nativeCodeOracle;
   _ClassHierarchyCache hierarchyCache;
   SummaryCollector summaryCollector;
   _InvocationsCache _invocationsCache;
@@ -1185,13 +1189,15 @@
   final Map<Member, Summary> _summaries = <Member, Summary>{};
   final Map<Field, _FieldValue> _fieldValues = <Field, _FieldValue>{};
 
-  TypeFlowAnalysis(Component component, CoreTypes coreTypes,
+  TypeFlowAnalysis(this.target, Component component, CoreTypes coreTypes,
       ClosedWorldClassHierarchy hierarchy, this.environment, this.libraryIndex,
-      {List<String> entryPointsJSONFiles, EntryPointsAnnotationMatcher matcher})
-      : nativeCodeOracle = new NativeCodeOracle(libraryIndex) {
+      {List<String> entryPointsJSONFiles, PragmaAnnotationParser matcher})
+      : annotationMatcher =
+            matcher ?? new ConstantPragmaAnnotationParser(coreTypes) {
+    nativeCodeOracle = new NativeCodeOracle(libraryIndex, annotationMatcher);
     hierarchyCache = new _ClassHierarchyCache(this, hierarchy);
     summaryCollector =
-        new SummaryCollector(environment, this, nativeCodeOracle);
+        new SummaryCollector(target, environment, this, nativeCodeOracle);
     _invocationsCache = new _InvocationsCache(this);
     workList = new _WorkList(this);
 
@@ -1199,10 +1205,8 @@
       nativeCodeOracle.processEntryPointsJSONFiles(entryPointsJSONFiles, this);
     }
 
-    matcher ??= new ConstantEntryPointsAnnotationMatcher(coreTypes);
-
-    component
-        .accept(new PragmaEntryPointsVisitor(this, nativeCodeOracle, matcher));
+    component.accept(new PragmaEntryPointsVisitor(
+        this, nativeCodeOracle, annotationMatcher));
   }
 
   _Invocation get currentInvocation => workList.callStack.last;
diff --git a/pkg/vm/lib/transformations/type_flow/calls.dart b/pkg/vm/lib/transformations/type_flow/calls.dart
index ac69128..958de82 100644
--- a/pkg/vm/lib/transformations/type_flow/calls.dart
+++ b/pkg/vm/lib/transformations/type_flow/calls.dart
@@ -118,9 +118,7 @@
   final Member member;
 
   InterfaceSelector(this.member, {CallKind callKind = CallKind.Method})
-      : super(callKind) {
-    assertx(memberAgreesToCallKind(member));
-  }
+      : super(callKind);
 
   @override
   int get hashCode => (super.hashCode ^ member.hashCode + 31) & kHashMask;
diff --git a/pkg/vm/lib/transformations/type_flow/entry_points.json b/pkg/vm/lib/transformations/type_flow/entry_points.json
index 3a1b81c..f8e856a 100644
--- a/pkg/vm/lib/transformations/type_flow/entry_points.json
+++ b/pkg/vm/lib/transformations/type_flow/entry_points.json
@@ -1,1398 +1 @@
-{
-    "native-methods": {
-        "ClassID_getID": [
-            {
-                "action": "return",
-                "class": "_Smi",
-                "library": "dart:core",
-                "nullable": false
-            }
-        ],
-        "Double_add": [
-            {
-                "action": "return",
-                "class": "_Double",
-                "library": "dart:core",
-                "nullable": false
-            }
-        ],
-        "Double_ceil": [
-            {
-                "action": "return",
-                "class": "_Double",
-                "library": "dart:core",
-                "nullable": false
-            }
-        ],
-        "Double_div": [
-            {
-                "action": "return",
-                "class": "_Double",
-                "library": "dart:core",
-                "nullable": false
-            }
-        ],
-        "Double_doubleFromInteger": [
-            {
-                "action": "return",
-                "class": "_Double",
-                "library": "dart:core",
-                "nullable": false
-            }
-        ],
-        "Double_flipSignBit": [
-            {
-                "action": "return",
-                "class": "_Double",
-                "library": "dart:core",
-                "nullable": false
-            }
-        ],
-        "Double_floor": [
-            {
-                "action": "return",
-                "class": "_Double",
-                "library": "dart:core",
-                "nullable": false
-            }
-        ],
-        "Double_getIsInfinite": [
-            {
-                "action": "return",
-                "class": "bool",
-                "library": "dart:core",
-                "nullable": false
-            }
-        ],
-        "Double_getIsNaN": [
-            {
-                "action": "return",
-                "class": "bool",
-                "library": "dart:core",
-                "nullable": false
-            }
-        ],
-        "Double_getIsNegative": [
-            {
-                "action": "return",
-                "class": "bool",
-                "library": "dart:core",
-                "nullable": false
-            }
-        ],
-        "Double_modulo": [
-            {
-                "action": "return",
-                "class": "_Double",
-                "library": "dart:core",
-                "nullable": false
-            }
-        ],
-        "Double_mul": [
-            {
-                "action": "return",
-                "class": "_Double",
-                "library": "dart:core",
-                "nullable": false
-            }
-        ],
-        "Double_round": [
-            {
-                "action": "return",
-                "class": "_Double",
-                "library": "dart:core",
-                "nullable": false
-            }
-        ],
-        "Double_sub": [
-            {
-                "action": "return",
-                "class": "_Double",
-                "library": "dart:core",
-                "nullable": false
-            }
-        ],
-        "Double_truncate": [
-            {
-                "action": "return",
-                "class": "_Double",
-                "library": "dart:core",
-                "nullable": false
-            }
-        ],
-        "Float32x4_abs": [
-            {
-                "action": "return",
-                "class": "_Float32x4",
-                "library": "dart:typed_data",
-                "nullable": false
-            }
-        ],
-        "Float32x4_add": [
-            {
-                "action": "return",
-                "class": "_Float32x4",
-                "library": "dart:typed_data",
-                "nullable": false
-            }
-        ],
-        "Float32x4_clamp": [
-            {
-                "action": "return",
-                "class": "_Float32x4",
-                "library": "dart:typed_data",
-                "nullable": false
-            }
-        ],
-        "Float32x4_cmpequal": [
-            {
-                "action": "return",
-                "class": "_Int32x4",
-                "library": "dart:typed_data",
-                "nullable": false
-            }
-        ],
-        "Float32x4_cmpgt": [
-            {
-                "action": "return",
-                "class": "_Int32x4",
-                "library": "dart:typed_data",
-                "nullable": false
-            }
-        ],
-        "Float32x4_cmpgte": [
-            {
-                "action": "return",
-                "class": "_Int32x4",
-                "library": "dart:typed_data",
-                "nullable": false
-            }
-        ],
-        "Float32x4_cmplt": [
-            {
-                "action": "return",
-                "class": "_Int32x4",
-                "library": "dart:typed_data",
-                "nullable": false
-            }
-        ],
-        "Float32x4_cmplte": [
-            {
-                "action": "return",
-                "class": "_Int32x4",
-                "library": "dart:typed_data",
-                "nullable": false
-            }
-        ],
-        "Float32x4_cmpnequal": [
-            {
-                "action": "return",
-                "class": "_Int32x4",
-                "library": "dart:typed_data",
-                "nullable": false
-            }
-        ],
-        "Float32x4_fromDoubles": [
-            {
-                "action": "return",
-                "class": "_Float32x4",
-                "library": "dart:typed_data",
-                "nullable": false
-            }
-        ],
-        "Float32x4_fromFloat64x2": [
-            {
-                "action": "return",
-                "class": "_Float32x4",
-                "library": "dart:typed_data",
-                "nullable": false
-            }
-        ],
-        "Float32x4_fromInt32x4Bits": [
-            {
-                "action": "return",
-                "class": "_Float32x4",
-                "library": "dart:typed_data",
-                "nullable": false
-            }
-        ],
-        "Float32x4_getW": [
-            {
-                "action": "return",
-                "class": "_Double",
-                "library": "dart:core",
-                "nullable": false
-            }
-        ],
-        "Float32x4_getX": [
-            {
-                "action": "return",
-                "class": "_Double",
-                "library": "dart:core",
-                "nullable": false
-            }
-        ],
-        "Float32x4_getY": [
-            {
-                "action": "return",
-                "class": "_Double",
-                "library": "dart:core",
-                "nullable": false
-            }
-        ],
-        "Float32x4_getZ": [
-            {
-                "action": "return",
-                "class": "_Double",
-                "library": "dart:core",
-                "nullable": false
-            }
-        ],
-        "Float32x4_max": [
-            {
-                "action": "return",
-                "class": "_Float32x4",
-                "library": "dart:typed_data",
-                "nullable": false
-            }
-        ],
-        "Float32x4_min": [
-            {
-                "action": "return",
-                "class": "_Float32x4",
-                "library": "dart:typed_data",
-                "nullable": false
-            }
-        ],
-        "Float32x4_mul": [
-            {
-                "action": "return",
-                "class": "_Float32x4",
-                "library": "dart:typed_data",
-                "nullable": false
-            }
-        ],
-        "Float32x4_negate": [
-            {
-                "action": "return",
-                "class": "_Float32x4",
-                "library": "dart:typed_data",
-                "nullable": false
-            }
-        ],
-        "Float32x4_reciprocal": [
-            {
-                "action": "return",
-                "class": "_Float32x4",
-                "library": "dart:typed_data",
-                "nullable": false
-            }
-        ],
-        "Float32x4_reciprocalSqrt": [
-            {
-                "action": "return",
-                "class": "_Float32x4",
-                "library": "dart:typed_data",
-                "nullable": false
-            }
-        ],
-        "Float32x4_scale": [
-            {
-                "action": "return",
-                "class": "_Float32x4",
-                "library": "dart:typed_data",
-                "nullable": false
-            }
-        ],
-        "Float32x4_setW": [
-            {
-                "action": "return",
-                "class": "_Float32x4",
-                "library": "dart:typed_data",
-                "nullable": false
-            }
-        ],
-        "Float32x4_setX": [
-            {
-                "action": "return",
-                "class": "_Float32x4",
-                "library": "dart:typed_data",
-                "nullable": false
-            }
-        ],
-        "Float32x4_setY": [
-            {
-                "action": "return",
-                "class": "_Float32x4",
-                "library": "dart:typed_data",
-                "nullable": false
-            }
-        ],
-        "Float32x4_setZ": [
-            {
-                "action": "return",
-                "class": "_Float32x4",
-                "library": "dart:typed_data",
-                "nullable": false
-            }
-        ],
-        "Float32x4_shuffle": [
-            {
-                "action": "return",
-                "class": "_Float32x4",
-                "library": "dart:typed_data",
-                "nullable": false
-            }
-        ],
-        "Float32x4_shuffleMix": [
-            {
-                "action": "return",
-                "class": "_Float32x4",
-                "library": "dart:typed_data",
-                "nullable": false
-            }
-        ],
-        "Float32x4_splat": [
-            {
-                "action": "return",
-                "class": "_Float32x4",
-                "library": "dart:typed_data",
-                "nullable": false
-            }
-        ],
-        "Float32x4_sqrt": [
-            {
-                "action": "return",
-                "class": "_Float32x4",
-                "library": "dart:typed_data",
-                "nullable": false
-            }
-        ],
-        "Float32x4_sub": [
-            {
-                "action": "return",
-                "class": "_Float32x4",
-                "library": "dart:typed_data",
-                "nullable": false
-            }
-        ],
-        "Float32x4_zero": [
-            {
-                "action": "return",
-                "class": "_Float32x4",
-                "library": "dart:typed_data",
-                "nullable": false
-            }
-        ],
-        "Float64x2_abs": [
-            {
-                "action": "return",
-                "class": "_Float64x2",
-                "library": "dart:typed_data",
-                "nullable": false
-            }
-        ],
-        "Float64x2_fromDoubles": [
-            {
-                "action": "return",
-                "class": "_Float64x2",
-                "library": "dart:typed_data",
-                "nullable": false
-            }
-        ],
-        "Float64x2_fromFloat32x4": [
-            {
-                "action": "return",
-                "class": "_Float64x2",
-                "library": "dart:typed_data",
-                "nullable": false
-            }
-        ],
-        "Float64x2_getX": [
-            {
-                "action": "return",
-                "class": "_Double",
-                "library": "dart:core",
-                "nullable": false
-            }
-        ],
-        "Float64x2_getY": [
-            {
-                "action": "return",
-                "class": "_Double",
-                "library": "dart:core",
-                "nullable": false
-            }
-        ],
-        "Float64x2_max": [
-            {
-                "action": "return",
-                "class": "_Float64x2",
-                "library": "dart:typed_data",
-                "nullable": false
-            }
-        ],
-        "Float64x2_min": [
-            {
-                "action": "return",
-                "class": "_Float64x2",
-                "library": "dart:typed_data",
-                "nullable": false
-            }
-        ],
-        "Float64x2_negate": [
-            {
-                "action": "return",
-                "class": "_Float64x2",
-                "library": "dart:typed_data",
-                "nullable": false
-            }
-        ],
-        "Float64x2_scale": [
-            {
-                "action": "return",
-                "class": "_Float64x2",
-                "library": "dart:typed_data",
-                "nullable": false
-            }
-        ],
-        "Float64x2_setX": [
-            {
-                "action": "return",
-                "class": "_Float64x2",
-                "library": "dart:typed_data",
-                "nullable": false
-            }
-        ],
-        "Float64x2_setY": [
-            {
-                "action": "return",
-                "class": "_Float64x2",
-                "library": "dart:typed_data",
-                "nullable": false
-            }
-        ],
-        "Float64x2_splat": [
-            {
-                "action": "return",
-                "class": "_Float64x2",
-                "library": "dart:typed_data",
-                "nullable": false
-            }
-        ],
-        "Float64x2_sqrt": [
-            {
-                "action": "return",
-                "class": "_Float64x2",
-                "library": "dart:typed_data",
-                "nullable": false
-            }
-        ],
-        "Float64x2_zero": [
-            {
-                "action": "return",
-                "class": "_Float64x2",
-                "library": "dart:typed_data",
-                "nullable": false
-            }
-        ],
-        "GrowableList_allocate": [
-            {
-                "action": "return",
-                "class": "_GrowableList",
-                "library": "dart:core",
-                "nullable": false
-            }
-        ],
-        "GrowableList_getCapacity": [
-            {
-                "action": "return",
-                "class": "_Smi",
-                "library": "dart:core",
-                "nullable": false
-            }
-        ],
-        "GrowableList_getLength": [
-            {
-                "action": "return",
-                "class": "_Smi",
-                "library": "dart:core",
-                "nullable": false
-            }
-        ],
-        "Identical_comparison": [
-            {
-                "action": "return",
-                "class": "bool",
-                "library": "dart:core",
-                "nullable": false
-            }
-        ],
-        "Int32x4_fromBools": [
-            {
-                "action": "return",
-                "class": "_Int32x4",
-                "library": "dart:typed_data",
-                "nullable": false
-            }
-        ],
-        "Int32x4_fromFloat32x4Bits": [
-            {
-                "action": "return",
-                "class": "_Int32x4",
-                "library": "dart:typed_data",
-                "nullable": false
-            }
-        ],
-        "Int32x4_fromInts": [
-            {
-                "action": "return",
-                "class": "_Int32x4",
-                "library": "dart:typed_data",
-                "nullable": false
-            }
-        ],
-        "Int32x4_getFlagW": [
-            {
-                "action": "return",
-                "class": "bool",
-                "library": "dart:core",
-                "nullable": false
-            }
-        ],
-        "Int32x4_getFlagX": [
-            {
-                "action": "return",
-                "class": "bool",
-                "library": "dart:core",
-                "nullable": false
-            }
-        ],
-        "Int32x4_getFlagY": [
-            {
-                "action": "return",
-                "class": "bool",
-                "library": "dart:core",
-                "nullable": false
-            }
-        ],
-        "Int32x4_getFlagZ": [
-            {
-                "action": "return",
-                "class": "bool",
-                "library": "dart:core",
-                "nullable": false
-            }
-        ],
-        "Int32x4_select": [
-            {
-                "action": "return",
-                "class": "_Float32x4",
-                "library": "dart:typed_data",
-                "nullable": false
-            }
-        ],
-        "Int32x4_setFlagW": [
-            {
-                "action": "return",
-                "class": "_Int32x4",
-                "library": "dart:typed_data",
-                "nullable": false
-            }
-        ],
-        "Int32x4_setFlagX": [
-            {
-                "action": "return",
-                "class": "_Int32x4",
-                "library": "dart:typed_data",
-                "nullable": false
-            }
-        ],
-        "Int32x4_setFlagY": [
-            {
-                "action": "return",
-                "class": "_Int32x4",
-                "library": "dart:typed_data",
-                "nullable": false
-            }
-        ],
-        "Int32x4_setFlagZ": [
-            {
-                "action": "return",
-                "class": "_Int32x4",
-                "library": "dart:typed_data",
-                "nullable": false
-            }
-        ],
-        "Int32x4_shuffle": [
-            {
-                "action": "return",
-                "class": "_Int32x4",
-                "library": "dart:typed_data",
-                "nullable": false
-            }
-        ],
-        "Int32x4_shuffleMix": [
-            {
-                "action": "return",
-                "class": "_Int32x4",
-                "library": "dart:typed_data",
-                "nullable": false
-            }
-        ],
-        "Integer_equalToInteger": [
-            {
-                "action": "return",
-                "class": "bool",
-                "library": "dart:core",
-                "nullable": false
-            }
-        ],
-        "Integer_greaterThanFromInteger": [
-            {
-                "action": "return",
-                "class": "bool",
-                "library": "dart:core",
-                "nullable": false
-            }
-        ],
-        "LinkedHashMap_getData": [
-            {
-                "action": "return",
-                "class": "_List",
-                "library": "dart:core",
-                "nullable": false
-            }
-        ],
-        "LinkedHashMap_getDeletedKeys": [
-            {
-                "action": "return",
-                "class": "_Smi",
-                "library": "dart:core",
-                "nullable": false
-            }
-        ],
-        "LinkedHashMap_getHashMask": [
-            {
-                "action": "return",
-                "class": "_Smi",
-                "library": "dart:core",
-                "nullable": false
-            }
-        ],
-        "LinkedHashMap_getIndex": [
-            {
-                "action": "return",
-                "class": "_Uint32List",
-                "library": "dart:typed_data",
-                "nullable": false
-            }
-        ],
-        "LinkedHashMap_getUsedData": [
-            {
-                "action": "return",
-                "class": "_Smi",
-                "library": "dart:core",
-                "nullable": false
-            }
-        ],
-        "List_allocate": [
-            {
-                "action": "return",
-                "class": "_List",
-                "library": "dart:core",
-                "nullable": false
-            }
-        ],
-        "List_getLength": [
-            {
-                "action": "return",
-                "class": "_Smi",
-                "library": "dart:core",
-                "nullable": false
-            }
-        ],
-        "Object_equals": [
-            {
-                "action": "return",
-                "class": "bool",
-                "library": "dart:core",
-                "nullable": false
-            }
-        ],
-        "Object_getHash": [
-            {
-                "action": "return",
-                "class": "_Smi",
-                "library": "dart:core",
-                "nullable": false
-            }
-        ],
-        "Object_haveSameRuntimeType": [
-            {
-                "action": "return",
-                "class": "bool",
-                "library": "dart:core",
-                "nullable": false
-            }
-        ],
-        "Object_runtimeType": [
-            {
-                "action": "return",
-                "class": "_Type",
-                "library": "dart:core",
-                "nullable": false
-            }
-        ],
-        "OneByteString_allocate": [
-            {
-                "action": "return",
-                "class": "_OneByteString",
-                "library": "dart:core",
-                "nullable": false
-            }
-        ],
-        "OneByteString_substringUnchecked": [
-            {
-                "action": "return",
-                "class": "_OneByteString",
-                "library": "dart:core",
-                "nullable": false
-            }
-        ],
-        "Smi_bitAndFromSmi": [
-            {
-                "action": "return",
-                "class": "_Smi",
-                "library": "dart:core",
-                "nullable": false
-            }
-        ],
-        "Smi_bitLength": [
-            {
-                "action": "return",
-                "class": "_Smi",
-                "library": "dart:core",
-                "nullable": false
-            }
-        ],
-        "Smi_bitNegate": [
-            {
-                "action": "return",
-                "class": "_Smi",
-                "library": "dart:core",
-                "nullable": false
-            }
-        ],
-        "String_codeUnitAt": [
-            {
-                "action": "return",
-                "class": "_Smi",
-                "library": "dart:core",
-                "nullable": false
-            }
-        ],
-        "String_getHashCode": [
-            {
-                "action": "return",
-                "class": "_Smi",
-                "library": "dart:core",
-                "nullable": false
-            }
-        ],
-        "String_getLength": [
-            {
-                "action": "return",
-                "class": "_Smi",
-                "library": "dart:core",
-                "nullable": false
-            }
-        ],
-        "Type_getHashCode": [
-            {
-                "action": "return",
-                "class": "_Smi",
-                "library": "dart:core",
-                "nullable": false
-            }
-        ],
-        "TypedData_Float32Array_new": [
-            {
-                "action": "return",
-                "class": "_Float32List",
-                "library": "dart:typed_data",
-                "nullable": false
-            }
-        ],
-        "TypedData_Float32x4Array_new": [
-            {
-                "action": "return",
-                "class": "_Float32x4List",
-                "library": "dart:typed_data",
-                "nullable": false
-            }
-        ],
-        "TypedData_Float64Array_new": [
-            {
-                "action": "return",
-                "class": "_Float64List",
-                "library": "dart:typed_data",
-                "nullable": false
-            }
-        ],
-        "TypedData_Float64x2Array_new": [
-            {
-                "action": "return",
-                "class": "_Float64x2List",
-                "library": "dart:typed_data",
-                "nullable": false
-            }
-        ],
-        "TypedData_GetFloat32": [
-            {
-                "action": "return",
-                "class": "_Double",
-                "library": "dart:core",
-                "nullable": false
-            }
-        ],
-        "TypedData_GetFloat32x4": [
-            {
-                "action": "return",
-                "class": "_Float32x4",
-                "library": "dart:typed_data",
-                "nullable": false
-            }
-        ],
-        "TypedData_GetFloat64": [
-            {
-                "action": "return",
-                "class": "_Double",
-                "library": "dart:core",
-                "nullable": false
-            }
-        ],
-        "TypedData_GetInt16": [
-            {
-                "action": "return",
-                "class": "_Smi",
-                "library": "dart:core",
-                "nullable": false
-            }
-        ],
-        "TypedData_GetInt32x4": [
-            {
-                "action": "return",
-                "class": "_Int32x4",
-                "library": "dart:typed_data",
-                "nullable": false
-            }
-        ],
-        "TypedData_GetInt8": [
-            {
-                "action": "return",
-                "class": "_Smi",
-                "library": "dart:core",
-                "nullable": false
-            }
-        ],
-        "TypedData_GetUint16": [
-            {
-                "action": "return",
-                "class": "_Smi",
-                "library": "dart:core",
-                "nullable": false
-            }
-        ],
-        "TypedData_GetUint8": [
-            {
-                "action": "return",
-                "class": "_Smi",
-                "library": "dart:core",
-                "nullable": false
-            }
-        ],
-        "TypedData_Int16Array_new": [
-            {
-                "action": "return",
-                "class": "_Int16List",
-                "library": "dart:typed_data",
-                "nullable": false
-            }
-        ],
-        "TypedData_Int32Array_new": [
-            {
-                "action": "return",
-                "class": "_Int32List",
-                "library": "dart:typed_data",
-                "nullable": false
-            }
-        ],
-        "TypedData_Int32x4Array_new": [
-            {
-                "action": "return",
-                "class": "_Int32x4List",
-                "library": "dart:typed_data",
-                "nullable": false
-            }
-        ],
-        "TypedData_Int64Array_new": [
-            {
-                "action": "return",
-                "class": "_Int64List",
-                "library": "dart:typed_data",
-                "nullable": false
-            }
-        ],
-        "TypedData_Int8Array_new": [
-            {
-                "action": "return",
-                "class": "_Int8List",
-                "library": "dart:typed_data",
-                "nullable": false
-            }
-        ],
-        "TypedData_Uint16Array_new": [
-            {
-                "action": "return",
-                "class": "_Uint16List",
-                "library": "dart:typed_data",
-                "nullable": false
-            }
-        ],
-        "TypedData_Uint32Array_new": [
-            {
-                "action": "return",
-                "class": "_Uint32List",
-                "library": "dart:typed_data",
-                "nullable": false
-            }
-        ],
-        "TypedData_Uint64Array_new": [
-            {
-                "action": "return",
-                "class": "_Uint64List",
-                "library": "dart:typed_data",
-                "nullable": false
-            }
-        ],
-        "TypedData_Uint8Array_new": [
-            {
-                "action": "return",
-                "class": "_Uint8List",
-                "library": "dart:typed_data",
-                "nullable": false
-            }
-        ],
-        "TypedData_Uint8ClampedArray_new": [
-            {
-                "action": "return",
-                "class": "_Uint8ClampedList",
-                "library": "dart:typed_data",
-                "nullable": false
-            }
-        ],
-        "TypedData_length": [
-            {
-                "action": "return",
-                "class": "_Smi",
-                "library": "dart:core",
-                "nullable": false
-            }
-        ]
-    },
-    "roots": [
-        {
-            "action": "create-instance",
-            "class": "Object",
-            "library": "dart:core"
-        },
-        {
-            "action": "create-instance",
-            "class": "_LibraryPrefix",
-            "library": "dart:core"
-        },
-        {
-            "action": "create-instance",
-            "class": "_Type",
-            "library": "dart:core"
-        },
-        {
-            "action": "create-instance",
-            "class": "_TypeRef",
-            "library": "dart:core"
-        },
-        {
-            "action": "create-instance",
-            "class": "_TypeParameter",
-            "library": "dart:core"
-        },
-        {
-            "action": "create-instance",
-            "class": "_BoundedType",
-            "library": "dart:core"
-        },
-        {
-            "action": "create-instance",
-            "class": "_MixinAppType",
-            "library": "dart:core"
-        },
-        {
-            "action": "create-instance",
-            "class": "_Closure",
-            "library": "dart:core"
-        },
-        {
-            "action": "create-instance",
-            "class": "_Smi",
-            "library": "dart:core"
-        },
-        {
-            "action": "create-instance",
-            "class": "_Mint",
-            "library": "dart:core"
-        },
-        {
-            "action": "create-instance",
-            "class": "_Double",
-            "library": "dart:core"
-        },
-        {
-            "action": "create-instance",
-            "class": "bool",
-            "library": "dart:core"
-        },
-        {
-            "action": "create-instance",
-            "class": "_GrowableList",
-            "library": "dart:core"
-        },
-        {
-            "action": "create-instance",
-            "class": "_Float32x4",
-            "library": "dart:typed_data"
-        },
-        {
-            "action": "create-instance",
-            "class": "_Int32x4",
-            "library": "dart:typed_data"
-        },
-        {
-            "action": "create-instance",
-            "class": "_Float64x2",
-            "library": "dart:typed_data"
-        },
-        {
-            "action": "create-instance",
-            "class": "_CapabilityImpl",
-            "library": "dart:isolate"
-        },
-        {
-            "action": "create-instance",
-            "class": "_RawReceivePortImpl",
-            "library": "dart:isolate"
-        },
-        {
-            "action": "create-instance",
-            "class": "_SendPortImpl",
-            "library": "dart:isolate"
-        },
-        {
-            "action": "create-instance",
-            "class": "_StackTrace",
-            "library": "dart:core"
-        },
-        {
-            "action": "create-instance",
-            "class": "_RegExp",
-            "library": "dart:core"
-        },
-        {
-            "action": "create-instance",
-            "class": "_WeakProperty",
-            "library": "dart:core"
-        },
-        {
-            "action": "create-instance",
-            "class": "_MirrorReference",
-            "library": "dart:mirrors"
-        },
-        {
-            "action": "create-instance",
-            "class": "_InternalLinkedHashMap",
-            "library": "dart:collection"
-        },
-        {
-            "action": "create-instance",
-            "class": "_UserTag",
-            "library": "dart:developer"
-        },
-        {
-            "action": "create-instance",
-            "class": "_List",
-            "library": "dart:core"
-        },
-        {
-            "action": "create-instance",
-            "class": "_ImmutableList",
-            "library": "dart:core"
-        },
-        {
-            "action": "create-instance",
-            "class": "_OneByteString",
-            "library": "dart:core"
-        },
-        {
-            "action": "create-instance",
-            "class": "_TwoByteString",
-            "library": "dart:core"
-        },
-        {
-            "action": "create-instance",
-            "class": "_ExternalOneByteString",
-            "library": "dart:core"
-        },
-        {
-            "action": "create-instance",
-            "class": "_ExternalTwoByteString",
-            "library": "dart:core"
-        },
-        {
-            "action": "create-instance",
-            "class": "_Int8List",
-            "library": "dart:typed_data"
-        },
-        {
-            "action": "create-instance",
-            "class": "_Uint8List",
-            "library": "dart:typed_data"
-        },
-        {
-            "action": "create-instance",
-            "class": "_Uint8ClampedList",
-            "library": "dart:typed_data"
-        },
-        {
-            "action": "create-instance",
-            "class": "_Int16List",
-            "library": "dart:typed_data"
-        },
-        {
-            "action": "create-instance",
-            "class": "_Uint16List",
-            "library": "dart:typed_data"
-        },
-        {
-            "action": "create-instance",
-            "class": "_Int32List",
-            "library": "dart:typed_data"
-        },
-        {
-            "action": "create-instance",
-            "class": "_Uint32List",
-            "library": "dart:typed_data"
-        },
-        {
-            "action": "create-instance",
-            "class": "_Int64List",
-            "library": "dart:typed_data"
-        },
-        {
-            "action": "create-instance",
-            "class": "_Uint64List",
-            "library": "dart:typed_data"
-        },
-        {
-            "action": "create-instance",
-            "class": "_Float32List",
-            "library": "dart:typed_data"
-        },
-        {
-            "action": "create-instance",
-            "class": "_Float64List",
-            "library": "dart:typed_data"
-        },
-        {
-            "action": "create-instance",
-            "class": "_Float32x4List",
-            "library": "dart:typed_data"
-        },
-        {
-            "action": "create-instance",
-            "class": "_Int32x4List",
-            "library": "dart:typed_data"
-        },
-        {
-            "action": "create-instance",
-            "class": "_Float64x2List",
-            "library": "dart:typed_data"
-        },
-        {
-            "action": "create-instance",
-            "class": "_Int8ArrayView",
-            "library": "dart:typed_data"
-        },
-        {
-            "action": "create-instance",
-            "class": "_Uint8ArrayView",
-            "library": "dart:typed_data"
-        },
-        {
-            "action": "create-instance",
-            "class": "_Uint8ClampedArrayView",
-            "library": "dart:typed_data"
-        },
-        {
-            "action": "create-instance",
-            "class": "_Int16ArrayView",
-            "library": "dart:typed_data"
-        },
-        {
-            "action": "create-instance",
-            "class": "_Uint16ArrayView",
-            "library": "dart:typed_data"
-        },
-        {
-            "action": "create-instance",
-            "class": "_Int32ArrayView",
-            "library": "dart:typed_data"
-        },
-        {
-            "action": "create-instance",
-            "class": "_Uint32ArrayView",
-            "library": "dart:typed_data"
-        },
-        {
-            "action": "create-instance",
-            "class": "_Int64ArrayView",
-            "library": "dart:typed_data"
-        },
-        {
-            "action": "create-instance",
-            "class": "_Uint64ArrayView",
-            "library": "dart:typed_data"
-        },
-        {
-            "action": "create-instance",
-            "class": "_Float32ArrayView",
-            "library": "dart:typed_data"
-        },
-        {
-            "action": "create-instance",
-            "class": "_Float64ArrayView",
-            "library": "dart:typed_data"
-        },
-        {
-            "action": "create-instance",
-            "class": "_Float32x4ArrayView",
-            "library": "dart:typed_data"
-        },
-        {
-            "action": "create-instance",
-            "class": "_Int32x4ArrayView",
-            "library": "dart:typed_data"
-        },
-        {
-            "action": "create-instance",
-            "class": "_Float64x2ArrayView",
-            "library": "dart:typed_data"
-        },
-        {
-            "action": "create-instance",
-            "class": "_ByteDataView",
-            "library": "dart:typed_data"
-        },
-        {
-            "action": "create-instance",
-            "class": "_ExternalInt8Array",
-            "library": "dart:typed_data"
-        },
-        {
-            "action": "create-instance",
-            "class": "_ExternalUint8Array",
-            "library": "dart:typed_data"
-        },
-        {
-            "action": "create-instance",
-            "class": "_ExternalUint8ClampedArray",
-            "library": "dart:typed_data"
-        },
-        {
-            "action": "create-instance",
-            "class": "_ExternalInt16Array",
-            "library": "dart:typed_data"
-        },
-        {
-            "action": "create-instance",
-            "class": "_ExternalUint16Array",
-            "library": "dart:typed_data"
-        },
-        {
-            "action": "create-instance",
-            "class": "_ExternalInt32Array",
-            "library": "dart:typed_data"
-        },
-        {
-            "action": "create-instance",
-            "class": "_ExternalUint32Array",
-            "library": "dart:typed_data"
-        },
-        {
-            "action": "create-instance",
-            "class": "_ExternalInt64Array",
-            "library": "dart:typed_data"
-        },
-        {
-            "action": "create-instance",
-            "class": "_ExternalUint64Array",
-            "library": "dart:typed_data"
-        },
-        {
-            "action": "create-instance",
-            "class": "_ExternalFloat32Array",
-            "library": "dart:typed_data"
-        },
-        {
-            "action": "create-instance",
-            "class": "_ExternalFloat64Array",
-            "library": "dart:typed_data"
-        },
-        {
-            "action": "create-instance",
-            "class": "_ExternalFloat32x4Array",
-            "library": "dart:typed_data"
-        },
-        {
-            "action": "create-instance",
-            "class": "_ExternalInt32x4Array",
-            "library": "dart:typed_data"
-        },
-        {
-            "action": "create-instance",
-            "class": "_ExternalFloat64x2Array",
-            "library": "dart:typed_data"
-        },
-        {
-            "action": "create-instance",
-            "class": "_ByteBuffer",
-            "library": "dart:typed_data"
-        },
-        {
-            "action": "create-instance",
-            "class": "Null",
-            "library": "dart:core"
-        },
-        {
-            "action": "get",
-            "class": "_SecureFilterImpl",
-            "library": "dart:io",
-            "name": "ENCRYPTED_SIZE"
-        },
-        {
-            "action": "get",
-            "class": "_SecureFilterImpl",
-            "library": "dart:io",
-            "name": "SIZE"
-        }
-    ]
-}
+{"roots":[]}
\ No newline at end of file
diff --git a/pkg/vm/lib/transformations/type_flow/native_code.dart b/pkg/vm/lib/transformations/type_flow/native_code.dart
index c3bbf2d..2c38d28 100644
--- a/pkg/vm/lib/transformations/type_flow/native_code.dart
+++ b/pkg/vm/lib/transformations/type_flow/native_code.dart
@@ -11,7 +11,6 @@
 
 import 'package:kernel/ast.dart';
 import 'package:kernel/core_types.dart' show CoreTypes;
-import 'package:kernel/external_name.dart' show getExternalName;
 import 'package:kernel/library_index.dart' show LibraryIndex;
 
 import 'calls.dart';
@@ -29,81 +28,123 @@
   ConcreteType addAllocatedClass(Class c);
 }
 
+abstract class ParsedPragma {}
+
 enum PragmaEntryPointType { Always, GetterOnly, SetterOnly }
 
-const kEntryPointPragmaName = "vm:entry-point";
-const kNativeMethodPragmaName = "vm:native-method";
-
-abstract class EntryPointsAnnotationMatcher {
-  PragmaEntryPointType annotationsDefineRoot(List<Expression> annotations);
+class ParsedEntryPointPragma extends ParsedPragma {
+  final PragmaEntryPointType type;
+  ParsedEntryPointPragma(this.type);
 }
 
-class ConstantEntryPointsAnnotationMatcher
-    implements EntryPointsAnnotationMatcher {
+class ParsedResultTypeByTypePragma extends ParsedPragma {
+  final DartType type;
+  ParsedResultTypeByTypePragma(this.type);
+}
+
+class ParsedResultTypeByPathPragma extends ParsedPragma {
+  final String path;
+  ParsedResultTypeByPathPragma(this.path);
+}
+
+const kEntryPointPragmaName = "vm:entry-point";
+const kExactResultTypePragmaName = "vm:exact-result-type";
+
+abstract class PragmaAnnotationParser {
+  /// May return 'null' if the annotation does not represent a recognized
+  /// @pragma.
+  ParsedPragma parsePragma(Expression annotation);
+}
+
+class ConstantPragmaAnnotationParser extends PragmaAnnotationParser {
   final CoreTypes coreTypes;
 
-  ConstantEntryPointsAnnotationMatcher(this.coreTypes);
+  ConstantPragmaAnnotationParser(this.coreTypes);
 
-  PragmaEntryPointType definesRoot(InstanceConstant constant) {
-    if (constant.classReference.node != coreTypes.pragmaClass) return null;
+  ParsedPragma parsePragma(Expression annotation) {
+    InstanceConstant pragmaConstant;
+    if (annotation is ConstantExpression) {
+      Constant constant = annotation.constant;
+      if (constant is InstanceConstant) {
+        if (constant.classReference.node == coreTypes.pragmaClass) {
+          pragmaConstant = constant;
+        }
+      }
+    }
+    if (pragmaConstant == null) return null;
 
-    Constant name = constant.fieldValues[coreTypes.pragmaName.reference];
-    assertx(name != null);
-    if (name is! StringConstant ||
-        (name as StringConstant).value != kEntryPointPragmaName) {
+    String pragmaName;
+    Constant name = pragmaConstant.fieldValues[coreTypes.pragmaName.reference];
+    if (name is StringConstant) {
+      pragmaName = name.value;
+    } else {
       return null;
     }
 
-    Constant options = constant.fieldValues[coreTypes.pragmaOptions.reference];
+    Constant options =
+        pragmaConstant.fieldValues[coreTypes.pragmaOptions.reference];
     assertx(options != null);
-    if (options is NullConstant) return PragmaEntryPointType.Always;
-    if (options is BoolConstant && options.value == true) {
-      return PragmaEntryPointType.Always;
-    }
-    if (options is StringConstant) {
-      if (options.value == "get") {
-        return PragmaEntryPointType.GetterOnly;
-      } else if (options.value == "set") {
-        return PragmaEntryPointType.SetterOnly;
-      } else {
-        throw "Error: string directive to @pragma('$kEntryPointPragmaName', ...) must be either 'get' or 'set'.";
-      }
-    }
-    return null;
-  }
 
-  @override
-  PragmaEntryPointType annotationsDefineRoot(List<Expression> annotations) {
-    for (var annotation in annotations) {
-      if (annotation is ConstantExpression) {
-        Constant constant = annotation.constant;
-        if (constant is InstanceConstant) {
-          var type = definesRoot(constant);
-          if (type != null) return type;
+    switch (pragmaName) {
+      case kEntryPointPragmaName:
+        PragmaEntryPointType type;
+        if (options is NullConstant) {
+          type = PragmaEntryPointType.Always;
+        } else if (options is BoolConstant && options.value == true) {
+          type = PragmaEntryPointType.Always;
+        } else if (options is StringConstant) {
+          if (options.value == "get") {
+            type = PragmaEntryPointType.GetterOnly;
+          } else if (options.value == "set") {
+            type = PragmaEntryPointType.SetterOnly;
+          } else {
+            throw "Error: string directive to @pragma('$kEntryPointPragmaName', ...) "
+                "must be either 'get' or 'set'.";
+          }
         }
-      } else {
-        throw "All annotations must be constants!";
-      }
+        return type != null ? new ParsedEntryPointPragma(type) : null;
+      case kExactResultTypePragmaName:
+        if (options == null) return null;
+        if (options is TypeLiteralConstant) {
+          return new ParsedResultTypeByTypePragma(options.type);
+        } else if (options is StringConstant) {
+          return new ParsedResultTypeByPathPragma(options.value);
+        }
+        throw "ERROR: Unsupported option to '$kExactResultTypePragmaName' "
+            "pragma: $options";
+      default:
+        return null;
     }
-    return null;
   }
 }
 
 class PragmaEntryPointsVisitor extends RecursiveVisitor {
   final EntryPointsListener entryPoints;
   final NativeCodeOracle nativeCodeOracle;
-  final EntryPointsAnnotationMatcher matcher;
+  final PragmaAnnotationParser matcher;
   Class currentClass = null;
 
   PragmaEntryPointsVisitor(
-      this.entryPoints, this.nativeCodeOracle, this.matcher);
+      this.entryPoints, this.nativeCodeOracle, this.matcher) {
+    assertx(matcher != null);
+  }
+
+  PragmaEntryPointType _annotationsDefineRoot(List<Expression> annotations) {
+    for (var annotation in annotations) {
+      ParsedPragma pragma = matcher.parsePragma(annotation);
+      if (pragma == null) continue;
+      if (pragma is ParsedEntryPointPragma) return pragma.type;
+    }
+    return null;
+  }
 
   @override
   visitClass(Class klass) {
-    var type = matcher.annotationsDefineRoot(klass.annotations);
+    var type = _annotationsDefineRoot(klass.annotations);
     if (type != null) {
       if (type != PragmaEntryPointType.Always) {
-        throw "Error: pragma entry-point definition on a class must evaluate to null, true or false. See entry_points_pragma.md.";
+        throw "Error: pragma entry-point definition on a class must evaluate "
+            "to null, true or false. See entry_points_pragma.md.";
       }
       entryPoints.addAllocatedClass(klass);
     }
@@ -113,10 +154,12 @@
 
   @override
   visitProcedure(Procedure proc) {
-    var type = matcher.annotationsDefineRoot(proc.annotations);
+    var type = _annotationsDefineRoot(proc.annotations);
     if (type != null) {
       if (type != PragmaEntryPointType.Always) {
-        throw "Error: pragma entry-point definition on a procedure (including getters and setters) must evaluate to null, true or false. See entry_points_pragma.md.";
+        throw "Error: pragma entry-point definition on a procedure (including"
+            "getters and setters) must evaluate to null, true or false. "
+            "See entry_points_pragma.md.";
       }
       var callKind = proc.isGetter
           ? CallKind.PropertyGet
@@ -130,10 +173,11 @@
 
   @override
   visitConstructor(Constructor ctor) {
-    var type = matcher.annotationsDefineRoot(ctor.annotations);
+    var type = _annotationsDefineRoot(ctor.annotations);
     if (type != null) {
       if (type != PragmaEntryPointType.Always) {
-        throw "Error: pragma entry-point definition on a constructor must evaluate to null, true or false. See entry_points_pragma.md.";
+        throw "Error: pragma entry-point definition on a constructor must "
+            "evaluate to null, true or false. See entry_points_pragma.md.";
       }
       entryPoints
           .addRawCall(new DirectSelector(ctor, callKind: CallKind.Method));
@@ -144,7 +188,7 @@
 
   @override
   visitField(Field field) {
-    var type = matcher.annotationsDefineRoot(field.annotations);
+    var type = _annotationsDefineRoot(field.annotations);
     if (type == null) return;
 
     void addSelector(CallKind ck) {
@@ -172,12 +216,13 @@
 
 /// Provides insights into the behavior of native code.
 class NativeCodeOracle {
-  final Map<String, List<Map<String, dynamic>>> _nativeMethods =
-      <String, List<Map<String, dynamic>>>{};
   final LibraryIndex _libraryIndex;
   final Set<Member> _membersReferencedFromNativeCode = new Set<Member>();
+  final PragmaAnnotationParser _matcher;
 
-  NativeCodeOracle(this._libraryIndex);
+  NativeCodeOracle(this._libraryIndex, this._matcher) {
+    assertx(_matcher != null);
+  }
 
   void setMemberReferencedFromNativeCode(Member member) {
     _membersReferencedFromNativeCode.add(member);
@@ -190,30 +235,44 @@
   /// using [entryPointsListener]. Returns result type of the native method.
   Type handleNativeProcedure(
       Member member, EntryPointsListener entryPointsListener) {
-    final String nativeName = getExternalName(member);
     Type returnType = null;
 
-    final nativeActions = _nativeMethods[nativeName];
-
-    if (nativeActions != null) {
-      for (var action in nativeActions) {
-        if (action['action'] == 'return') {
-          final c = _libraryIndex.getClass(action['library'], action['class']);
-
-          final concreteClass = entryPointsListener.addAllocatedClass(c);
-
-          final nullable = action['nullable'];
-          if (nullable == false) {
-            returnType = concreteClass;
-          } else if ((nullable == true) || (nullable == null)) {
-            returnType = new Type.nullable(concreteClass);
-          } else {
-            throw 'Bad entry point: unexpected nullable: "$nullable" in $action';
-          }
-        } else {
-          _addRoot(action, entryPointsListener);
+    for (var annotation in member.annotations) {
+      ParsedPragma pragma = _matcher.parsePragma(annotation);
+      if (pragma == null) continue;
+      if (pragma is ParsedResultTypeByTypePragma ||
+          pragma is ParsedResultTypeByPathPragma) {
+        // We can only use the 'vm:exact-result-type' pragma on methods in core
+        // libraries for safety reasons. See 'result_type_pragma.md', detail 1.2
+        // for explanation.
+        if (member.enclosingLibrary.importUri.scheme != "dart") {
+          throw "ERROR: Cannot use $kExactResultTypePragmaName "
+              "outside core libraries.";
         }
       }
+      if (pragma is ParsedResultTypeByTypePragma) {
+        var type = pragma.type;
+        if (type is InterfaceType) {
+          returnType = entryPointsListener.addAllocatedClass(type.classNode);
+          break;
+        }
+        throw "ERROR: Invalid return type for native method: ${pragma.type}";
+      } else if (pragma is ParsedResultTypeByPathPragma) {
+        List<String> parts = pragma.path.split("#");
+        if (parts.length != 2) {
+          throw "ERROR: Could not parse native method return type: ${pragma.path}";
+        }
+
+        String libName = parts[0];
+        String klassName = parts[1];
+
+        // Error is thrown on the next line if the class is not found.
+        Class klass = _libraryIndex.getClass(libName, klassName);
+        Type concreteClass = entryPointsListener.addAllocatedClass(klass);
+
+        returnType = concreteClass;
+        break;
+      }
     }
 
     if (returnType != null) {
@@ -223,146 +282,19 @@
     }
   }
 
-  void _addRoot(
-      Map<String, String> rootDesc, EntryPointsListener entryPointsListener) {
-    final String library = rootDesc['library'];
-    final String class_ = rootDesc['class'];
-    final String name = rootDesc['name'];
-    final String action = rootDesc['action'];
-
-    final libraryIndex = _libraryIndex;
-
-    if ((action == 'create-instance') || ((action == null) && (name == null))) {
-      if (name != null) {
-        throw 'Bad entry point: unexpected "name" element in $rootDesc';
-      }
-
-      final Class cls = libraryIndex.getClass(library, class_);
-      if (cls.isAbstract) {
-        throw 'Bad entry point: abstract class listed in $rootDesc';
-      }
-
-      entryPointsListener.addAllocatedClass(cls);
-    } else if ((action == 'call') ||
-        (action == 'get') ||
-        (action == 'set') ||
-        ((action == null) && (name != null))) {
-      if (name == null) {
-        throw 'Bad entry point: expected "name" element in $rootDesc';
-      }
-
-      final String prefix = {
-            'get': LibraryIndex.getterPrefix,
-            'set': LibraryIndex.setterPrefix
-          }[action] ??
-          '';
-
-      Member member;
-
-      if (class_ != null) {
-        final classDotPrefix = class_ + '.';
-        if ((name == class_) || name.startsWith(classDotPrefix)) {
-          // constructor
-          if (action != 'call' && action != null) {
-            throw 'Bad entry point: action "$action" is not applicable to'
-                ' constructor in $rootDesc';
-          }
-
-          final constructorName =
-              (name == class_) ? '' : name.substring(classDotPrefix.length);
-
-          member = libraryIndex.getMember(library, class_, constructorName);
-        } else {
-          member = libraryIndex.tryGetMember(library, class_, prefix + name);
-          if (member == null) {
-            member = libraryIndex.getMember(library, class_, name);
-          }
-        }
-      } else {
-        member = libraryIndex.tryGetTopLevelMember(
-            library, /* unused */ null, prefix + name);
-        if (member == null) {
-          member = libraryIndex.getTopLevelMember(library, name);
-        }
-      }
-
-      assertx(member != null);
-
-      CallKind callKind;
-
-      if (action == null) {
-        if ((member is Field) || ((member is Procedure) && member.isGetter)) {
-          callKind = CallKind.PropertyGet;
-        } else if ((member is Procedure) && member.isSetter) {
-          callKind = CallKind.PropertySet;
-        } else {
-          callKind = CallKind.Method;
-        }
-      } else {
-        callKind = const {
-          'get': CallKind.PropertyGet,
-          'set': CallKind.PropertySet,
-          'call': CallKind.Method
-        }[action];
-      }
-
-      assertx(callKind != null);
-
-      final Selector selector = member.isInstanceMember
-          ? new InterfaceSelector(member, callKind: callKind)
-          : new DirectSelector(member, callKind: callKind);
-
-      entryPointsListener.addRawCall(selector);
-
-      if ((action == null) && (member is Field) && !member.isFinal) {
-        Selector selector = member.isInstanceMember
-            ? new InterfaceSelector(member, callKind: CallKind.PropertySet)
-            : new DirectSelector(member, callKind: CallKind.PropertySet);
-
-        entryPointsListener.addRawCall(selector);
-      }
-
-      _membersReferencedFromNativeCode.add(member);
-    } else {
-      throw 'Bad entry point: unrecognized action "$action" in $rootDesc';
-    }
-  }
-
-  /// Reads JSON describing entry points and native methods from [jsonString].
-  /// Adds all global entry points using [entryPointsListener].
-  ///
-  /// The format of the JSON descriptor is described in
-  /// 'runtime/vm/compiler/aot/entry_points_json.md'.
-  void processEntryPointsJSON(
-      String jsonString, EntryPointsListener entryPointsListener) {
-    final jsonObject = json.decode(jsonString);
-
-    final roots = jsonObject['roots'];
-    if (roots != null) {
-      for (var root in roots) {
-        _addRoot(new Map<String, String>.from(root), entryPointsListener);
-      }
-    }
-
-    final nativeMethods = jsonObject['native-methods'];
-    if (nativeMethods != null) {
-      nativeMethods.forEach((name, actions) {
-        _nativeMethods[name] = new List<Map<String, dynamic>>.from(
-            actions.map((action) => new Map<String, dynamic>.from(action)));
-      });
-    }
-  }
-
   /// Reads JSON files [jsonFiles] describing entry points and native methods.
-  /// Adds all global entry points using [entryPointsListener].
-  ///
-  /// The format of the JSON descriptor is described in
-  /// 'runtime/vm/compiler/aot/entry_points_json.md'.
+  /// Currently just checks that JSON file is empty as it is deprecated.
   void processEntryPointsJSONFiles(
       List<String> jsonFiles, EntryPointsListener entryPointsListener) {
     for (var file in jsonFiles) {
-      processEntryPointsJSON(
-          new File(file).readAsStringSync(), entryPointsListener);
+      String jsonString = new File(file).readAsStringSync();
+      final jsonObject = json.decode(jsonString);
+
+      final roots = jsonObject['roots'];
+      if (roots != null && roots.isNotEmpty) {
+        throw "Error: Found non-empty entry points JSON file $file."
+            " Use the @pragma('vm:entry-point') annotation instead.";
+      }
     }
   }
 }
diff --git a/pkg/vm/lib/transformations/type_flow/summary_collector.dart b/pkg/vm/lib/transformations/type_flow/summary_collector.dart
index 0ed585c..984521d 100644
--- a/pkg/vm/lib/transformations/type_flow/summary_collector.dart
+++ b/pkg/vm/lib/transformations/type_flow/summary_collector.dart
@@ -7,6 +7,7 @@
 
 import 'dart:core' hide Type;
 
+import 'package:kernel/target/targets.dart';
 import 'package:kernel/ast.dart' hide Statement, StatementVisitor;
 import 'package:kernel/ast.dart' as ast show Statement, StatementVisitor;
 import 'package:kernel/type_environment.dart' show TypeEnvironment;
@@ -242,6 +243,7 @@
 
 /// Create a type flow summary for a member from the kernel AST.
 class SummaryCollector extends RecursiveVisitor<TypeExpr> {
+  final Target target;
   final TypeEnvironment _environment;
   final EntryPointsListener _entryPointsListener;
   final NativeCodeOracle _nativeCodeOracle;
@@ -255,8 +257,8 @@
   Parameter _receiver;
   ConstantAllocationCollector constantAllocationCollector;
 
-  SummaryCollector(
-      this._environment, this._entryPointsListener, this._nativeCodeOracle) {
+  SummaryCollector(this.target, this._environment, this._entryPointsListener,
+      this._nativeCodeOracle) {
     constantAllocationCollector = new ConstantAllocationCollector(this);
   }
 
@@ -268,15 +270,24 @@
     _returnValue = null;
     _receiver = null;
 
-    if (member is Field) {
-      _summary = new Summary();
+    final hasReceiver = hasReceiverArg(member);
 
+    if (member is Field) {
+      if (hasReceiver) {
+        _summary = new Summary(parameterCount: 1, positionalParameterCount: 1);
+        // TODO(alexmarkov): subclass cone
+        _receiver = _declareParameter(
+            "this", member.enclosingClass.rawType, null,
+            isReceiver: true);
+        _environment.thisType = member.enclosingClass?.thisType;
+      } else {
+        _summary = new Summary();
+      }
       assertx(member.initializer != null);
       _summary.result = _visit(member.initializer);
     } else {
       FunctionNode function = member.function;
 
-      final hasReceiver = hasReceiverArg(member);
       final firstParamIndex = hasReceiver ? 1 : 0;
 
       _summary = new Summary(
@@ -366,8 +377,7 @@
     final List<Type> args = <Type>[];
     final List<String> names = <String>[];
 
-    if (hasReceiverArg(member) &&
-        (selector.callKind != CallKind.FieldInitializer)) {
+    if (hasReceiverArg(member)) {
       assertx(member.enclosingClass != null);
       Type receiver = new Type.cone(member.enclosingClass.rawType);
       args.add(receiver);
@@ -535,6 +545,10 @@
   Type get _stringType =>
       _cachedStringType ??= new Type.cone(_environment.stringType);
 
+  Type _cachedSymbolType;
+  Type get _symbolType =>
+      _cachedSymbolType ??= new Type.cone(_environment.symbolType);
+
   Type _cachedNullType;
   Type get _nullType => _cachedNullType ??= new Type.nullable(new Type.empty());
 
@@ -618,17 +632,8 @@
     final receiver = _visit(node.receiver);
     final args = new Args<TypeExpr>([receiver]);
     final target = node.target;
-    if ((target is Field) || ((target is Procedure) && target.isGetter)) {
-      return _makeCall(node,
-          new DirectSelector(target, callKind: CallKind.PropertyGet), args);
-    } else {
-      // Tear-off.
-      // TODO(alexmarkov): Consider cleaning up this code as it duplicates
-      // processing in DirectInvocation.
-      // TODO(alexmarkov): capture receiver type
-      _entryPointsListener.addRawCall(new DirectSelector(target));
-      return _staticType(node);
-    }
+    return _makeCall(
+        node, new DirectSelector(target, callKind: CallKind.PropertyGet), args);
   }
 
   @override
@@ -678,8 +683,11 @@
   @override
   TypeExpr visitListLiteral(ListLiteral node) {
     node.expressions.forEach(_visit);
-    // TODO(alexmarkov): concrete type
-    return _staticType(node);
+    Class concreteClass =
+        target.concreteListLiteralClass(_environment.coreTypes);
+    return concreteClass != null
+        ? _entryPointsListener.addAllocatedClass(concreteClass)
+        : _staticType(node);
   }
 
   @override
@@ -695,8 +703,11 @@
       _visit(entry.key);
       _visit(entry.value);
     }
-    // TODO(alexmarkov): concrete type
-    return _staticType(node);
+    Class concreteClass =
+        target.concreteMapLiteralClass(_environment.coreTypes);
+    return concreteClass != null
+        ? _entryPointsListener.addAllocatedClass(concreteClass)
+        : _staticType(node);
   }
 
   @override
@@ -748,15 +759,8 @@
       return _makeCall(
           node, new DynamicSelector(CallKind.PropertyGet, node.name), args);
     }
-    if ((target is Field) || ((target is Procedure) && target.isGetter)) {
-      return _makeCall(node,
-          new InterfaceSelector(target, callKind: CallKind.PropertyGet), args);
-    } else {
-      // Tear-off.
-      // TODO(alexmarkov): capture receiver type
-      _entryPointsListener.addRawCall(new InterfaceSelector(target));
-      return _staticType(node);
-    }
+    return _makeCall(node,
+        new InterfaceSelector(target, callKind: CallKind.PropertyGet), args);
   }
 
   @override
@@ -815,17 +819,8 @@
     if (target == null) {
       return new Type.empty();
     } else {
-      if ((target is Field) || ((target is Procedure) && target.isGetter)) {
-        return _makeCall(node,
-            new DirectSelector(target, callKind: CallKind.PropertyGet), args);
-      } else {
-        // Tear-off.
-        // TODO(alexmarkov): Consider cleaning up this code as it duplicates
-        // processing in DirectInvocation.
-        // TODO(alexmarkov): capture receiver type
-        _entryPointsListener.addRawCall(new DirectSelector(target));
-        return _staticType(node);
-      }
+      return _makeCall(node,
+          new DirectSelector(target, callKind: CallKind.PropertyGet), args);
     }
   }
 
@@ -866,14 +861,8 @@
   TypeExpr visitStaticGet(StaticGet node) {
     final args = new Args<TypeExpr>(const <TypeExpr>[]);
     final target = node.target;
-    if ((target is Field) || (target is Procedure) && target.isGetter) {
-      return _makeCall(node,
-          new DirectSelector(target, callKind: CallKind.PropertyGet), args);
-    } else {
-      // Tear-off.
-      _entryPointsListener.addRawCall(new DirectSelector(target));
-      return _staticType(node);
-    }
+    return _makeCall(
+        node, new DirectSelector(target, callKind: CallKind.PropertyGet), args);
   }
 
   @override
@@ -1203,9 +1192,9 @@
   final TypeEnvironment _environment;
   final SummaryCollector _summaryColector;
 
-  CreateAllSummariesVisitor(this._environment)
-      : _summaryColector = new SummaryCollector(_environment,
-            new EmptyEntryPointsListener(), new NativeCodeOracle(null));
+  CreateAllSummariesVisitor(Target target, this._environment)
+      : _summaryColector = new SummaryCollector(target, _environment,
+            new EmptyEntryPointsListener(), new NativeCodeOracle(null, null));
 
   @override
   defaultMember(Member m) {
@@ -1259,6 +1248,11 @@
   }
 
   @override
+  visitSymbolConstant(SymbolConstant constant) {
+    return summaryCollector._symbolType;
+  }
+
+  @override
   Type visitMapConstant(MapConstant node) {
     throw 'The kernel2kernel constants transformation desugars const maps!';
   }
@@ -1268,7 +1262,11 @@
     for (final Constant entry in constant.entries) {
       typeFor(entry);
     }
-    return new Type.cone(constant.getType(summaryCollector._environment));
+    Class concreteClass = summaryCollector.target
+        .concreteConstListLiteralClass(summaryCollector._environment.coreTypes);
+    return concreteClass != null
+        ? summaryCollector._entryPointsListener.addAllocatedClass(concreteClass)
+        : new Type.cone(constant.getType(summaryCollector._environment));
   }
 
   @override
diff --git a/pkg/vm/lib/transformations/type_flow/transformer.dart b/pkg/vm/lib/transformations/type_flow/transformer.dart
index 098e79d..fcfd575 100644
--- a/pkg/vm/lib/transformations/type_flow/transformer.dart
+++ b/pkg/vm/lib/transformations/type_flow/transformer.dart
@@ -7,6 +7,7 @@
 
 import 'dart:core' hide Type;
 
+import 'package:kernel/target/targets.dart';
 import 'package:kernel/ast.dart' hide Statement, StatementVisitor;
 import 'package:kernel/core_types.dart' show CoreTypes;
 import 'package:kernel/class_hierarchy.dart' show ClassHierarchy;
@@ -31,13 +32,9 @@
 
 /// Whole-program type flow analysis and transformation.
 /// Assumes strong mode and closed world.
-Component transformComponent(
-    CoreTypes coreTypes, Component component, List<String> entryPoints,
-    [EntryPointsAnnotationMatcher matcher]) {
-  if ((entryPoints == null) || entryPoints.isEmpty) {
-    throw 'Error: unable to perform global type flow analysis without entry points.';
-  }
-
+Component transformComponent(Target target, CoreTypes coreTypes,
+    Component component, List<String> entryPoints,
+    [PragmaAnnotationParser matcher]) {
   void ignoreAmbiguousSupertypes(Class cls, Supertype a, Supertype b) {}
   final hierarchy = new ClassHierarchy(component,
       onAmbiguousSupertypes: ignoreAmbiguousSupertypes);
@@ -46,7 +43,7 @@
 
   if (kDumpAllSummaries) {
     Statistics.reset();
-    new CreateAllSummariesVisitor(types).visitComponent(component);
+    new CreateAllSummariesVisitor(target, types).visitComponent(component);
     Statistics.print("All summaries statistics");
   }
 
@@ -54,7 +51,7 @@
   final analysisStopWatch = new Stopwatch()..start();
 
   final typeFlowAnalysis = new TypeFlowAnalysis(
-      component, coreTypes, hierarchy, types, libraryIndex,
+      target, component, coreTypes, hierarchy, types, libraryIndex,
       entryPointsJSONFiles: entryPoints, matcher: matcher);
 
   Procedure main = component.mainMethod;
@@ -940,6 +937,11 @@
   visitStringConstant(StringConstant constant) {}
 
   @override
+  visitSymbolConstant(SymbolConstant constant) {
+    // The Symbol class and it's _name field are always retained.
+  }
+
+  @override
   visitMapConstant(MapConstant node) {
     throw 'The kernel2kernel constants transformation desugars const maps!';
   }
diff --git a/pkg/vm/test/common_test_utils.dart b/pkg/vm/test/common_test_utils.dart
index 5960361..0ed04c7 100644
--- a/pkg/vm/test/common_test_utils.dart
+++ b/pkg/vm/test/common_test_utils.dart
@@ -22,14 +22,14 @@
   TestingVmTarget(TargetFlags flags) : super(flags);
 
   @override
-  bool enableSuperMixins;
+  bool enableSuperMixins = false;
 }
 
 Future<Component> compileTestCaseToKernelProgram(Uri sourceUri,
-    {bool enableSuperMixins: false}) async {
+    {Target target, bool enableSuperMixins: false}) async {
   final platformKernel =
       computePlatformBinariesLocation().resolve('vm_platform_strong.dill');
-  final target = new TestingVmTarget(new TargetFlags(strongMode: true))
+  target ??= new TestingVmTarget(new TargetFlags(strongMode: true))
     ..enableSuperMixins = enableSuperMixins;
   final options = new CompilerOptions()
     ..strongMode = true
diff --git a/pkg/vm/test/transformations/type_flow/annotation_matcher.dart b/pkg/vm/test/transformations/type_flow/annotation_matcher.dart
new file mode 100644
index 0000000..cd3e21c
--- /dev/null
+++ b/pkg/vm/test/transformations/type_flow/annotation_matcher.dart
@@ -0,0 +1,64 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for 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/core_types.dart';
+import 'package:vm/transformations/type_flow/native_code.dart';
+import 'package:vm/transformations/type_flow/utils.dart';
+
+// Since we don't run the constants transformation in this test, we can't
+// recognize all pragma annotations precisely. Instead, we pattern match on
+// annotations which look like a pragma and assume that their options field
+// evaluates to true.
+class ExpressionPragmaAnnotationParser extends PragmaAnnotationParser {
+  final CoreTypes coreTypes;
+
+  ExpressionPragmaAnnotationParser(this.coreTypes);
+
+  ParsedPragma parsePragma(Expression annotation) {
+    assertx(annotation is! ConstantExpression);
+
+    String pragmaName;
+    Expression options;
+
+    if (annotation is ConstructorInvocation) {
+      if (annotation.constructedType.classNode != coreTypes.pragmaClass) {
+        return null;
+      }
+
+      if (annotation.arguments.types.length != 0 ||
+          (annotation.arguments.positional.length != 1 &&
+              annotation.arguments.positional.length != 2) ||
+          annotation.arguments.named.length != 0) {
+        throw "Cannot evaluate pragma annotation $annotation";
+      }
+
+      var arguments = annotation.arguments.positional;
+      var nameArg = arguments[0];
+      if (nameArg is StringLiteral) {
+        pragmaName = nameArg.value;
+      } else {
+        return null;
+      }
+
+      options = arguments.length > 1 ? arguments[1] : new NullLiteral();
+    }
+
+    switch (pragmaName) {
+      case kEntryPointPragmaName:
+        // We ignore the option because we can't properly evaluate it, assume
+        // it's true.
+        return new ParsedEntryPointPragma(PragmaEntryPointType.Always);
+      case kExactResultTypePragmaName:
+        if (options is TypeLiteral) {
+          return new ParsedResultTypeByTypePragma(options.type);
+        } else if (options is StringLiteral) {
+          return new ParsedResultTypeByPathPragma(options.value);
+        }
+        throw "Could not recognize option to $kExactResultTypePragmaName";
+      default:
+        return null;
+    }
+  }
+}
diff --git a/pkg/vm/test/transformations/type_flow/summary_collector_test.dart b/pkg/vm/test/transformations/type_flow/summary_collector_test.dart
index 369c421..34c54015 100644
--- a/pkg/vm/test/transformations/type_flow/summary_collector_test.dart
+++ b/pkg/vm/test/transformations/type_flow/summary_collector_test.dart
@@ -11,18 +11,25 @@
 import 'package:test/test.dart';
 import 'package:vm/transformations/type_flow/native_code.dart';
 import 'package:vm/transformations/type_flow/summary_collector.dart';
+import 'annotation_matcher.dart';
+import 'package:kernel/target/targets.dart';
 
 import '../../common_test_utils.dart';
 
 final String pkgVmDir = Platform.script.resolve('../../..').toFilePath();
 
 class PrintSummaries extends RecursiveVisitor<Null> {
-  final SummaryCollector _summaryColector;
+  final SummaryCollector _summaryCollector;
   final StringBuffer _buf = new StringBuffer();
 
-  PrintSummaries(TypeEnvironment environment)
-      : _summaryColector = new SummaryCollector(environment,
-            new EmptyEntryPointsListener(), new NativeCodeOracle(null));
+  PrintSummaries(
+      Target target, TypeEnvironment environment, CoreTypes coreTypes)
+      : _summaryCollector = new SummaryCollector(
+            target,
+            environment,
+            new EmptyEntryPointsListener(),
+            new NativeCodeOracle(
+                null, new ExpressionPragmaAnnotationParser(coreTypes)));
 
   String print(TreeNode node) {
     visitLibrary(node);
@@ -34,19 +41,22 @@
     if (!member.isAbstract &&
         !((member is Field) && (member.initializer == null))) {
       _buf.writeln("------------ $member ------------");
-      _buf.writeln(_summaryColector.createSummary(member));
+      _buf.writeln(_summaryCollector.createSummary(member));
     }
   }
 }
 
 runTestCase(Uri source) async {
+  final Target target = new TestingVmTarget(new TargetFlags(strongMode: true));
   final Component component = await compileTestCaseToKernelProgram(source);
   final Library library = component.mainMethod.enclosingLibrary;
+  final CoreTypes coreTypes = new CoreTypes(component);
 
-  final typeEnvironment = new TypeEnvironment(
-      new CoreTypes(component), new ClassHierarchy(component));
+  final typeEnvironment =
+      new TypeEnvironment(coreTypes, new ClassHierarchy(component));
 
-  final actual = new PrintSummaries(typeEnvironment).print(library);
+  final actual =
+      new PrintSummaries(target, typeEnvironment, coreTypes).print(library);
 
   compareResultWithExpectationsFile(source, actual);
 }
diff --git a/pkg/vm/test/transformations/type_flow/transformer_test.dart b/pkg/vm/test/transformations/type_flow/transformer_test.dart
index 354d191..3f8da8d 100644
--- a/pkg/vm/test/transformations/type_flow/transformer_test.dart
+++ b/pkg/vm/test/transformations/type_flow/transformer_test.dart
@@ -4,68 +4,28 @@
 
 import 'dart:io';
 
+import 'package:kernel/target/targets.dart';
 import 'package:kernel/ast.dart';
 import 'package:kernel/core_types.dart';
 import 'package:kernel/kernel.dart';
 import 'package:test/test.dart';
-import 'package:vm/transformations/type_flow/native_code.dart';
 import 'package:vm/transformations/type_flow/transformer.dart'
     show transformComponent;
-import 'package:vm/transformations/type_flow/utils.dart';
+import 'annotation_matcher.dart';
 
 import '../../common_test_utils.dart';
 
 final String pkgVmDir = Platform.script.resolve('../../..').toFilePath();
 
-// Since we don't run the constants transformation in this test, we can't
-// recognize all pragma annotations precisely. Instead, we pattern match on
-// annotations which look like a pragma and assume that their options field
-// evaluates to true.
-class ExpressionEntryPointsAnnotationMatcher
-    extends EntryPointsAnnotationMatcher {
-  final CoreTypes coreTypes;
-
-  ExpressionEntryPointsAnnotationMatcher(this.coreTypes);
-
-  bool _looksLikePragma(ConstructorInvocation annotation) {
-    if (annotation.constructedType.classNode != coreTypes.pragmaClass) {
-      return false;
-    }
-
-    if (annotation.arguments.types.length != 0 ||
-        annotation.arguments.positional.length < 1 ||
-        annotation.arguments.named.length != 0) {
-      throw "Cannot evaluate pragma annotation $annotation";
-    }
-
-    var argument = annotation.arguments.positional[0];
-    return argument is StringLiteral && argument.value == kEntryPointPragmaName;
-  }
-
-  @override
-  PragmaEntryPointType annotationsDefineRoot(List<Expression> annotations) {
-    for (var annotation in annotations) {
-      assertx(annotation is! ConstantExpression);
-      if (annotation is ConstructorInvocation && _looksLikePragma(annotation)) {
-        return PragmaEntryPointType.Always;
-      }
-    }
-    return null;
-  }
-}
-
 runTestCase(Uri source) async {
-  Component component = await compileTestCaseToKernelProgram(source);
+  final target = new TestingVmTarget(new TargetFlags(strongMode: true));
+  Component component =
+      await compileTestCaseToKernelProgram(source, target: target);
 
   final coreTypes = new CoreTypes(component);
 
-  final entryPoints = [
-    pkgVmDir + '/lib/transformations/type_flow/entry_points.json',
-    pkgVmDir + '/lib/transformations/type_flow/entry_points_extra.json',
-  ];
-
-  component = transformComponent(coreTypes, component, entryPoints,
-      new ExpressionEntryPointsAnnotationMatcher(coreTypes));
+  component = transformComponent(target, coreTypes, component, [],
+      new ExpressionPragmaAnnotationParser(coreTypes));
 
   final actual = kernelLibraryToString(component.mainMethod.enclosingLibrary);
 
diff --git a/pkg/vm/testcases/bytecode/asserts.dart.expect b/pkg/vm/testcases/bytecode/asserts.dart.expect
index 176424f..d6a69ba 100644
--- a/pkg/vm/testcases/bytecode/asserts.dart.expect
+++ b/pkg/vm/testcases/bytecode/asserts.dart.expect
@@ -9,25 +9,22 @@
   JumpIfNoAsserts      L1
   Push                 FP[-5]
   AssertBoolean        0
-  PushConstant         CP#0
+  PushTrue
   IfEqStrictTOS
   Jump                 L1
+  PushInt              0
+  PushInt              0
+  PushNull
   PushConstant         CP#1
-  PushConstant         CP#1
-  PushConstant         CP#2
-  PushConstant         CP#4
-  IndirectStaticCall   3, CP#3
+  IndirectStaticCall   3, CP#0
   Drop1
 L1:
-  PushConstant         CP#2
+  PushNull
   ReturnTOS
 }
 ConstantPool {
-  [0] = Bool true
-  [1] = Int 0
-  [2] = Null
-  [3] = ArgDesc num-args 3, num-type-args 0, names []
-  [4] = StaticICData target 'dart.core::_AssertionError::_throwNew', arg-desc CP#3
+  [0] = ArgDesc num-args 3, num-type-args 0, names []
+  [1] = StaticICData target 'dart.core::_AssertionError::_throwNew', arg-desc CP#0
 }
 ]static method test1(core::bool condition) → void {
   assert(condition);
@@ -40,29 +37,26 @@
   Push                 FP[-6]
   InstanceCall         1, CP#1
   AssertBoolean        0
-  PushConstant         CP#2
+  PushTrue
   IfEqStrictTOS
   Jump                 L1
-  PushConstant         CP#3
-  PushConstant         CP#3
+  PushInt              0
+  PushInt              0
   Push                 FP[-5]
-  InstanceCall         1, CP#4
-  PushConstant         CP#6
-  IndirectStaticCall   3, CP#5
+  InstanceCall         1, CP#2
+  PushConstant         CP#4
+  IndirectStaticCall   3, CP#3
   Drop1
 L1:
-  PushConstant         CP#7
+  PushNull
   ReturnTOS
 }
 ConstantPool {
   [0] = ArgDesc num-args 1, num-type-args 0, names []
-  [1] = ICData target-name 'call', arg-desc CP#0
-  [2] = Bool true
-  [3] = Int 0
-  [4] = ICData target-name 'call', arg-desc CP#0
-  [5] = ArgDesc num-args 3, num-type-args 0, names []
-  [6] = StaticICData target 'dart.core::_AssertionError::_throwNew', arg-desc CP#5
-  [7] = Null
+  [1] = ICData dynamic target-name 'call', arg-desc CP#0
+  [2] = ICData dynamic target-name 'call', arg-desc CP#0
+  [3] = ArgDesc num-args 3, num-type-args 0, names []
+  [4] = StaticICData target 'dart.core::_AssertionError::_throwNew', arg-desc CP#3
 }
 ]static method test2(() → core::bool condition, () → core::String message) → void {
   assert([@vm.call-site-attributes.metadata=receiverType:() → dart.core::bool] condition.call(), [@vm.call-site-attributes.metadata=receiverType:() → dart.core::String] message.call());
@@ -71,10 +65,9 @@
 Bytecode {
   Entry                0
   CheckStack
-  PushConstant         CP#0
+  PushNull
   ReturnTOS
 }
 ConstantPool {
-  [0] = Null
 }
 ]static method main() → dynamic {}
diff --git a/pkg/vm/testcases/bytecode/async.dart.expect b/pkg/vm/testcases/bytecode/async.dart.expect
index 45fdde0..9b27c2d 100644
--- a/pkg/vm/testcases/bytecode/async.dart.expect
+++ b/pkg/vm/testcases/bytecode/async.dart.expect
@@ -7,20 +7,20 @@
 Bytecode {
   Entry                3
   CheckStack
-  Allocate             CP#21
+  Allocate             CP#19
   StoreLocal           r2
   Push                 r2
-  PushConstant         CP#3
+  PushNull
+  StoreFieldTOS        CP#20
+  Push                 r2
+  PushNull
   StoreFieldTOS        CP#22
   Push                 r2
-  PushConstant         CP#3
-  StoreFieldTOS        CP#24
-  Push                 r2
-  PushConstant         CP#26
-  StoreFieldTOS        CP#27
+  PushConstant         CP#24
+  StoreFieldTOS        CP#25
   Push                 r2
   PushConstant         CP#0
-  StoreFieldTOS        CP#29
+  StoreFieldTOS        CP#27
   Push                 r2
   Push                 r0
   StoreFieldTOS        CP#1
@@ -30,47 +30,45 @@
   [0] = ClosureFunction <anonymous closure> (dart.async::Future<dart.core::int> x) → dart.async::Future<dart.core::Null> /* originally async */ ;
   [1] = InstanceField dart.core::_Closure::_context
   [2] = Reserved
-  [3] = Null
-  [4] = Type dart.async::Future<dart.core::int>
-  [5] = String 'x'
-  [6] = SubtypeTestCache
-  [7] = TypeArgumentsForInstanceAllocation dart.async::Completer [dart.core::Null]
-  [8] = ArgDesc num-args 1, num-type-args 0, names []
-  [9] = StaticICData target 'dart.async::Completer::sync', arg-desc CP#8
-  [10] = Int 0
-  [11] = ClosureFunction :async_op ([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding ;
-  [12] = Int 1
-  [13] = ArgDesc num-args 4, num-type-args 0, names []
-  [14] = StaticICData target 'dart.async::_awaitHelper', arg-desc CP#13
-  [15] = ArgDesc num-args 2, num-type-args 0, names []
-  [16] = StaticICData target 'dart.async::_completeOnAsyncReturn', arg-desc CP#15
-  [17] = Type dynamic
-  [18] = ArgDesc num-args 3, num-type-args 0, names []
-  [19] = ICData target-name 'completeError', arg-desc CP#18
-  [20] = EndClosureFunctionScope
-  [21] = Class dart.core::_Closure
-  [22] = InstanceField dart.core::_Closure::_instantiator_type_arguments
+  [3] = Type dart.async::Future<dart.core::int>
+  [4] = String 'x'
+  [5] = SubtypeTestCache
+  [6] = TypeArgumentsForInstanceAllocation dart.async::Completer [dart.core::Null]
+  [7] = ArgDesc num-args 1, num-type-args 0, names []
+  [8] = StaticICData target 'dart.async::Completer::sync', arg-desc CP#7
+  [9] = ClosureFunction :async_op ([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding ;
+  [10] = Null
+  [11] = ArgDesc num-args 4, num-type-args 0, names []
+  [12] = StaticICData target 'dart.async::_awaitHelper', arg-desc CP#11
+  [13] = ArgDesc num-args 2, num-type-args 0, names []
+  [14] = StaticICData target 'dart.async::_completeOnAsyncReturn', arg-desc CP#13
+  [15] = Type dynamic
+  [16] = ArgDesc num-args 3, num-type-args 0, names []
+  [17] = ICData target-name 'completeError', arg-desc CP#16
+  [18] = EndClosureFunctionScope
+  [19] = Class dart.core::_Closure
+  [20] = InstanceField dart.core::_Closure::_instantiator_type_arguments
+  [21] = Reserved
+  [22] = InstanceField dart.core::_Closure::_function_type_arguments
   [23] = Reserved
-  [24] = InstanceField dart.core::_Closure::_function_type_arguments
-  [25] = Reserved
-  [26] = EmptyTypeArguments
-  [27] = InstanceField dart.core::_Closure::_delayed_type_arguments
+  [24] = EmptyTypeArguments
+  [25] = InstanceField dart.core::_Closure::_delayed_type_arguments
+  [26] = Reserved
+  [27] = InstanceField dart.core::_Closure::_function
   [28] = Reserved
-  [29] = InstanceField dart.core::_Closure::_function
-  [30] = Reserved
-  [31] = StaticICData target 'dart.async::_asyncStackTraceHelper', arg-desc CP#8
-  [32] = StaticICData target 'dart.async::_asyncThenWrapperHelper', arg-desc CP#8
-  [33] = StaticICData target 'dart.async::_asyncErrorWrapperHelper', arg-desc CP#8
-  [34] = TypeArgumentsForInstanceAllocation dart.async::Future [dynamic]
-  [35] = StaticICData target 'dart.async::Future::microtask', arg-desc CP#15
-  [36] = ICData get target-name 'future', arg-desc CP#8
-  [37] = EndClosureFunctionScope
+  [29] = StaticICData target 'dart.async::_asyncStackTraceHelper', arg-desc CP#7
+  [30] = StaticICData target 'dart.async::_asyncThenWrapperHelper', arg-desc CP#7
+  [31] = StaticICData target 'dart.async::_asyncErrorWrapperHelper', arg-desc CP#7
+  [32] = TypeArgumentsForInstanceAllocation dart.async::Future [dynamic]
+  [33] = StaticICData target 'dart.async::Future::microtask', arg-desc CP#13
+  [34] = ICData get target-name 'future', arg-desc CP#7
+  [35] = EndClosureFunctionScope
 }
-Closure CP#11 {
+Closure CP#9 {
   EntryOptional        1, 3, 0
-  LoadConstant         r1, CP#3
-  LoadConstant         r2, CP#3
-  LoadConstant         r3, CP#3
+  LoadConstant         r1, CP#10
+  LoadConstant         r2, CP#10
+  LoadConstant         r3, CP#10
   Frame                6
   CheckStack
   Push                 r0
@@ -79,15 +77,15 @@
   Push                 r4
   LoadContextVar       5
   StoreLocal           r5
-  PushConstant         CP#10
-  IfNeStrictNumTOS
+  PushInt              0
+  IfNeStrictTOS
   Jump                 L1
   Push                 r4
   Push                 r4
   StoreContextVar      7
 Try #0 start:
   Push                 r4
-  PushConstant         CP#12
+  PushInt              1
   StoreContextVar      5
   Push                 r4
   Push                 r4
@@ -100,10 +98,10 @@
   LoadContextVar       4
   Push                 r4
   LoadContextVar       8
-  PushConstant         CP#14
-  IndirectStaticCall   4, CP#13
+  PushConstant         CP#12
+  IndirectStaticCall   4, CP#11
   PopLocal             r8
-  PushConstant         CP#3
+  PushNull
   ReturnTOS
 L4:
   IfEqNull             r2
@@ -118,10 +116,10 @@
   LoadContextVar       1
   Push                 r4
   LoadContextVar       2
-  PushConstant         CP#16
-  IndirectStaticCall   2, CP#15
+  PushConstant         CP#14
+  IndirectStaticCall   2, CP#13
   Drop1
-  PushConstant         CP#3
+  PushNull
   ReturnTOS
   Jump                 L3
 Try #0 end:
@@ -143,11 +141,11 @@
   LoadContextVar       1
   Push                 r8
   Push                 r9
-  InstanceCall         3, CP#19
+  InstanceCall         3, CP#17
   Drop1
   Jump                 L3
 L3:
-  PushConstant         CP#3
+  PushNull
   ReturnTOS
 L1:
   Push                 r4
@@ -169,84 +167,84 @@
   Push                 FP[-5]
   StoreContextVar      0
   Push                 FP[-5]
-  PushConstant         CP#3
+  PushNull
+  PushNull
   PushConstant         CP#3
   PushConstant         CP#4
-  PushConstant         CP#5
-  AssertAssignable     0, CP#6
+  AssertAssignable     0, CP#5
   Drop1
   Push                 r0
-  PushConstant         CP#7
-  PushConstant         CP#9
-  IndirectStaticCall   1, CP#8
+  PushConstant         CP#6
+  PushConstant         CP#8
+  IndirectStaticCall   1, CP#7
   StoreContextVar      1
   Push                 r0
-  PushConstant         CP#3
+  PushNull
   StoreContextVar      2
-  PushConstant         CP#3
+  PushNull
   PopLocal             r2
   Push                 r0
-  PushConstant         CP#3
+  PushNull
   StoreContextVar      3
   Push                 r0
-  PushConstant         CP#3
+  PushNull
   StoreContextVar      4
   Push                 r0
-  PushConstant         CP#10
+  PushInt              0
   StoreContextVar      5
   Push                 r0
-  PushConstant         CP#3
+  PushNull
   StoreContextVar      6
   Push                 r0
-  PushConstant         CP#3
+  PushNull
   StoreContextVar      7
   Push                 r0
-  Allocate             CP#21
+  Allocate             CP#19
   StoreLocal           r3
   Push                 r3
-  PushConstant         CP#3
+  PushNull
+  StoreFieldTOS        CP#20
+  Push                 r3
+  PushNull
   StoreFieldTOS        CP#22
   Push                 r3
-  PushConstant         CP#3
-  StoreFieldTOS        CP#24
+  PushConstant         CP#24
+  StoreFieldTOS        CP#25
   Push                 r3
-  PushConstant         CP#26
+  PushConstant         CP#9
   StoreFieldTOS        CP#27
   Push                 r3
-  PushConstant         CP#11
-  StoreFieldTOS        CP#29
-  Push                 r3
   Push                 r0
   StoreFieldTOS        CP#1
   StoreContextVar      8
   Push                 r0
   LoadContextVar       8
-  PushConstant         CP#31
-  IndirectStaticCall   1, CP#8
+  PushConstant         CP#29
+  IndirectStaticCall   1, CP#7
   PopLocal             r2
   Push                 r0
   Push                 r0
   LoadContextVar       8
-  PushConstant         CP#32
-  IndirectStaticCall   1, CP#8
+  PushConstant         CP#30
+  IndirectStaticCall   1, CP#7
   StoreContextVar      3
   Push                 r0
   Push                 r0
   LoadContextVar       8
-  PushConstant         CP#33
-  IndirectStaticCall   1, CP#8
+  PushConstant         CP#31
+  IndirectStaticCall   1, CP#7
   StoreContextVar      4
-  PushConstant         CP#34
+  PushConstant         CP#32
   Push                 r0
   LoadContextVar       8
-  PushConstant         CP#35
-  IndirectStaticCall   2, CP#15
+  PushConstant         CP#33
+  IndirectStaticCall   2, CP#13
   Drop1
   Push                 r0
   LoadContextVar       1
-  InstanceCall         1, CP#36
+  InstanceCall         1, CP#34
   ReturnTOS
-  PushConstant         CP#3
+  PushNull
   ReturnTOS
 
 }
@@ -290,119 +288,117 @@
   IndirectStaticCall   1, CP#1
   StoreContextVar      0
   Push                 r0
-  PushConstant         CP#3
+  PushNull
   StoreContextVar      1
-  PushConstant         CP#3
+  PushNull
   PopLocal             r2
-  PushConstant         CP#3
+  PushNull
   PopLocal             r3
-  PushConstant         CP#3
+  PushNull
   PopLocal             r4
   Push                 r0
-  PushConstant         CP#4
+  PushInt              0
   StoreContextVar      2
   Push                 r0
-  PushConstant         CP#3
+  PushNull
   StoreContextVar      3
-  Allocate             CP#15
+  Allocate             CP#13
   StoreLocal           r6
   Push                 r6
-  PushConstant         CP#3
+  PushNull
+  StoreFieldTOS        CP#14
+  Push                 r6
+  PushNull
   StoreFieldTOS        CP#16
   Push                 r6
-  PushConstant         CP#3
-  StoreFieldTOS        CP#18
+  PushConstant         CP#18
+  StoreFieldTOS        CP#19
   Push                 r6
-  PushConstant         CP#20
+  PushConstant         CP#3
   StoreFieldTOS        CP#21
   Push                 r6
-  PushConstant         CP#5
-  StoreFieldTOS        CP#23
-  Push                 r6
   Push                 r0
-  StoreFieldTOS        CP#6
+  StoreFieldTOS        CP#5
   PopLocal             r5
   Push                 r5
+  PushConstant         CP#23
+  IndirectStaticCall   1, CP#1
+  PopLocal             r2
+  Push                 r5
+  PushConstant         CP#24
+  IndirectStaticCall   1, CP#1
+  PopLocal             r3
+  Push                 r5
   PushConstant         CP#25
   IndirectStaticCall   1, CP#1
-  PopLocal             r2
-  Push                 r5
+  PopLocal             r4
   PushConstant         CP#26
-  IndirectStaticCall   1, CP#1
-  PopLocal             r3
   Push                 r5
   PushConstant         CP#27
-  IndirectStaticCall   1, CP#1
-  PopLocal             r4
-  PushConstant         CP#28
-  Push                 r5
-  PushConstant         CP#29
-  IndirectStaticCall   2, CP#9
+  IndirectStaticCall   2, CP#7
   Drop1
   Push                 r0
   LoadContextVar       0
-  InstanceCall         1, CP#30
+  InstanceCall         1, CP#28
   ReturnTOS
   Push                 r0
   LoadContextParent
   PopLocal             r0
-  PushConstant         CP#3
+  PushNull
   ReturnTOS
 }
 ConstantPool {
   [0] = TypeArgumentsForInstanceAllocation dart.async::Completer [dart.core::int]
   [1] = ArgDesc num-args 1, num-type-args 0, names []
   [2] = StaticICData target 'dart.async::Completer::sync', arg-desc CP#1
-  [3] = Null
-  [4] = Int 0
-  [5] = ClosureFunction :async_op ([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding ;
-  [6] = InstanceField dart.core::_Closure::_context
-  [7] = Reserved
-  [8] = Int 42
-  [9] = ArgDesc num-args 2, num-type-args 0, names []
-  [10] = StaticICData target 'dart.async::_completeOnAsyncReturn', arg-desc CP#9
-  [11] = Type dynamic
-  [12] = ArgDesc num-args 3, num-type-args 0, names []
-  [13] = ICData target-name 'completeError', arg-desc CP#12
-  [14] = EndClosureFunctionScope
-  [15] = Class dart.core::_Closure
-  [16] = InstanceField dart.core::_Closure::_instantiator_type_arguments
+  [3] = ClosureFunction :async_op ([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding ;
+  [4] = Null
+  [5] = InstanceField dart.core::_Closure::_context
+  [6] = Reserved
+  [7] = ArgDesc num-args 2, num-type-args 0, names []
+  [8] = StaticICData target 'dart.async::_completeOnAsyncReturn', arg-desc CP#7
+  [9] = Type dynamic
+  [10] = ArgDesc num-args 3, num-type-args 0, names []
+  [11] = ICData target-name 'completeError', arg-desc CP#10
+  [12] = EndClosureFunctionScope
+  [13] = Class dart.core::_Closure
+  [14] = InstanceField dart.core::_Closure::_instantiator_type_arguments
+  [15] = Reserved
+  [16] = InstanceField dart.core::_Closure::_function_type_arguments
   [17] = Reserved
-  [18] = InstanceField dart.core::_Closure::_function_type_arguments
-  [19] = Reserved
-  [20] = EmptyTypeArguments
-  [21] = InstanceField dart.core::_Closure::_delayed_type_arguments
+  [18] = EmptyTypeArguments
+  [19] = InstanceField dart.core::_Closure::_delayed_type_arguments
+  [20] = Reserved
+  [21] = InstanceField dart.core::_Closure::_function
   [22] = Reserved
-  [23] = InstanceField dart.core::_Closure::_function
-  [24] = Reserved
-  [25] = StaticICData target 'dart.async::_asyncStackTraceHelper', arg-desc CP#1
-  [26] = StaticICData target 'dart.async::_asyncThenWrapperHelper', arg-desc CP#1
-  [27] = StaticICData target 'dart.async::_asyncErrorWrapperHelper', arg-desc CP#1
-  [28] = TypeArgumentsForInstanceAllocation dart.async::Future [dynamic]
-  [29] = StaticICData target 'dart.async::Future::microtask', arg-desc CP#9
-  [30] = ICData get target-name 'future', arg-desc CP#1
+  [23] = StaticICData target 'dart.async::_asyncStackTraceHelper', arg-desc CP#1
+  [24] = StaticICData target 'dart.async::_asyncThenWrapperHelper', arg-desc CP#1
+  [25] = StaticICData target 'dart.async::_asyncErrorWrapperHelper', arg-desc CP#1
+  [26] = TypeArgumentsForInstanceAllocation dart.async::Future [dynamic]
+  [27] = StaticICData target 'dart.async::Future::microtask', arg-desc CP#7
+  [28] = ICData get target-name 'future', arg-desc CP#1
 }
-Closure CP#5 {
+Closure CP#3 {
   EntryOptional        1, 3, 0
-  LoadConstant         r1, CP#3
-  LoadConstant         r2, CP#3
-  LoadConstant         r3, CP#3
+  LoadConstant         r1, CP#4
+  LoadConstant         r2, CP#4
+  LoadConstant         r3, CP#4
   Frame                6
   CheckStack
   Push                 r0
-  LoadFieldTOS         CP#6
+  LoadFieldTOS         CP#5
   PopLocal             r4
   Push                 r4
   LoadContextVar       2
   StoreLocal           r5
-  PushConstant         CP#4
-  IfNeStrictNumTOS
+  PushInt              0
+  IfNeStrictTOS
   Jump                 L1
   Push                 r4
   PopLocal             r6
 Try #0 start:
   Push                 r4
-  PushConstant         CP#8
+  PushInt              42
   StoreContextVar      1
   Jump                 L2
 L2:
@@ -410,10 +406,10 @@
   LoadContextVar       0
   Push                 r4
   LoadContextVar       1
-  PushConstant         CP#10
-  IndirectStaticCall   2, CP#9
+  PushConstant         CP#8
+  IndirectStaticCall   2, CP#7
   Drop1
-  PushConstant         CP#3
+  PushNull
   ReturnTOS
   Jump                 L3
 Try #0 end:
@@ -431,11 +427,11 @@
   LoadContextVar       0
   Push                 r8
   Push                 r9
-  InstanceCall         3, CP#13
+  InstanceCall         3, CP#11
   Drop1
   Jump                 L3
 L3:
-  PushConstant         CP#3
+  PushNull
   ReturnTOS
 L1:
   Trap
@@ -486,137 +482,134 @@
   IndirectStaticCall   1, CP#1
   StoreContextVar      2
   Push                 r0
-  PushConstant         CP#3
+  PushNull
   StoreContextVar      3
-  PushConstant         CP#3
+  PushNull
   PopLocal             r2
   Push                 r0
-  PushConstant         CP#3
+  PushNull
   StoreContextVar      4
   Push                 r0
-  PushConstant         CP#3
+  PushNull
   StoreContextVar      5
   Push                 r0
-  PushConstant         CP#4
+  PushInt              0
   StoreContextVar      6
   Push                 r0
-  PushConstant         CP#3
+  PushNull
   StoreContextVar      7
   Push                 r0
-  PushConstant         CP#3
+  PushNull
   StoreContextVar      8
   Push                 r0
-  PushConstant         CP#3
+  PushNull
   StoreContextVar      9
   Push                 r0
-  Allocate             CP#20
+  Allocate             CP#17
   StoreLocal           r3
   Push                 r3
-  PushConstant         CP#3
-  StoreFieldTOS        CP#21
+  PushNull
+  StoreFieldTOS        CP#18
   Push                 r3
-  PushConstant         CP#3
+  PushNull
+  StoreFieldTOS        CP#20
+  Push                 r3
+  PushConstant         CP#22
   StoreFieldTOS        CP#23
   Push                 r3
-  PushConstant         CP#25
-  StoreFieldTOS        CP#26
-  Push                 r3
-  PushConstant         CP#5
-  StoreFieldTOS        CP#28
+  PushConstant         CP#3
+  StoreFieldTOS        CP#25
   Push                 r3
   Push                 r0
-  StoreFieldTOS        CP#6
+  StoreFieldTOS        CP#5
   StoreContextVar      10
   Push                 r0
   LoadContextVar       10
-  PushConstant         CP#30
+  PushConstant         CP#27
   IndirectStaticCall   1, CP#1
   PopLocal             r2
   Push                 r0
   Push                 r0
   LoadContextVar       10
-  PushConstant         CP#31
+  PushConstant         CP#28
   IndirectStaticCall   1, CP#1
   StoreContextVar      4
   Push                 r0
   Push                 r0
   LoadContextVar       10
-  PushConstant         CP#32
+  PushConstant         CP#29
   IndirectStaticCall   1, CP#1
   StoreContextVar      5
-  PushConstant         CP#33
+  PushConstant         CP#30
   Push                 r0
   LoadContextVar       10
-  PushConstant         CP#34
-  IndirectStaticCall   2, CP#13
+  PushConstant         CP#31
+  IndirectStaticCall   2, CP#10
   Drop1
   Push                 r0
   LoadContextVar       2
-  InstanceCall         1, CP#35
+  InstanceCall         1, CP#32
   ReturnTOS
-  PushConstant         CP#3
+  PushNull
   ReturnTOS
 }
 ConstantPool {
   [0] = TypeArgumentsForInstanceAllocation dart.async::Completer [dart.core::int]
   [1] = ArgDesc num-args 1, num-type-args 0, names []
   [2] = StaticICData target 'dart.async::Completer::sync', arg-desc CP#1
-  [3] = Null
-  [4] = Int 0
-  [5] = ClosureFunction :async_op ([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding ;
-  [6] = InstanceField dart.core::_Closure::_context
-  [7] = Reserved
-  [8] = Int 1
-  [9] = ArgDesc num-args 4, num-type-args 0, names []
-  [10] = StaticICData target 'dart.async::_awaitHelper', arg-desc CP#9
-  [11] = Int 2
-  [12] = StaticICData target 'dart.async::_awaitHelper', arg-desc CP#9
-  [13] = ArgDesc num-args 2, num-type-args 0, names []
-  [14] = ICData target-name '+', arg-desc CP#13
-  [15] = StaticICData target 'dart.async::_completeOnAsyncReturn', arg-desc CP#13
-  [16] = Type dynamic
-  [17] = ArgDesc num-args 3, num-type-args 0, names []
-  [18] = ICData target-name 'completeError', arg-desc CP#17
-  [19] = EndClosureFunctionScope
-  [20] = Class dart.core::_Closure
-  [21] = InstanceField dart.core::_Closure::_instantiator_type_arguments
-  [22] = Reserved
-  [23] = InstanceField dart.core::_Closure::_function_type_arguments
+  [3] = ClosureFunction :async_op ([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding ;
+  [4] = Null
+  [5] = InstanceField dart.core::_Closure::_context
+  [6] = Reserved
+  [7] = ArgDesc num-args 4, num-type-args 0, names []
+  [8] = StaticICData target 'dart.async::_awaitHelper', arg-desc CP#7
+  [9] = StaticICData target 'dart.async::_awaitHelper', arg-desc CP#7
+  [10] = ArgDesc num-args 2, num-type-args 0, names []
+  [11] = ICData target-name '+', arg-desc CP#10
+  [12] = StaticICData target 'dart.async::_completeOnAsyncReturn', arg-desc CP#10
+  [13] = Type dynamic
+  [14] = ArgDesc num-args 3, num-type-args 0, names []
+  [15] = ICData target-name 'completeError', arg-desc CP#14
+  [16] = EndClosureFunctionScope
+  [17] = Class dart.core::_Closure
+  [18] = InstanceField dart.core::_Closure::_instantiator_type_arguments
+  [19] = Reserved
+  [20] = InstanceField dart.core::_Closure::_function_type_arguments
+  [21] = Reserved
+  [22] = EmptyTypeArguments
+  [23] = InstanceField dart.core::_Closure::_delayed_type_arguments
   [24] = Reserved
-  [25] = EmptyTypeArguments
-  [26] = InstanceField dart.core::_Closure::_delayed_type_arguments
-  [27] = Reserved
-  [28] = InstanceField dart.core::_Closure::_function
-  [29] = Reserved
-  [30] = StaticICData target 'dart.async::_asyncStackTraceHelper', arg-desc CP#1
-  [31] = StaticICData target 'dart.async::_asyncThenWrapperHelper', arg-desc CP#1
-  [32] = StaticICData target 'dart.async::_asyncErrorWrapperHelper', arg-desc CP#1
-  [33] = TypeArgumentsForInstanceAllocation dart.async::Future [dynamic]
-  [34] = StaticICData target 'dart.async::Future::microtask', arg-desc CP#13
-  [35] = ICData get target-name 'future', arg-desc CP#1
+  [25] = InstanceField dart.core::_Closure::_function
+  [26] = Reserved
+  [27] = StaticICData target 'dart.async::_asyncStackTraceHelper', arg-desc CP#1
+  [28] = StaticICData target 'dart.async::_asyncThenWrapperHelper', arg-desc CP#1
+  [29] = StaticICData target 'dart.async::_asyncErrorWrapperHelper', arg-desc CP#1
+  [30] = TypeArgumentsForInstanceAllocation dart.async::Future [dynamic]
+  [31] = StaticICData target 'dart.async::Future::microtask', arg-desc CP#10
+  [32] = ICData get target-name 'future', arg-desc CP#1
 }
-Closure CP#5 {
+Closure CP#3 {
   EntryOptional        1, 3, 0
-  LoadConstant         r1, CP#3
-  LoadConstant         r2, CP#3
-  LoadConstant         r3, CP#3
+  LoadConstant         r1, CP#4
+  LoadConstant         r2, CP#4
+  LoadConstant         r3, CP#4
   Frame                6
   CheckStack
   Push                 r0
-  LoadFieldTOS         CP#6
+  LoadFieldTOS         CP#5
   PopLocal             r4
   Push                 r4
   LoadContextVar       6
   StoreLocal           r5
-  PushConstant         CP#4
-  IfNeStrictNumTOS
+  PushInt              0
+  IfNeStrictTOS
   Jump                 L1
   Push                 r4
   Push                 r4
   StoreContextVar      8
 Try #0 start:
   Push                 r4
-  PushConstant         CP#8
+  PushInt              1
   StoreContextVar      6
   Push                 r4
   Push                 r4
@@ -629,10 +622,10 @@
   LoadContextVar       5
   Push                 r4
   LoadContextVar       10
-  PushConstant         CP#10
-  IndirectStaticCall   4, CP#9
+  PushConstant         CP#8
+  IndirectStaticCall   4, CP#7
   PopLocal             r8
-  PushConstant         CP#3
+  PushNull
   ReturnTOS
 L6:
   IfEqNull             r2
@@ -645,7 +638,7 @@
   Push                 r1
   StoreContextVar      9
   Push                 r4
-  PushConstant         CP#11
+  PushInt              2
   StoreContextVar      6
   Push                 r4
   Push                 r4
@@ -658,10 +651,10 @@
   LoadContextVar       5
   Push                 r4
   LoadContextVar       10
-  PushConstant         CP#12
-  IndirectStaticCall   4, CP#9
+  PushConstant         CP#9
+  IndirectStaticCall   4, CP#7
   PopLocal             r9
-  PushConstant         CP#3
+  PushNull
   ReturnTOS
 L7:
   IfEqNull             r2
@@ -674,7 +667,7 @@
   Push                 r4
   LoadContextVar       9
   Push                 r1
-  InstanceCall         2, CP#14
+  InstanceCall         2, CP#11
   StoreContextVar      3
   Jump                 L4
 L4:
@@ -682,17 +675,17 @@
   LoadContextVar       2
   Push                 r4
   LoadContextVar       3
-  PushConstant         CP#15
-  IndirectStaticCall   2, CP#13
+  PushConstant         CP#12
+  IndirectStaticCall   2, CP#10
   Drop1
-  PushConstant         CP#3
+  PushNull
   ReturnTOS
   Jump                 L5
 Try #0 end:
 Try #0 handler:
   SetFrame             10
   Push                 r0
-  LoadFieldTOS         CP#6
+  LoadFieldTOS         CP#5
   PopLocal             r4
   Push                 r4
   LoadContextVar       8
@@ -707,19 +700,19 @@
   LoadContextVar       2
   Push                 r8
   Push                 r9
-  InstanceCall         3, CP#18
+  InstanceCall         3, CP#15
   Drop1
   Jump                 L5
 L5:
-  PushConstant         CP#3
+  PushNull
   ReturnTOS
 L1:
   Push                 r4
   LoadContextVar       7
   PopLocal             r4
   Push                 r5
-  PushConstant         CP#8
-  IfEqStrictNumTOS
+  PushInt              1
+  IfEqStrictTOS
   Jump                 L6
   Jump                 L7
 
@@ -771,145 +764,141 @@
   IndirectStaticCall   1, CP#1
   StoreContextVar      1
   Push                 r0
-  PushConstant         CP#3
+  PushNull
   StoreContextVar      2
-  PushConstant         CP#3
+  PushNull
   PopLocal             r2
   Push                 r0
-  PushConstant         CP#3
+  PushNull
   StoreContextVar      3
   Push                 r0
-  PushConstant         CP#3
+  PushNull
   StoreContextVar      4
   Push                 r0
-  PushConstant         CP#4
+  PushInt              0
   StoreContextVar      5
   Push                 r0
-  PushConstant         CP#3
+  PushNull
   StoreContextVar      6
   Push                 r0
-  PushConstant         CP#3
+  PushNull
   StoreContextVar      7
   Push                 r0
-  PushConstant         CP#3
+  PushNull
   StoreContextVar      8
   Push                 r0
-  PushConstant         CP#3
+  PushNull
   StoreContextVar      9
   Push                 r0
-  Allocate             CP#32
+  Allocate             CP#28
   StoreLocal           r3
   Push                 r3
-  PushConstant         CP#3
-  StoreFieldTOS        CP#33
+  PushNull
+  StoreFieldTOS        CP#29
+  Push                 r3
+  PushNull
+  StoreFieldTOS        CP#31
+  Push                 r3
+  PushConstant         CP#33
+  StoreFieldTOS        CP#34
   Push                 r3
   PushConstant         CP#3
-  StoreFieldTOS        CP#35
-  Push                 r3
-  PushConstant         CP#37
-  StoreFieldTOS        CP#38
-  Push                 r3
-  PushConstant         CP#5
-  StoreFieldTOS        CP#40
+  StoreFieldTOS        CP#36
   Push                 r3
   Push                 r0
-  StoreFieldTOS        CP#6
+  StoreFieldTOS        CP#5
   StoreContextVar      10
   Push                 r0
   LoadContextVar       10
-  PushConstant         CP#42
+  PushConstant         CP#38
   IndirectStaticCall   1, CP#1
   PopLocal             r2
   Push                 r0
   Push                 r0
   LoadContextVar       10
-  PushConstant         CP#43
+  PushConstant         CP#39
   IndirectStaticCall   1, CP#1
   StoreContextVar      3
   Push                 r0
   Push                 r0
   LoadContextVar       10
-  PushConstant         CP#44
+  PushConstant         CP#40
   IndirectStaticCall   1, CP#1
   StoreContextVar      4
-  PushConstant         CP#45
+  PushConstant         CP#41
   Push                 r0
   LoadContextVar       10
-  PushConstant         CP#46
-  IndirectStaticCall   2, CP#9
+  PushConstant         CP#42
+  IndirectStaticCall   2, CP#7
   Drop1
   Push                 r0
   LoadContextVar       1
-  InstanceCall         1, CP#47
+  InstanceCall         1, CP#43
   ReturnTOS
-  PushConstant         CP#3
+  PushNull
   ReturnTOS
 }
 ConstantPool {
   [0] = TypeArgumentsForInstanceAllocation dart.async::Completer [dart.core::int]
   [1] = ArgDesc num-args 1, num-type-args 0, names []
   [2] = StaticICData target 'dart.async::Completer::sync', arg-desc CP#1
-  [3] = Null
-  [4] = Int 0
-  [5] = ClosureFunction :async_op ([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding ;
-  [6] = InstanceField dart.core::_Closure::_context
-  [7] = Reserved
-  [8] = Int 10
-  [9] = ArgDesc num-args 2, num-type-args 0, names []
-  [10] = ICData target-name '<', arg-desc CP#9
-  [11] = Bool true
-  [12] = ICData get target-name 'iterator', arg-desc CP#1
-  [13] = ICData target-name 'moveNext', arg-desc CP#1
-  [14] = ICData get target-name 'current', arg-desc CP#1
-  [15] = ICData target-name '+', arg-desc CP#9
-  [16] = Int 1
-  [17] = ArgDesc num-args 0, num-type-args 0, names []
-  [18] = StaticICData target '#lib::foo', arg-desc CP#17
-  [19] = ArgDesc num-args 4, num-type-args 0, names []
-  [20] = StaticICData target 'dart.async::_awaitHelper', arg-desc CP#19
-  [21] = ICData target-name '+', arg-desc CP#9
-  [22] = ICData target-name '+', arg-desc CP#9
-  [23] = ICData target-name '+', arg-desc CP#9
-  [24] = ICData target-name '<', arg-desc CP#9
-  [25] = ICData target-name '+', arg-desc CP#9
-  [26] = ICData target-name '+', arg-desc CP#9
-  [27] = StaticICData target 'dart.async::_completeOnAsyncReturn', arg-desc CP#9
-  [28] = Type dynamic
-  [29] = ArgDesc num-args 3, num-type-args 0, names []
-  [30] = ICData target-name 'completeError', arg-desc CP#29
-  [31] = EndClosureFunctionScope
-  [32] = Class dart.core::_Closure
-  [33] = InstanceField dart.core::_Closure::_instantiator_type_arguments
-  [34] = Reserved
-  [35] = InstanceField dart.core::_Closure::_function_type_arguments
-  [36] = Reserved
-  [37] = EmptyTypeArguments
-  [38] = InstanceField dart.core::_Closure::_delayed_type_arguments
-  [39] = Reserved
-  [40] = InstanceField dart.core::_Closure::_function
-  [41] = Reserved
-  [42] = StaticICData target 'dart.async::_asyncStackTraceHelper', arg-desc CP#1
-  [43] = StaticICData target 'dart.async::_asyncThenWrapperHelper', arg-desc CP#1
-  [44] = StaticICData target 'dart.async::_asyncErrorWrapperHelper', arg-desc CP#1
-  [45] = TypeArgumentsForInstanceAllocation dart.async::Future [dynamic]
-  [46] = StaticICData target 'dart.async::Future::microtask', arg-desc CP#9
-  [47] = ICData get target-name 'future', arg-desc CP#1
+  [3] = ClosureFunction :async_op ([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding ;
+  [4] = Null
+  [5] = InstanceField dart.core::_Closure::_context
+  [6] = Reserved
+  [7] = ArgDesc num-args 2, num-type-args 0, names []
+  [8] = ICData target-name '<', arg-desc CP#7
+  [9] = ICData get target-name 'iterator', arg-desc CP#1
+  [10] = ICData target-name 'moveNext', arg-desc CP#1
+  [11] = ICData get target-name 'current', arg-desc CP#1
+  [12] = ICData target-name '+', arg-desc CP#7
+  [13] = ArgDesc num-args 0, num-type-args 0, names []
+  [14] = StaticICData target '#lib::foo', arg-desc CP#13
+  [15] = ArgDesc num-args 4, num-type-args 0, names []
+  [16] = StaticICData target 'dart.async::_awaitHelper', arg-desc CP#15
+  [17] = ICData target-name '+', arg-desc CP#7
+  [18] = ICData target-name '+', arg-desc CP#7
+  [19] = ICData target-name '+', arg-desc CP#7
+  [20] = ICData target-name '<', arg-desc CP#7
+  [21] = ICData target-name '+', arg-desc CP#7
+  [22] = ICData target-name '+', arg-desc CP#7
+  [23] = StaticICData target 'dart.async::_completeOnAsyncReturn', arg-desc CP#7
+  [24] = Type dynamic
+  [25] = ArgDesc num-args 3, num-type-args 0, names []
+  [26] = ICData target-name 'completeError', arg-desc CP#25
+  [27] = EndClosureFunctionScope
+  [28] = Class dart.core::_Closure
+  [29] = InstanceField dart.core::_Closure::_instantiator_type_arguments
+  [30] = Reserved
+  [31] = InstanceField dart.core::_Closure::_function_type_arguments
+  [32] = Reserved
+  [33] = EmptyTypeArguments
+  [34] = InstanceField dart.core::_Closure::_delayed_type_arguments
+  [35] = Reserved
+  [36] = InstanceField dart.core::_Closure::_function
+  [37] = Reserved
+  [38] = StaticICData target 'dart.async::_asyncStackTraceHelper', arg-desc CP#1
+  [39] = StaticICData target 'dart.async::_asyncThenWrapperHelper', arg-desc CP#1
+  [40] = StaticICData target 'dart.async::_asyncErrorWrapperHelper', arg-desc CP#1
+  [41] = TypeArgumentsForInstanceAllocation dart.async::Future [dynamic]
+  [42] = StaticICData target 'dart.async::Future::microtask', arg-desc CP#7
+  [43] = ICData get target-name 'future', arg-desc CP#1
 }
-Closure CP#5 {
+Closure CP#3 {
   EntryOptional        1, 3, 0
-  LoadConstant         r1, CP#3
-  LoadConstant         r2, CP#3
-  LoadConstant         r3, CP#3
+  LoadConstant         r1, CP#4
+  LoadConstant         r2, CP#4
+  LoadConstant         r3, CP#4
   Frame                7
   CheckStack
   Push                 r0
-  LoadFieldTOS         CP#6
+  LoadFieldTOS         CP#5
   PopLocal             r4
   Push                 r4
   LoadContextVar       5
   StoreLocal           r5
-  PushConstant         CP#4
-  IfNeStrictNumTOS
+  PushInt              0
+  IfNeStrictTOS
   Jump                 L1
   Push                 r4
   Push                 r4
@@ -922,7 +911,7 @@
   StoreContextParent
   PopLocal             r4
   Push                 r4
-  PushConstant         CP#4
+  PushInt              0
   StoreContextVar      0
   AllocateContext      2
   StoreLocal           r5
@@ -931,23 +920,23 @@
   StoreContextParent
   PopLocal             r4
   Push                 r4
-  PushConstant         CP#4
+  PushInt              0
   StoreContextVar      0
 L6:
   CheckStack
   Push                 r4
   LoadContextVar       0
-  PushConstant         CP#8
-  InstanceCall         2, CP#10
+  PushInt              10
+  InstanceCall         2, CP#8
   AssertBoolean        0
-  PushConstant         CP#11
+  PushTrue
   IfNeStrictTOS
   Jump                 L2
   Push                 r4
   LoadContextParent
   LoadContextParent
   LoadContextVar       0
-  InstanceCall         1, CP#12
+  InstanceCall         1, CP#9
   PopLocal             r8
   Push                 r4
   Push                 r8
@@ -957,8 +946,8 @@
   Push                 r4
   LoadContextVar       1
   StoreLocal           r8
-  InstanceCall         1, CP#13
-  PushConstant         CP#11
+  InstanceCall         1, CP#10
+  PushTrue
   IfNeStrictTOS
   Jump                 L3
   AllocateContext      1
@@ -969,7 +958,7 @@
   PopLocal             r4
   Push                 r4
   Push                 r8
-  InstanceCall         1, CP#14
+  InstanceCall         1, CP#11
   StoreContextVar      0
   Push                 r4
   LoadContextParent
@@ -989,13 +978,13 @@
   LoadContextVar       0
   Push                 r4
   LoadContextVar       0
-  InstanceCall         2, CP#15
+  InstanceCall         2, CP#12
   StoreContextVar      8
   Push                 r4
   LoadContextParent
   LoadContextParent
   LoadContextParent
-  PushConstant         CP#16
+  PushInt              1
   StoreContextVar      5
   Push                 r4
   LoadContextParent
@@ -1003,8 +992,8 @@
   LoadContextParent
   Push                 r4
   StoreContextVar      6
-  PushConstant         CP#18
-  IndirectStaticCall   0, CP#17
+  PushConstant         CP#14
+  IndirectStaticCall   0, CP#13
   Push                 r4
   LoadContextParent
   LoadContextParent
@@ -1020,10 +1009,10 @@
   LoadContextParent
   LoadContextParent
   LoadContextVar       10
-  PushConstant         CP#20
-  IndirectStaticCall   4, CP#19
+  PushConstant         CP#16
+  IndirectStaticCall   4, CP#15
   PopLocal             r10
-  PushConstant         CP#3
+  PushNull
   ReturnTOS
 L11:
   IfEqNull             r2
@@ -1046,8 +1035,8 @@
   LoadContextParent
   LoadContextVar       8
   Push                 r1
-  InstanceCall         2, CP#21
-  InstanceCall         2, CP#22
+  InstanceCall         2, CP#17
+  InstanceCall         2, CP#18
   StoreContextVar      0
   Push                 r4
   LoadContextParent
@@ -1060,8 +1049,8 @@
   Push                 r4
   Push                 r4
   LoadContextVar       0
-  PushConstant         CP#16
-  InstanceCall         2, CP#23
+  PushInt              1
+  InstanceCall         2, CP#19
   StoreLocal           r8
   StoreContextVar      0
   Push                 r8
@@ -1071,26 +1060,26 @@
   Push                 r4
   LoadContextParent
   PopLocal             r4
-  PushConstant         CP#4
+  PushInt              0
   PopLocal             r8
 L8:
   CheckStack
   Push                 r8
-  PushConstant         CP#8
-  InstanceCall         2, CP#24
+  PushInt              10
+  InstanceCall         2, CP#20
   AssertBoolean        0
-  PushConstant         CP#11
+  PushTrue
   IfNeStrictTOS
   Jump                 L7
   Push                 r4
   Push                 r4
   LoadContextVar       0
   Push                 r8
-  InstanceCall         2, CP#25
+  InstanceCall         2, CP#21
   StoreContextVar      0
   Push                 r8
-  PushConstant         CP#16
-  InstanceCall         2, CP#26
+  PushInt              1
+  InstanceCall         2, CP#22
   StoreLocal           r8
   Drop1
   Jump                 L8
@@ -1112,17 +1101,17 @@
   LoadContextVar       1
   Push                 r4
   LoadContextVar       2
-  PushConstant         CP#27
-  IndirectStaticCall   2, CP#9
+  PushConstant         CP#23
+  IndirectStaticCall   2, CP#7
   Drop1
-  PushConstant         CP#3
+  PushNull
   ReturnTOS
   Jump                 L10
 Try #0 end:
 Try #0 handler:
   SetFrame             11
   Push                 r0
-  LoadFieldTOS         CP#6
+  LoadFieldTOS         CP#5
   PopLocal             r4
   Push                 r4
   LoadContextVar       7
@@ -1137,11 +1126,11 @@
   LoadContextVar       1
   Push                 r8
   Push                 r9
-  InstanceCall         3, CP#30
+  InstanceCall         3, CP#26
   Drop1
   Jump                 L10
 L10:
-  PushConstant         CP#3
+  PushNull
   ReturnTOS
 L1:
   Push                 r4
@@ -1213,160 +1202,152 @@
   IndirectStaticCall   1, CP#1
   StoreContextVar      3
   Push                 r0
-  PushConstant         CP#3
+  PushNull
   StoreContextVar      4
-  PushConstant         CP#3
+  PushNull
   PopLocal             r2
   Push                 r0
-  PushConstant         CP#3
+  PushNull
   StoreContextVar      5
   Push                 r0
-  PushConstant         CP#3
+  PushNull
   StoreContextVar      6
   Push                 r0
-  PushConstant         CP#4
+  PushInt              0
   StoreContextVar      7
   Push                 r0
-  PushConstant         CP#3
+  PushNull
   StoreContextVar      8
   Push                 r0
-  PushConstant         CP#3
+  PushNull
   StoreContextVar      9
   Push                 r0
-  PushConstant         CP#3
+  PushNull
   StoreContextVar      10
   Push                 r0
-  PushConstant         CP#3
+  PushNull
   StoreContextVar      11
   Push                 r0
-  PushConstant         CP#3
+  PushNull
   StoreContextVar      12
   Push                 r0
-  PushConstant         CP#3
+  PushNull
   StoreContextVar      13
   Push                 r0
-  PushConstant         CP#3
+  PushNull
   StoreContextVar      14
   Push                 r0
-  Allocate             CP#38
+  Allocate             CP#30
   StoreLocal           r3
   Push                 r3
-  PushConstant         CP#3
-  StoreFieldTOS        CP#39
+  PushNull
+  StoreFieldTOS        CP#31
+  Push                 r3
+  PushNull
+  StoreFieldTOS        CP#33
+  Push                 r3
+  PushConstant         CP#35
+  StoreFieldTOS        CP#36
   Push                 r3
   PushConstant         CP#3
-  StoreFieldTOS        CP#41
-  Push                 r3
-  PushConstant         CP#43
-  StoreFieldTOS        CP#44
-  Push                 r3
-  PushConstant         CP#5
-  StoreFieldTOS        CP#46
+  StoreFieldTOS        CP#38
   Push                 r3
   Push                 r0
-  StoreFieldTOS        CP#6
+  StoreFieldTOS        CP#5
   StoreContextVar      15
   Push                 r0
   LoadContextVar       15
-  PushConstant         CP#48
+  PushConstant         CP#40
   IndirectStaticCall   1, CP#1
   PopLocal             r2
   Push                 r0
   Push                 r0
   LoadContextVar       15
-  PushConstant         CP#49
+  PushConstant         CP#41
   IndirectStaticCall   1, CP#1
   StoreContextVar      5
   Push                 r0
   Push                 r0
   LoadContextVar       15
-  PushConstant         CP#50
+  PushConstant         CP#42
   IndirectStaticCall   1, CP#1
   StoreContextVar      6
-  PushConstant         CP#51
+  PushConstant         CP#43
   Push                 r0
   LoadContextVar       15
-  PushConstant         CP#52
-  IndirectStaticCall   2, CP#11
+  PushConstant         CP#44
+  IndirectStaticCall   2, CP#9
   Drop1
   Push                 r0
   LoadContextVar       3
-  InstanceCall         1, CP#53
+  InstanceCall         1, CP#45
   ReturnTOS
-  PushConstant         CP#3
+  PushNull
   ReturnTOS
 }
 ConstantPool {
   [0] = TypeArgumentsForInstanceAllocation dart.async::Completer [dart.core::int]
   [1] = ArgDesc num-args 1, num-type-args 0, names []
   [2] = StaticICData target 'dart.async::Completer::sync', arg-desc CP#1
-  [3] = Null
-  [4] = Int 0
-  [5] = ClosureFunction :async_op ([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding ;
-  [6] = InstanceField dart.core::_Closure::_context
-  [7] = Reserved
-  [8] = Int 1
-  [9] = ArgDesc num-args 4, num-type-args 0, names []
-  [10] = StaticICData target 'dart.async::_awaitHelper', arg-desc CP#9
-  [11] = ArgDesc num-args 2, num-type-args 0, names []
-  [12] = ICData target-name '+', arg-desc CP#11
-  [13] = Type dynamic
-  [14] = Type dart.core::Error
-  [15] = ICData target-name 'dart.core::_instanceOf', arg-desc CP#9
-  [16] = Bool true
-  [17] = Int 42
-  [18] = Int 2
-  [19] = StaticICData target 'dart.async::_awaitHelper', arg-desc CP#9
-  [20] = ICData target-name '+', arg-desc CP#11
-  [21] = String 'fin'
-  [22] = StaticICData target 'dart.core::print', arg-desc CP#1
-  [23] = Int 3
-  [24] = StaticICData target 'dart.async::_awaitHelper', arg-desc CP#9
-  [25] = ICData target-name '+', arg-desc CP#11
-  [26] = StaticICData target 'dart.core::print', arg-desc CP#1
-  [27] = Int 4
-  [28] = StaticICData target 'dart.async::_awaitHelper', arg-desc CP#9
-  [29] = ICData target-name '+', arg-desc CP#11
-  [30] = StaticICData target 'dart.core::print', arg-desc CP#1
-  [31] = Int 5
-  [32] = StaticICData target 'dart.async::_awaitHelper', arg-desc CP#9
-  [33] = ICData target-name '+', arg-desc CP#11
-  [34] = StaticICData target 'dart.async::_completeOnAsyncReturn', arg-desc CP#11
-  [35] = ArgDesc num-args 3, num-type-args 0, names []
-  [36] = ICData target-name 'completeError', arg-desc CP#35
-  [37] = EndClosureFunctionScope
-  [38] = Class dart.core::_Closure
-  [39] = InstanceField dart.core::_Closure::_instantiator_type_arguments
-  [40] = Reserved
-  [41] = InstanceField dart.core::_Closure::_function_type_arguments
-  [42] = Reserved
-  [43] = EmptyTypeArguments
-  [44] = InstanceField dart.core::_Closure::_delayed_type_arguments
-  [45] = Reserved
-  [46] = InstanceField dart.core::_Closure::_function
-  [47] = Reserved
-  [48] = StaticICData target 'dart.async::_asyncStackTraceHelper', arg-desc CP#1
-  [49] = StaticICData target 'dart.async::_asyncThenWrapperHelper', arg-desc CP#1
-  [50] = StaticICData target 'dart.async::_asyncErrorWrapperHelper', arg-desc CP#1
-  [51] = TypeArgumentsForInstanceAllocation dart.async::Future [dynamic]
-  [52] = StaticICData target 'dart.async::Future::microtask', arg-desc CP#11
-  [53] = ICData get target-name 'future', arg-desc CP#1
+  [3] = ClosureFunction :async_op ([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding ;
+  [4] = Null
+  [5] = InstanceField dart.core::_Closure::_context
+  [6] = Reserved
+  [7] = ArgDesc num-args 4, num-type-args 0, names []
+  [8] = StaticICData target 'dart.async::_awaitHelper', arg-desc CP#7
+  [9] = ArgDesc num-args 2, num-type-args 0, names []
+  [10] = ICData target-name '+', arg-desc CP#9
+  [11] = Type dynamic
+  [12] = Type dart.core::Error
+  [13] = ICData target-name 'dart.core::_instanceOf', arg-desc CP#7
+  [14] = StaticICData target 'dart.async::_awaitHelper', arg-desc CP#7
+  [15] = ICData target-name '+', arg-desc CP#9
+  [16] = String 'fin'
+  [17] = StaticICData target 'dart.core::print', arg-desc CP#1
+  [18] = StaticICData target 'dart.async::_awaitHelper', arg-desc CP#7
+  [19] = ICData target-name '+', arg-desc CP#9
+  [20] = StaticICData target 'dart.core::print', arg-desc CP#1
+  [21] = StaticICData target 'dart.async::_awaitHelper', arg-desc CP#7
+  [22] = ICData target-name '+', arg-desc CP#9
+  [23] = StaticICData target 'dart.core::print', arg-desc CP#1
+  [24] = StaticICData target 'dart.async::_awaitHelper', arg-desc CP#7
+  [25] = ICData target-name '+', arg-desc CP#9
+  [26] = StaticICData target 'dart.async::_completeOnAsyncReturn', arg-desc CP#9
+  [27] = ArgDesc num-args 3, num-type-args 0, names []
+  [28] = ICData target-name 'completeError', arg-desc CP#27
+  [29] = EndClosureFunctionScope
+  [30] = Class dart.core::_Closure
+  [31] = InstanceField dart.core::_Closure::_instantiator_type_arguments
+  [32] = Reserved
+  [33] = InstanceField dart.core::_Closure::_function_type_arguments
+  [34] = Reserved
+  [35] = EmptyTypeArguments
+  [36] = InstanceField dart.core::_Closure::_delayed_type_arguments
+  [37] = Reserved
+  [38] = InstanceField dart.core::_Closure::_function
+  [39] = Reserved
+  [40] = StaticICData target 'dart.async::_asyncStackTraceHelper', arg-desc CP#1
+  [41] = StaticICData target 'dart.async::_asyncThenWrapperHelper', arg-desc CP#1
+  [42] = StaticICData target 'dart.async::_asyncErrorWrapperHelper', arg-desc CP#1
+  [43] = TypeArgumentsForInstanceAllocation dart.async::Future [dynamic]
+  [44] = StaticICData target 'dart.async::Future::microtask', arg-desc CP#9
+  [45] = ICData get target-name 'future', arg-desc CP#1
 }
-Closure CP#5 {
+Closure CP#3 {
   EntryOptional        1, 3, 0
-  LoadConstant         r1, CP#3
-  LoadConstant         r2, CP#3
-  LoadConstant         r3, CP#3
+  LoadConstant         r1, CP#4
+  LoadConstant         r2, CP#4
+  LoadConstant         r3, CP#4
   Frame                10
   CheckStack
   Push                 r0
-  LoadFieldTOS         CP#6
+  LoadFieldTOS         CP#5
   PopLocal             r4
   Push                 r4
   LoadContextVar       7
   StoreLocal           r5
-  PushConstant         CP#4
-  IfNeStrictNumTOS
+  PushInt              0
+  IfNeStrictTOS
   Jump                 L1
   Push                 r4
   Push                 r4
@@ -1379,7 +1360,7 @@
   StoreContextParent
   PopLocal             r4
   Push                 r4
-  PushConstant         CP#8
+  PushInt              1
   StoreContextVar      0
   Push                 r4
   LoadContextParent
@@ -1398,7 +1379,7 @@
   StoreContextVar      14
   Push                 r4
   LoadContextParent
-  PushConstant         CP#8
+  PushInt              1
   StoreContextVar      7
   Push                 r4
   LoadContextParent
@@ -1416,10 +1397,10 @@
   Push                 r4
   LoadContextParent
   LoadContextVar       15
-  PushConstant         CP#10
-  IndirectStaticCall   4, CP#9
+  PushConstant         CP#8
+  IndirectStaticCall   4, CP#7
   PopLocal             r13
-  PushConstant         CP#3
+  PushNull
   ReturnTOS
 L13:
   IfEqNull             r2
@@ -1433,14 +1414,14 @@
   LoadContextParent
   LoadContextVar       14
   Push                 r1
-  InstanceCall         2, CP#12
+  InstanceCall         2, CP#10
   StoreContextVar      0
   Jump                 L3
 Try #2 end:
 Try #2 handler:
   SetFrame             14
   Push                 r0
-  LoadFieldTOS         CP#6
+  LoadFieldTOS         CP#5
   PopLocal             r4
   Push                 r4
   LoadContextVar       11
@@ -1460,17 +1441,17 @@
   StoreContextVar      1
   Push                 r4
   LoadContextVar       1
-  PushConstant         CP#3
-  PushConstant         CP#3
-  PushConstant         CP#14
-  InstanceCall         4, CP#15
+  PushNull
+  PushNull
+  PushConstant         CP#12
+  InstanceCall         4, CP#13
   AssertBoolean        0
-  PushConstant         CP#16
+  PushTrue
   IfNeStrictTOS
   Jump                 L4
   Push                 r4
   LoadContextParent
-  PushConstant         CP#17
+  PushInt              42
   StoreContextVar      4
   Jump                 L5
 L4:
@@ -1481,7 +1462,7 @@
   StoreContextVar      14
   Push                 r4
   LoadContextParent
-  PushConstant         CP#18
+  PushInt              2
   StoreContextVar      7
   Push                 r4
   LoadContextParent
@@ -1499,10 +1480,10 @@
   Push                 r4
   LoadContextParent
   LoadContextVar       15
-  PushConstant         CP#19
-  IndirectStaticCall   4, CP#9
+  PushConstant         CP#14
+  IndirectStaticCall   4, CP#7
   PopLocal             r13
-  PushConstant         CP#3
+  PushNull
   ReturnTOS
 L14:
   IfEqNull             r2
@@ -1516,7 +1497,7 @@
   LoadContextParent
   LoadContextVar       14
   Push                 r1
-  InstanceCall         2, CP#20
+  InstanceCall         2, CP#15
   StoreContextVar      0
   Push                 r4
   LoadContextParent
@@ -1533,7 +1514,7 @@
 Try #1 handler:
   SetFrame             14
   Push                 r0
-  LoadFieldTOS         CP#6
+  LoadFieldTOS         CP#5
   PopLocal             r4
   Push                 r4
   LoadContextVar       10
@@ -1548,8 +1529,8 @@
   LoadContextParent
   Push                 r9
   StoreContextVar      13
-  PushConstant         CP#21
-  PushConstant         CP#22
+  PushConstant         CP#16
+  PushConstant         CP#17
   IndirectStaticCall   1, CP#1
   Drop1
   Push                 r4
@@ -1559,7 +1540,7 @@
   StoreContextVar      14
   Push                 r4
   LoadContextParent
-  PushConstant         CP#23
+  PushInt              3
   StoreContextVar      7
   Push                 r4
   LoadContextParent
@@ -1577,10 +1558,10 @@
   Push                 r4
   LoadContextParent
   LoadContextVar       15
-  PushConstant         CP#24
-  IndirectStaticCall   4, CP#9
+  PushConstant         CP#18
+  IndirectStaticCall   4, CP#7
   PopLocal             r12
-  PushConstant         CP#3
+  PushNull
   ReturnTOS
 L15:
   IfEqNull             r2
@@ -1594,7 +1575,7 @@
   LoadContextParent
   LoadContextVar       14
   Push                 r1
-  InstanceCall         2, CP#25
+  InstanceCall         2, CP#19
   StoreContextVar      0
   Push                 r4
   LoadContextParent
@@ -1614,13 +1595,13 @@
   Throw                1
 L5:
   Push                 r0
-  LoadFieldTOS         CP#6
+  LoadFieldTOS         CP#5
   PopLocal             r4
   Push                 r4
   LoadContextVar       10
   PopLocal             r4
-  PushConstant         CP#21
-  PushConstant         CP#26
+  PushConstant         CP#16
+  PushConstant         CP#20
   IndirectStaticCall   1, CP#1
   Drop1
   Push                 r4
@@ -1630,7 +1611,7 @@
   StoreContextVar      14
   Push                 r4
   LoadContextParent
-  PushConstant         CP#27
+  PushInt              4
   StoreContextVar      7
   Push                 r4
   LoadContextParent
@@ -1648,10 +1629,10 @@
   Push                 r4
   LoadContextParent
   LoadContextVar       15
-  PushConstant         CP#28
-  IndirectStaticCall   4, CP#9
+  PushConstant         CP#21
+  IndirectStaticCall   4, CP#7
   PopLocal             r12
-  PushConstant         CP#3
+  PushNull
   ReturnTOS
 L16:
   IfEqNull             r2
@@ -1665,7 +1646,7 @@
   LoadContextParent
   LoadContextVar       14
   Push                 r1
-  InstanceCall         2, CP#29
+  InstanceCall         2, CP#22
   StoreContextVar      0
   Push                 r4
   LoadContextParent
@@ -1682,13 +1663,13 @@
   Jump                 L9
 L7:
   Push                 r0
-  LoadFieldTOS         CP#6
+  LoadFieldTOS         CP#5
   PopLocal             r4
   Push                 r4
   LoadContextVar       10
   PopLocal             r4
-  PushConstant         CP#21
-  PushConstant         CP#30
+  PushConstant         CP#16
+  PushConstant         CP#23
   IndirectStaticCall   1, CP#1
   Drop1
   Push                 r4
@@ -1698,7 +1679,7 @@
   StoreContextVar      14
   Push                 r4
   LoadContextParent
-  PushConstant         CP#31
+  PushInt              5
   StoreContextVar      7
   Push                 r4
   LoadContextParent
@@ -1716,10 +1697,10 @@
   Push                 r4
   LoadContextParent
   LoadContextVar       15
-  PushConstant         CP#32
-  IndirectStaticCall   4, CP#9
+  PushConstant         CP#24
+  IndirectStaticCall   4, CP#7
   PopLocal             r12
-  PushConstant         CP#3
+  PushNull
   ReturnTOS
 L17:
   IfEqNull             r2
@@ -1733,7 +1714,7 @@
   LoadContextParent
   LoadContextVar       14
   Push                 r1
-  InstanceCall         2, CP#33
+  InstanceCall         2, CP#25
   StoreContextVar      0
   Push                 r4
   LoadContextParent
@@ -1752,17 +1733,17 @@
   LoadContextVar       3
   Push                 r4
   LoadContextVar       4
-  PushConstant         CP#34
-  IndirectStaticCall   2, CP#11
+  PushConstant         CP#26
+  IndirectStaticCall   2, CP#9
   Drop1
-  PushConstant         CP#3
+  PushNull
   ReturnTOS
   Jump                 L12
 Try #0 end:
 Try #0 handler:
   SetFrame             14
   Push                 r0
-  LoadFieldTOS         CP#6
+  LoadFieldTOS         CP#5
   PopLocal             r4
   Push                 r4
   LoadContextVar       9
@@ -1777,31 +1758,31 @@
   LoadContextVar       3
   Push                 r8
   Push                 r9
-  InstanceCall         3, CP#36
+  InstanceCall         3, CP#28
   Drop1
   Jump                 L12
 L12:
-  PushConstant         CP#3
+  PushNull
   ReturnTOS
 L1:
   Push                 r4
   LoadContextVar       8
   PopLocal             r4
   Push                 r5
-  PushConstant         CP#8
-  IfEqStrictNumTOS
+  PushInt              1
+  IfEqStrictTOS
   Jump                 L13
   Push                 r5
-  PushConstant         CP#18
-  IfEqStrictNumTOS
+  PushInt              2
+  IfEqStrictTOS
   Jump                 L14
   Push                 r5
-  PushConstant         CP#23
-  IfEqStrictNumTOS
+  PushInt              3
+  IfEqStrictTOS
   Jump                 L15
   Push                 r5
-  PushConstant         CP#27
-  IfEqStrictNumTOS
+  PushInt              4
+  IfEqStrictTOS
   Jump                 L16
   Jump                 L17
 
@@ -1872,77 +1853,72 @@
   Push                 FP[-5]
   StoreContextVar      0
   Push                 r0
-  PushConstant         CP#0
+  PushInt              3
   StoreContextVar      1
-  Allocate             CP#26
+  Allocate             CP#21
   StoreLocal           r3
   Push                 r3
-  PushConstant         CP#7
+  PushNull
+  StoreFieldTOS        CP#22
+  Push                 r3
+  PushNull
+  StoreFieldTOS        CP#24
+  Push                 r3
+  PushConstant         CP#26
   StoreFieldTOS        CP#27
   Push                 r3
-  PushConstant         CP#7
+  PushConstant         CP#0
   StoreFieldTOS        CP#29
   Push                 r3
-  PushConstant         CP#31
-  StoreFieldTOS        CP#32
-  Push                 r3
-  PushConstant         CP#1
-  StoreFieldTOS        CP#34
-  Push                 r3
   Push                 r0
-  StoreFieldTOS        CP#2
+  StoreFieldTOS        CP#1
   PopLocal             r2
   Push                 r2
   ReturnTOS
-  PushConstant         CP#7
+  PushNull
   ReturnTOS
 }
 ConstantPool {
-  [0] = Int 3
-  [1] = ClosureFunction nested () → dart.async::Future<dart.core::int> /* originally async */ ;
-  [2] = InstanceField dart.core::_Closure::_context
-  [3] = Reserved
-  [4] = TypeArgumentsForInstanceAllocation dart.async::Completer [dart.core::int]
-  [5] = ArgDesc num-args 1, num-type-args 0, names []
-  [6] = StaticICData target 'dart.async::Completer::sync', arg-desc CP#5
+  [0] = ClosureFunction nested () → dart.async::Future<dart.core::int> /* originally async */ ;
+  [1] = InstanceField dart.core::_Closure::_context
+  [2] = Reserved
+  [3] = TypeArgumentsForInstanceAllocation dart.async::Completer [dart.core::int]
+  [4] = ArgDesc num-args 1, num-type-args 0, names []
+  [5] = StaticICData target 'dart.async::Completer::sync', arg-desc CP#4
+  [6] = ClosureFunction :async_op ([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding ;
   [7] = Null
-  [8] = Int 0
-  [9] = ClosureFunction :async_op ([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding ;
-  [10] = Int 4
-  [11] = Int 5
-  [12] = Int 1
-  [13] = ArgDesc num-args 4, num-type-args 0, names []
-  [14] = StaticICData target 'dart.async::_awaitHelper', arg-desc CP#13
-  [15] = ArgDesc num-args 2, num-type-args 0, names []
-  [16] = ICData target-name '+', arg-desc CP#15
-  [17] = Type dynamic
-  [18] = String 'fin'
-  [19] = StaticICData target 'dart.core::print', arg-desc CP#5
-  [20] = StaticICData target 'dart.core::print', arg-desc CP#5
-  [21] = StaticICData target 'dart.core::print', arg-desc CP#5
-  [22] = StaticICData target 'dart.async::_completeOnAsyncReturn', arg-desc CP#15
-  [23] = ArgDesc num-args 3, num-type-args 0, names []
-  [24] = ICData target-name 'completeError', arg-desc CP#23
-  [25] = EndClosureFunctionScope
-  [26] = Class dart.core::_Closure
-  [27] = InstanceField dart.core::_Closure::_instantiator_type_arguments
+  [8] = ArgDesc num-args 4, num-type-args 0, names []
+  [9] = StaticICData target 'dart.async::_awaitHelper', arg-desc CP#8
+  [10] = ArgDesc num-args 2, num-type-args 0, names []
+  [11] = ICData target-name '+', arg-desc CP#10
+  [12] = Type dynamic
+  [13] = String 'fin'
+  [14] = StaticICData target 'dart.core::print', arg-desc CP#4
+  [15] = StaticICData target 'dart.core::print', arg-desc CP#4
+  [16] = StaticICData target 'dart.core::print', arg-desc CP#4
+  [17] = StaticICData target 'dart.async::_completeOnAsyncReturn', arg-desc CP#10
+  [18] = ArgDesc num-args 3, num-type-args 0, names []
+  [19] = ICData target-name 'completeError', arg-desc CP#18
+  [20] = EndClosureFunctionScope
+  [21] = Class dart.core::_Closure
+  [22] = InstanceField dart.core::_Closure::_instantiator_type_arguments
+  [23] = Reserved
+  [24] = InstanceField dart.core::_Closure::_function_type_arguments
+  [25] = Reserved
+  [26] = EmptyTypeArguments
+  [27] = InstanceField dart.core::_Closure::_delayed_type_arguments
   [28] = Reserved
-  [29] = InstanceField dart.core::_Closure::_function_type_arguments
+  [29] = InstanceField dart.core::_Closure::_function
   [30] = Reserved
-  [31] = EmptyTypeArguments
-  [32] = InstanceField dart.core::_Closure::_delayed_type_arguments
-  [33] = Reserved
-  [34] = InstanceField dart.core::_Closure::_function
-  [35] = Reserved
-  [36] = StaticICData target 'dart.async::_asyncStackTraceHelper', arg-desc CP#5
-  [37] = StaticICData target 'dart.async::_asyncThenWrapperHelper', arg-desc CP#5
-  [38] = StaticICData target 'dart.async::_asyncErrorWrapperHelper', arg-desc CP#5
-  [39] = TypeArgumentsForInstanceAllocation dart.async::Future [dynamic]
-  [40] = StaticICData target 'dart.async::Future::microtask', arg-desc CP#15
-  [41] = ICData get target-name 'future', arg-desc CP#5
-  [42] = EndClosureFunctionScope
+  [31] = StaticICData target 'dart.async::_asyncStackTraceHelper', arg-desc CP#4
+  [32] = StaticICData target 'dart.async::_asyncThenWrapperHelper', arg-desc CP#4
+  [33] = StaticICData target 'dart.async::_asyncErrorWrapperHelper', arg-desc CP#4
+  [34] = TypeArgumentsForInstanceAllocation dart.async::Future [dynamic]
+  [35] = StaticICData target 'dart.async::Future::microtask', arg-desc CP#10
+  [36] = ICData get target-name 'future', arg-desc CP#4
+  [37] = EndClosureFunctionScope
 }
-Closure CP#9 {
+Closure CP#6 {
   EntryOptional        1, 3, 0
   LoadConstant         r1, CP#7
   LoadConstant         r2, CP#7
@@ -1950,13 +1926,13 @@
   Frame                8
   CheckStack
   Push                 r0
-  LoadFieldTOS         CP#2
+  LoadFieldTOS         CP#1
   PopLocal             r4
   Push                 r4
   LoadContextVar       4
   StoreLocal           r5
-  PushConstant         CP#8
-  IfNeStrictNumTOS
+  PushInt              0
+  IfNeStrictTOS
   Jump                 L1
   Push                 r4
   Push                 r4
@@ -1969,7 +1945,7 @@
   StoreContextParent
   PopLocal             r4
   Push                 r4
-  PushConstant         CP#10
+  PushInt              4
   StoreContextVar      0
   Push                 r4
   LoadContextParent
@@ -1979,11 +1955,11 @@
   Push                 r4
   LoadContextParent
   LoadContextParent
-  PushConstant         CP#11
+  PushInt              5
   StoreContextVar      1
   Push                 r4
   LoadContextParent
-  PushConstant         CP#12
+  PushInt              1
   StoreContextVar      4
   Push                 r4
   LoadContextParent
@@ -2002,10 +1978,10 @@
   Push                 r4
   LoadContextParent
   LoadContextVar       8
-  PushConstant         CP#14
-  IndirectStaticCall   4, CP#13
+  PushConstant         CP#9
+  IndirectStaticCall   4, CP#8
   PopLocal             r11
-  PushConstant         CP#7
+  PushNull
   ReturnTOS
 L7:
   IfEqNull             r2
@@ -2025,7 +2001,7 @@
   LoadContextVar       1
   Push                 r4
   LoadContextVar       0
-  InstanceCall         2, CP#16
+  InstanceCall         2, CP#11
   StoreContextVar      1
   Jump                 L3
   Jump                 L4
@@ -2033,30 +2009,30 @@
 Try #1 handler:
   SetFrame             12
   Push                 r0
-  LoadFieldTOS         CP#2
+  LoadFieldTOS         CP#1
   PopLocal             r4
   Push                 r4
   LoadContextVar       7
   PopLocal             r4
   MoveSpecial          r8, exception
   MoveSpecial          r9, stackTrace
-  PushConstant         CP#18
-  PushConstant         CP#19
-  IndirectStaticCall   1, CP#5
+  PushConstant         CP#13
+  PushConstant         CP#14
+  IndirectStaticCall   1, CP#4
   Drop1
   Push                 r8
   Push                 r9
   Throw                1
 L3:
   Push                 r0
-  LoadFieldTOS         CP#2
+  LoadFieldTOS         CP#1
   PopLocal             r4
   Push                 r4
   LoadContextVar       7
   PopLocal             r4
-  PushConstant         CP#18
-  PushConstant         CP#20
-  IndirectStaticCall   1, CP#5
+  PushConstant         CP#13
+  PushConstant         CP#15
+  IndirectStaticCall   1, CP#4
   Drop1
   Push                 r4
   LoadContextParent
@@ -2064,14 +2040,14 @@
   Jump                 L5
 L4:
   Push                 r0
-  LoadFieldTOS         CP#2
+  LoadFieldTOS         CP#1
   PopLocal             r4
   Push                 r4
   LoadContextVar       7
   PopLocal             r4
-  PushConstant         CP#18
-  PushConstant         CP#21
-  IndirectStaticCall   1, CP#5
+  PushConstant         CP#13
+  PushConstant         CP#16
+  IndirectStaticCall   1, CP#4
   Drop1
   Push                 r4
   LoadContextParent
@@ -2081,17 +2057,17 @@
   LoadContextVar       0
   Push                 r4
   LoadContextVar       1
-  PushConstant         CP#22
-  IndirectStaticCall   2, CP#15
+  PushConstant         CP#17
+  IndirectStaticCall   2, CP#10
   Drop1
-  PushConstant         CP#7
+  PushNull
   ReturnTOS
   Jump                 L6
 Try #0 end:
 Try #0 handler:
   SetFrame             12
   Push                 r0
-  LoadFieldTOS         CP#2
+  LoadFieldTOS         CP#1
   PopLocal             r4
   Push                 r4
   LoadContextVar       6
@@ -2106,11 +2082,11 @@
   LoadContextVar       0
   Push                 r8
   Push                 r9
-  InstanceCall         3, CP#24
+  InstanceCall         3, CP#19
   Drop1
   Jump                 L6
 L6:
-  PushConstant         CP#7
+  PushNull
   ReturnTOS
 L1:
   Push                 r4
@@ -2120,11 +2096,11 @@
 
 }
 
-Closure CP#1 {
+Closure CP#0 {
   EntryFixed           1, 4
   CheckStack
   Push                 FP[-5]
-  LoadFieldTOS         CP#2
+  LoadFieldTOS         CP#1
   PopLocal             r0
   AllocateContext      9
   StoreLocal           r1
@@ -2133,83 +2109,83 @@
   StoreContextParent
   PopLocal             r0
   Push                 r0
-  PushConstant         CP#4
-  PushConstant         CP#6
-  IndirectStaticCall   1, CP#5
+  PushConstant         CP#3
+  PushConstant         CP#5
+  IndirectStaticCall   1, CP#4
   StoreContextVar      0
   Push                 r0
-  PushConstant         CP#7
+  PushNull
   StoreContextVar      1
-  PushConstant         CP#7
+  PushNull
   PopLocal             r2
   Push                 r0
-  PushConstant         CP#7
+  PushNull
   StoreContextVar      2
   Push                 r0
-  PushConstant         CP#7
+  PushNull
   StoreContextVar      3
   Push                 r0
-  PushConstant         CP#8
+  PushInt              0
   StoreContextVar      4
   Push                 r0
-  PushConstant         CP#7
+  PushNull
   StoreContextVar      5
   Push                 r0
-  PushConstant         CP#7
+  PushNull
   StoreContextVar      6
   Push                 r0
-  PushConstant         CP#7
+  PushNull
   StoreContextVar      7
   Push                 r0
-  Allocate             CP#26
+  Allocate             CP#21
   StoreLocal           r3
   Push                 r3
-  PushConstant         CP#7
+  PushNull
+  StoreFieldTOS        CP#22
+  Push                 r3
+  PushNull
+  StoreFieldTOS        CP#24
+  Push                 r3
+  PushConstant         CP#26
   StoreFieldTOS        CP#27
   Push                 r3
-  PushConstant         CP#7
+  PushConstant         CP#6
   StoreFieldTOS        CP#29
   Push                 r3
-  PushConstant         CP#31
-  StoreFieldTOS        CP#32
-  Push                 r3
-  PushConstant         CP#9
-  StoreFieldTOS        CP#34
-  Push                 r3
   Push                 r0
-  StoreFieldTOS        CP#2
+  StoreFieldTOS        CP#1
   StoreContextVar      8
   Push                 r0
   LoadContextVar       8
-  PushConstant         CP#36
-  IndirectStaticCall   1, CP#5
+  PushConstant         CP#31
+  IndirectStaticCall   1, CP#4
   PopLocal             r2
   Push                 r0
   Push                 r0
   LoadContextVar       8
-  PushConstant         CP#37
-  IndirectStaticCall   1, CP#5
+  PushConstant         CP#32
+  IndirectStaticCall   1, CP#4
   StoreContextVar      2
   Push                 r0
   Push                 r0
   LoadContextVar       8
-  PushConstant         CP#38
-  IndirectStaticCall   1, CP#5
+  PushConstant         CP#33
+  IndirectStaticCall   1, CP#4
   StoreContextVar      3
-  PushConstant         CP#39
+  PushConstant         CP#34
   Push                 r0
   LoadContextVar       8
-  PushConstant         CP#40
-  IndirectStaticCall   2, CP#15
+  PushConstant         CP#35
+  IndirectStaticCall   2, CP#10
   Drop1
   Push                 r0
   LoadContextVar       0
-  InstanceCall         1, CP#41
+  InstanceCall         1, CP#36
   ReturnTOS
   Push                 r0
   LoadContextParent
   PopLocal             r0
-  PushConstant         CP#7
+  PushNull
   ReturnTOS
 
 }
@@ -2270,129 +2246,124 @@
   IndirectStaticCall   1, CP#1
   StoreContextVar      1
   Push                 r0
-  PushConstant         CP#3
+  PushNull
   StoreContextVar      2
-  PushConstant         CP#3
+  PushNull
   PopLocal             r2
   Push                 r0
-  PushConstant         CP#3
+  PushNull
   StoreContextVar      3
   Push                 r0
-  PushConstant         CP#3
+  PushNull
   StoreContextVar      4
   Push                 r0
-  PushConstant         CP#4
+  PushInt              0
   StoreContextVar      5
   Push                 r0
-  PushConstant         CP#3
+  PushNull
   StoreContextVar      6
   Push                 r0
-  PushConstant         CP#3
+  PushNull
   StoreContextVar      7
   Push                 r0
-  Allocate             CP#22
+  Allocate             CP#17
   StoreLocal           r3
   Push                 r3
-  PushConstant         CP#3
+  PushNull
+  StoreFieldTOS        CP#18
+  Push                 r3
+  PushNull
+  StoreFieldTOS        CP#20
+  Push                 r3
+  PushConstant         CP#22
   StoreFieldTOS        CP#23
   Push                 r3
   PushConstant         CP#3
   StoreFieldTOS        CP#25
   Push                 r3
-  PushConstant         CP#27
-  StoreFieldTOS        CP#28
-  Push                 r3
-  PushConstant         CP#5
-  StoreFieldTOS        CP#30
-  Push                 r3
   Push                 r0
-  StoreFieldTOS        CP#6
+  StoreFieldTOS        CP#5
   StoreContextVar      8
   Push                 r0
   LoadContextVar       8
-  PushConstant         CP#32
+  PushConstant         CP#27
   IndirectStaticCall   1, CP#1
   PopLocal             r2
   Push                 r0
   Push                 r0
   LoadContextVar       8
-  PushConstant         CP#33
+  PushConstant         CP#28
   IndirectStaticCall   1, CP#1
   StoreContextVar      3
   Push                 r0
   Push                 r0
   LoadContextVar       8
-  PushConstant         CP#34
+  PushConstant         CP#29
   IndirectStaticCall   1, CP#1
   StoreContextVar      4
-  PushConstant         CP#35
+  PushConstant         CP#30
   Push                 r0
   LoadContextVar       8
-  PushConstant         CP#36
-  IndirectStaticCall   2, CP#12
+  PushConstant         CP#31
+  IndirectStaticCall   2, CP#9
   Drop1
   Push                 r0
   LoadContextVar       1
-  InstanceCall         1, CP#37
+  InstanceCall         1, CP#32
   ReturnTOS
-  PushConstant         CP#3
+  PushNull
   ReturnTOS
 }
 ConstantPool {
   [0] = TypeArgumentsForInstanceAllocation dart.async::Completer [dart.core::int]
   [1] = ArgDesc num-args 1, num-type-args 0, names []
   [2] = StaticICData target 'dart.async::Completer::sync', arg-desc CP#1
-  [3] = Null
-  [4] = Int 0
-  [5] = ClosureFunction :async_op ([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding ;
-  [6] = InstanceField dart.core::_Closure::_context
-  [7] = Reserved
-  [8] = Int 1
-  [9] = ArgDesc num-args 4, num-type-args 0, names []
-  [10] = StaticICData target 'dart.async::_awaitHelper', arg-desc CP#9
-  [11] = Int 42
-  [12] = ArgDesc num-args 2, num-type-args 0, names []
-  [13] = ICData target-name '==', arg-desc CP#12
-  [14] = Bool true
-  [15] = ArgDesc num-args 3, num-type-args 0, names []
-  [16] = StaticICData target 'dart.core::_AssertionError::_throwNew', arg-desc CP#15
-  [17] = Int 7
-  [18] = StaticICData target 'dart.async::_completeOnAsyncReturn', arg-desc CP#12
-  [19] = Type dynamic
-  [20] = ICData target-name 'completeError', arg-desc CP#15
-  [21] = EndClosureFunctionScope
-  [22] = Class dart.core::_Closure
-  [23] = InstanceField dart.core::_Closure::_instantiator_type_arguments
+  [3] = ClosureFunction :async_op ([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding ;
+  [4] = Null
+  [5] = InstanceField dart.core::_Closure::_context
+  [6] = Reserved
+  [7] = ArgDesc num-args 4, num-type-args 0, names []
+  [8] = StaticICData target 'dart.async::_awaitHelper', arg-desc CP#7
+  [9] = ArgDesc num-args 2, num-type-args 0, names []
+  [10] = ICData target-name '==', arg-desc CP#9
+  [11] = ArgDesc num-args 3, num-type-args 0, names []
+  [12] = StaticICData target 'dart.core::_AssertionError::_throwNew', arg-desc CP#11
+  [13] = StaticICData target 'dart.async::_completeOnAsyncReturn', arg-desc CP#9
+  [14] = Type dynamic
+  [15] = ICData target-name 'completeError', arg-desc CP#11
+  [16] = EndClosureFunctionScope
+  [17] = Class dart.core::_Closure
+  [18] = InstanceField dart.core::_Closure::_instantiator_type_arguments
+  [19] = Reserved
+  [20] = InstanceField dart.core::_Closure::_function_type_arguments
+  [21] = Reserved
+  [22] = EmptyTypeArguments
+  [23] = InstanceField dart.core::_Closure::_delayed_type_arguments
   [24] = Reserved
-  [25] = InstanceField dart.core::_Closure::_function_type_arguments
+  [25] = InstanceField dart.core::_Closure::_function
   [26] = Reserved
-  [27] = EmptyTypeArguments
-  [28] = InstanceField dart.core::_Closure::_delayed_type_arguments
-  [29] = Reserved
-  [30] = InstanceField dart.core::_Closure::_function
-  [31] = Reserved
-  [32] = StaticICData target 'dart.async::_asyncStackTraceHelper', arg-desc CP#1
-  [33] = StaticICData target 'dart.async::_asyncThenWrapperHelper', arg-desc CP#1
-  [34] = StaticICData target 'dart.async::_asyncErrorWrapperHelper', arg-desc CP#1
-  [35] = TypeArgumentsForInstanceAllocation dart.async::Future [dynamic]
-  [36] = StaticICData target 'dart.async::Future::microtask', arg-desc CP#12
-  [37] = ICData get target-name 'future', arg-desc CP#1
+  [27] = StaticICData target 'dart.async::_asyncStackTraceHelper', arg-desc CP#1
+  [28] = StaticICData target 'dart.async::_asyncThenWrapperHelper', arg-desc CP#1
+  [29] = StaticICData target 'dart.async::_asyncErrorWrapperHelper', arg-desc CP#1
+  [30] = TypeArgumentsForInstanceAllocation dart.async::Future [dynamic]
+  [31] = StaticICData target 'dart.async::Future::microtask', arg-desc CP#9
+  [32] = ICData get target-name 'future', arg-desc CP#1
 }
-Closure CP#5 {
+Closure CP#3 {
   EntryOptional        1, 3, 0
-  LoadConstant         r1, CP#3
-  LoadConstant         r2, CP#3
-  LoadConstant         r3, CP#3
+  LoadConstant         r1, CP#4
+  LoadConstant         r2, CP#4
+  LoadConstant         r3, CP#4
   Frame                6
   CheckStack
   Push                 r0
-  LoadFieldTOS         CP#6
+  LoadFieldTOS         CP#5
   PopLocal             r4
   Push                 r4
   LoadContextVar       5
   StoreLocal           r5
-  PushConstant         CP#4
-  IfNeStrictNumTOS
+  PushInt              0
+  IfNeStrictTOS
   Jump                 L1
   Push                 r4
   Push                 r4
@@ -2400,7 +2371,7 @@
 Try #0 start:
   JumpIfNoAsserts      L2
   Push                 r4
-  PushConstant         CP#8
+  PushInt              1
   StoreContextVar      5
   Push                 r4
   Push                 r4
@@ -2413,10 +2384,10 @@
   LoadContextVar       4
   Push                 r4
   LoadContextVar       8
-  PushConstant         CP#10
-  IndirectStaticCall   4, CP#9
+  PushConstant         CP#8
+  IndirectStaticCall   4, CP#7
   PopLocal             r8
-  PushConstant         CP#3
+  PushNull
   ReturnTOS
 L6:
   IfEqNull             r2
@@ -2427,21 +2398,21 @@
 L3:
   JumpIfNoAsserts      L2
   Push                 r1
-  PushConstant         CP#11
-  InstanceCall         2, CP#13
+  PushInt              42
+  InstanceCall         2, CP#10
   AssertBoolean        0
-  PushConstant         CP#14
+  PushTrue
   IfEqStrictTOS
   Jump                 L2
-  PushConstant         CP#4
-  PushConstant         CP#4
-  PushConstant         CP#3
-  PushConstant         CP#16
-  IndirectStaticCall   3, CP#15
+  PushInt              0
+  PushInt              0
+  PushNull
+  PushConstant         CP#12
+  IndirectStaticCall   3, CP#11
   Drop1
 L2:
   Push                 r4
-  PushConstant         CP#17
+  PushInt              7
   StoreContextVar      2
   Jump                 L4
 L4:
@@ -2449,17 +2420,17 @@
   LoadContextVar       1
   Push                 r4
   LoadContextVar       2
-  PushConstant         CP#18
-  IndirectStaticCall   2, CP#12
+  PushConstant         CP#13
+  IndirectStaticCall   2, CP#9
   Drop1
-  PushConstant         CP#3
+  PushNull
   ReturnTOS
   Jump                 L5
 Try #0 end:
 Try #0 handler:
   SetFrame             10
   Push                 r0
-  LoadFieldTOS         CP#6
+  LoadFieldTOS         CP#5
   PopLocal             r4
   Push                 r4
   LoadContextVar       7
@@ -2474,11 +2445,11 @@
   LoadContextVar       1
   Push                 r8
   Push                 r9
-  InstanceCall         3, CP#20
+  InstanceCall         3, CP#15
   Drop1
   Jump                 L5
 L5:
-  PushConstant         CP#3
+  PushNull
   ReturnTOS
 L1:
   Push                 r4
@@ -2523,10 +2494,9 @@
 Bytecode {
   Entry                0
   CheckStack
-  PushConstant         CP#0
+  PushNull
   ReturnTOS
 }
 ConstantPool {
-  [0] = Null
 }
 ]static method main() → dynamic {}
diff --git a/pkg/vm/testcases/bytecode/bootstrapping.dart.expect b/pkg/vm/testcases/bytecode/bootstrapping.dart.expect
index a20221a..c14b6ae 100644
--- a/pkg/vm/testcases/bytecode/bootstrapping.dart.expect
+++ b/pkg/vm/testcases/bytecode/bootstrapping.dart.expect
@@ -14,13 +14,12 @@
   PushConstant         CP#1
   IndirectStaticCall   1, CP#0
   Drop1
-  PushConstant         CP#2
+  PushNull
   ReturnTOS
 }
 ConstantPool {
   [0] = ArgDesc num-args 1, num-type-args 0, names []
   [1] = StaticICData target 'dart.core::Object::', arg-desc CP#0
-  [2] = Null
 }
 ]  synthetic constructor •() → void
     : super core::Object::•()
@@ -36,13 +35,12 @@
   PushConstant         CP#1
   IndirectStaticCall   1, CP#0
   Drop1
-  PushConstant         CP#2
+  PushNull
   ReturnTOS
 }
 ConstantPool {
   [0] = ArgDesc num-args 1, num-type-args 0, names []
   [1] = StaticICData target 'dart.core::Object::', arg-desc CP#0
-  [2] = Null
 }
 ]  constructor _() → void
     : super core::Object::•()
@@ -100,7 +98,7 @@
   PushConstant         CP#4
   IndirectStaticCall   2, CP#3
   StoreStaticTOS       CP#5
-  PushConstant         CP#6
+  PushNull
   ReturnTOS
 }
 ConstantPool {
@@ -110,7 +108,6 @@
   [3] = ArgDesc num-args 2, num-type-args 0, names []
   [4] = StaticICData target '#lib::_NamespaceImpl::_create', arg-desc CP#3
   [5] = StaticField #lib::_NamespaceImpl::_cachedNamespace
-  [6] = Null
 }
 ]  static method _setupNamespace(dynamic namespace) → void {
     self::_NamespaceImpl::_cachedNamespace = self::_NamespaceImpl::_create(new self::_NamespaceImpl::_(), namespace);
@@ -121,42 +118,40 @@
   CheckStack
   PushConstant         CP#0
   PushStatic           CP#0
-  PushConstant         CP#1
-  InstanceCall         2, CP#3
+  PushNull
+  InstanceCall         2, CP#2
   AssertBoolean        0
-  PushConstant         CP#4
+  PushTrue
   IfNeStrictTOS
   Jump                 L1
-  Allocate             CP#5
+  Allocate             CP#3
   StoreLocal           r1
   Push                 r1
-  PushConstant         CP#7
-  IndirectStaticCall   1, CP#6
+  PushConstant         CP#5
+  IndirectStaticCall   1, CP#4
   Drop1
-  PushConstant         CP#9
-  IndirectStaticCall   0, CP#8
-  PushConstant         CP#10
-  IndirectStaticCall   2, CP#2
+  PushConstant         CP#7
+  IndirectStaticCall   0, CP#6
+  PushConstant         CP#8
+  IndirectStaticCall   2, CP#1
   StoreStaticTOS       CP#0
 L1:
   PushConstant         CP#0
   PushStatic           CP#0
   ReturnTOS
-  PushConstant         CP#1
+  PushNull
   ReturnTOS
 }
 ConstantPool {
   [0] = StaticField #lib::_NamespaceImpl::_cachedNamespace
-  [1] = Null
-  [2] = ArgDesc num-args 2, num-type-args 0, names []
-  [3] = ICData target-name '==', arg-desc CP#2
-  [4] = Bool true
-  [5] = Class #lib::_NamespaceImpl
-  [6] = ArgDesc num-args 1, num-type-args 0, names []
-  [7] = StaticICData target '#lib::_NamespaceImpl::_', arg-desc CP#6
-  [8] = ArgDesc num-args 0, num-type-args 0, names []
-  [9] = StaticICData target '#lib::_NamespaceImpl::_getDefault', arg-desc CP#8
-  [10] = StaticICData target '#lib::_NamespaceImpl::_create', arg-desc CP#2
+  [1] = ArgDesc num-args 2, num-type-args 0, names []
+  [2] = ICData target-name '==', arg-desc CP#1
+  [3] = Class #lib::_NamespaceImpl
+  [4] = ArgDesc num-args 1, num-type-args 0, names []
+  [5] = StaticICData target '#lib::_NamespaceImpl::_', arg-desc CP#4
+  [6] = ArgDesc num-args 0, num-type-args 0, names []
+  [7] = StaticICData target '#lib::_NamespaceImpl::_getDefault', arg-desc CP#6
+  [8] = StaticICData target '#lib::_NamespaceImpl::_create', arg-desc CP#1
 }
 ]  static get _namespace() → self::_NamespaceImpl {
     if(self::_NamespaceImpl::_cachedNamespace.{core::Object::==}(null)) {
@@ -173,7 +168,7 @@
   PushConstant         CP#3
   IndirectStaticCall   1, CP#2
   ReturnTOS
-  PushConstant         CP#4
+  PushNull
   ReturnTOS
 }
 ConstantPool {
@@ -181,7 +176,6 @@
   [1] = StaticICData get target '#lib::_NamespaceImpl::_namespace', arg-desc CP#0
   [2] = ArgDesc num-args 1, num-type-args 0, names []
   [3] = StaticICData target '#lib::_NamespaceImpl::_getPointer', arg-desc CP#2
-  [4] = Null
 }
 ]  static get _namespacePointer() → core::int
     return self::_NamespaceImpl::_getPointer(self::_NamespaceImpl::_namespace);
@@ -195,13 +189,12 @@
   PushConstant         CP#1
   IndirectStaticCall   1, CP#0
   Drop1
-  PushConstant         CP#2
+  PushNull
   ReturnTOS
 }
 ConstantPool {
   [0] = ArgDesc num-args 1, num-type-args 0, names []
   [1] = StaticICData target 'dart.core::Object::', arg-desc CP#0
-  [2] = Null
 }
 ]  synthetic constructor •() → void
     : super core::Object::•()
@@ -214,13 +207,12 @@
   PushConstant         CP#1
   IndirectStaticCall   1, CP#0
   Drop1
-  PushConstant         CP#2
+  PushNull
   ReturnTOS
 }
 ConstantPool {
   [0] = ArgDesc num-args 1, num-type-args 0, names []
   [1] = StaticICData target '#lib::_NamespaceImpl::_setupNamespace', arg-desc CP#0
-  [2] = Null
 }
 ]  static method _setupNamespace(dynamic namespace) → void {
     self::_NamespaceImpl::_setupNamespace(namespace);
@@ -232,13 +224,12 @@
   PushConstant         CP#1
   IndirectStaticCall   0, CP#0
   ReturnTOS
-  PushConstant         CP#2
+  PushNull
   ReturnTOS
 }
 ConstantPool {
   [0] = ArgDesc num-args 0, num-type-args 0, names []
   [1] = StaticICData get target '#lib::_NamespaceImpl::_namespace', arg-desc CP#0
-  [2] = Null
 }
 ]  static get _namespace() → self::_Namespace
     return self::_NamespaceImpl::_namespace;
@@ -249,13 +240,12 @@
   PushConstant         CP#1
   IndirectStaticCall   0, CP#0
   ReturnTOS
-  PushConstant         CP#2
+  PushNull
   ReturnTOS
 }
 ConstantPool {
   [0] = ArgDesc num-args 0, num-type-args 0, names []
   [1] = StaticICData get target '#lib::_NamespaceImpl::_namespacePointer', arg-desc CP#0
-  [2] = Null
 }
 ]  static get _namespacePointer() → core::int
     return self::_NamespaceImpl::_namespacePointer;
@@ -280,13 +270,12 @@
   PushConstant         CP#1
   IndirectStaticCall   1, CP#0
   Drop1
-  PushConstant         CP#2
+  PushNull
   ReturnTOS
 }
 ConstantPool {
   [0] = ArgDesc num-args 1, num-type-args 0, names []
   [1] = StaticICData target 'dart.core::Object::', arg-desc CP#0
-  [2] = Null
 }
 ]  synthetic constructor •() → void
     : super core::Object::•()
@@ -297,15 +286,14 @@
   CheckStack
   Push                 FP[-5]
   StoreStaticTOS       CP#0
-  PushConstant         CP#1
-  StoreStaticTOS       CP#2
-  PushConstant         CP#1
+  PushNull
+  StoreStaticTOS       CP#1
+  PushNull
   ReturnTOS
 }
 ConstantPool {
   [0] = StaticField #lib::VMLibraryHooks::_computeScriptUri
-  [1] = Null
-  [2] = StaticField #lib::VMLibraryHooks::_cachedScript
+  [1] = StaticField #lib::VMLibraryHooks::_cachedScript
 }
 ]  static set platformScript(dynamic f) → void {
     self::VMLibraryHooks::_computeScriptUri = f;
@@ -317,51 +305,48 @@
   CheckStack
   PushConstant         CP#0
   PushStatic           CP#0
-  PushConstant         CP#1
-  InstanceCall         2, CP#3
+  PushNull
+  InstanceCall         2, CP#2
   AssertBoolean        0
-  PushConstant         CP#4
+  PushTrue
   IfNeStrictTOS
   Jump                 L1
-  PushConstant         CP#5
-  PushStatic           CP#5
-  PushConstant         CP#1
-  InstanceCall         2, CP#6
+  PushConstant         CP#3
+  PushStatic           CP#3
+  PushNull
+  InstanceCall         2, CP#4
   AssertBoolean        0
   BooleanNegateTOS
   PopLocal             r0
   Jump                 L2
 L1:
-  PushConstant         CP#7
+  PushFalse
   PopLocal             r0
 L2:
   Push                 r0
   AssertBoolean        0
-  PushConstant         CP#4
+  PushTrue
   IfNeStrictTOS
   Jump                 L3
-  PushConstant         CP#5
-  PushStatic           CP#5
-  InstanceCall         1, CP#9
+  PushConstant         CP#3
+  PushStatic           CP#3
+  InstanceCall         1, CP#6
   StoreStaticTOS       CP#0
 L3:
   PushConstant         CP#0
   PushStatic           CP#0
   ReturnTOS
-  PushConstant         CP#1
+  PushNull
   ReturnTOS
 }
 ConstantPool {
   [0] = StaticField #lib::VMLibraryHooks::_cachedScript
-  [1] = Null
-  [2] = ArgDesc num-args 2, num-type-args 0, names []
-  [3] = ICData target-name '==', arg-desc CP#2
-  [4] = Bool true
-  [5] = StaticField #lib::VMLibraryHooks::_computeScriptUri
-  [6] = ICData target-name '==', arg-desc CP#2
-  [7] = Bool false
-  [8] = ArgDesc num-args 1, num-type-args 0, names []
-  [9] = ICData target-name 'call', arg-desc CP#8
+  [1] = ArgDesc num-args 2, num-type-args 0, names []
+  [2] = ICData target-name '==', arg-desc CP#1
+  [3] = StaticField #lib::VMLibraryHooks::_computeScriptUri
+  [4] = ICData target-name '==', arg-desc CP#1
+  [5] = ArgDesc num-args 1, num-type-args 0, names []
+  [6] = ICData dynamic target-name 'call', arg-desc CP#5
 }
 ]  static get platformScript() → dynamic {
     if(self::VMLibraryHooks::_cachedScript.{core::Object::==}(null) && !self::VMLibraryHooks::_computeScriptUri.{core::Object::==}(null)) {
@@ -396,14 +381,13 @@
   PushConstant         CP#2
   IndirectStaticCall   1, CP#0
   Drop1
-  PushConstant         CP#3
+  PushNull
   ReturnTOS
 }
 ConstantPool {
   [0] = ArgDesc num-args 1, num-type-args 0, names []
   [1] = ICData target-name 'toString', arg-desc CP#0
   [2] = StaticICData target '#lib::_printString', arg-desc CP#0
-  [3] = Null
 }
 ]static method _print(dynamic arg) → void {
   self::_printString(arg.{core::Object::toString}());
@@ -414,12 +398,11 @@
   CheckStack
   PushConstant         CP#0
   ReturnTOS
-  PushConstant         CP#1
+  PushNull
   ReturnTOS
 }
 ConstantPool {
   [0] = TearOff #lib::_print
-  [1] = Null
 }
 ]static method _getPrintClosure() → dynamic
   return self::_print;
@@ -429,12 +412,11 @@
   CheckStack
   Push                 FP[-5]
   StoreStaticTOS       CP#0
-  PushConstant         CP#1
+  PushNull
   ReturnTOS
 }
 ConstantPool {
   [0] = StaticField #lib::_ScheduleImmediate::_closure
-  [1] = Null
 }
 ]static method _setScheduleImmediateClosure((() → void) → void closure) → void {
   self::_ScheduleImmediate::_closure = closure;
@@ -449,14 +431,13 @@
   StoreStaticTOS       CP#1
   Push                 FP[-5]
   StoreStaticTOS       CP#2
-  PushConstant         CP#3
+  PushNull
   ReturnTOS
 }
 ConstantPool {
   [0] = StaticField #lib::_stdinFD
   [1] = StaticField #lib::_stdoutFD
   [2] = StaticField #lib::_stderrFD
-  [3] = Null
 }
 ]static method _setStdioFDs(core::int stdin, core::int stdout, core::int stderr) → void {
   self::_stdinFD = stdin;
@@ -472,59 +453,59 @@
   PushConstant         CP#1
   InstanceCall         2, CP#3
   AssertBoolean        0
-  PushConstant         CP#4
+  PushTrue
   IfEqStrictTOS
   Jump                 L1
   PushConstant         CP#0
   PushStatic           CP#0
-  PushConstant         CP#5
-  InstanceCall         2, CP#6
+  PushConstant         CP#4
+  InstanceCall         2, CP#5
   AssertBoolean        0
   PopLocal             r1
   Jump                 L2
 L1:
-  PushConstant         CP#4
+  PushTrue
   PopLocal             r1
 L2:
   Push                 r1
   AssertBoolean        0
-  PushConstant         CP#4
+  PushTrue
   IfEqStrictTOS
   Jump                 L3
   PushConstant         CP#0
   PushStatic           CP#0
-  PushConstant         CP#7
-  InstanceCall         2, CP#8
+  PushConstant         CP#6
+  InstanceCall         2, CP#7
   AssertBoolean        0
   PopLocal             r0
   Jump                 L4
 L3:
-  PushConstant         CP#4
+  PushTrue
   PopLocal             r0
 L4:
   Push                 r0
   AssertBoolean        0
-  PushConstant         CP#4
+  PushTrue
   IfNeStrictTOS
   Jump                 L5
   PushConstant         CP#0
   PushStatic           CP#0
-  PushConstant         CP#10
-  IndirectStaticCall   1, CP#9
+  PushConstant         CP#9
+  IndirectStaticCall   1, CP#8
   ReturnTOS
   Jump                 L6
 L5:
-  PushConstant         CP#12
-  IndirectStaticCall   0, CP#11
-  PushConstant         CP#13
+  PushConstant         CP#11
+  IndirectStaticCall   0, CP#10
+  PushNull
   PushConstant         CP#0
   PushStatic           CP#0
-  PushConstant         CP#14
+  PushConstant         CP#12
   IndirectStaticCall   2, CP#2
-  InstanceCall         2, CP#15
+  InstanceCall         2, CP#13
   ReturnTOS
 L6:
-  PushConstant         CP#13
+  PushNull
   ReturnTOS
 }
 ConstantPool {
@@ -532,18 +513,16 @@
   [1] = String 'http:'
   [2] = ArgDesc num-args 2, num-type-args 0, names []
   [3] = ICData target-name 'startsWith', arg-desc CP#2
-  [4] = Bool true
-  [5] = String 'https:'
-  [6] = ICData target-name 'startsWith', arg-desc CP#2
-  [7] = String 'file:'
-  [8] = ICData target-name 'startsWith', arg-desc CP#2
-  [9] = ArgDesc num-args 1, num-type-args 0, names []
-  [10] = StaticICData target 'dart.core::Uri::parse', arg-desc CP#9
-  [11] = ArgDesc num-args 0, num-type-args 0, names []
-  [12] = StaticICData get target 'dart.core::Uri::base', arg-desc CP#11
-  [13] = Null
-  [14] = StaticICData target 'dart.core::_Uri::file', arg-desc CP#2
-  [15] = ICData target-name 'resolveUri', arg-desc CP#2
+  [4] = String 'https:'
+  [5] = ICData target-name 'startsWith', arg-desc CP#2
+  [6] = String 'file:'
+  [7] = ICData target-name 'startsWith', arg-desc CP#2
+  [8] = ArgDesc num-args 1, num-type-args 0, names []
+  [9] = StaticICData target 'dart.core::Uri::parse', arg-desc CP#8
+  [10] = ArgDesc num-args 0, num-type-args 0, names []
+  [11] = StaticICData get target 'dart.core::Uri::base', arg-desc CP#10
+  [12] = StaticICData target 'dart.core::_Uri::file', arg-desc CP#2
+  [13] = ICData target-name 'resolveUri', arg-desc CP#2
 }
 ]static method _scriptUri() → core::Uri {
   if(self::_rawScript.{core::String::startsWith}("http:") || self::_rawScript.{core::String::startsWith}("https:") || self::_rawScript.{core::String::startsWith}("file:")) {
@@ -561,14 +540,13 @@
   PushConstant         CP#2
   IndirectStaticCall   1, CP#1
   Drop1
-  PushConstant         CP#3
+  PushNull
   ReturnTOS
 }
 ConstantPool {
   [0] = TearOff #lib::_scriptUri
   [1] = ArgDesc num-args 1, num-type-args 0, names []
   [2] = StaticICData set target '#lib::VMLibraryHooks::platformScript', arg-desc CP#1
-  [3] = Null
 }
 ]static method _setupHooks() → dynamic {
   self::VMLibraryHooks::platformScript = self::_scriptUri;
@@ -577,10 +555,9 @@
 Bytecode {
   Entry                0
   CheckStack
-  PushConstant         CP#0
+  PushNull
   ReturnTOS
 }
 ConstantPool {
-  [0] = Null
 }
 ]static method main() → dynamic {}
diff --git a/pkg/vm/testcases/bytecode/closures.dart.expect b/pkg/vm/testcases/bytecode/closures.dart.expect
index eb11001..10f84a5 100644
--- a/pkg/vm/testcases/bytecode/closures.dart.expect
+++ b/pkg/vm/testcases/bytecode/closures.dart.expect
@@ -12,13 +12,12 @@
   PushConstant         CP#1
   IndirectStaticCall   1, CP#0
   Drop1
-  PushConstant         CP#2
+  PushNull
   ReturnTOS
 }
 ConstantPool {
   [0] = ArgDesc num-args 1, num-type-args 0, names []
   [1] = StaticICData target 'dart.core::Object::', arg-desc CP#0
-  [2] = Null
 }
 ]  synthetic constructor •() → void
     : super core::Object::•()
@@ -33,13 +32,12 @@
   PushConstant         CP#1
   IndirectStaticCall   1, CP#0
   Drop1
-  PushConstant         CP#2
+  PushNull
   ReturnTOS
 }
 ConstantPool {
   [0] = ArgDesc num-args 1, num-type-args 0, names []
   [1] = StaticICData target 'dart.core::Object::', arg-desc CP#0
-  [2] = Null
 }
 ]  synthetic constructor •() → void
     : super core::Object::•()
@@ -54,13 +52,12 @@
   PushConstant         CP#1
   IndirectStaticCall   1, CP#0
   Drop1
-  PushConstant         CP#2
+  PushNull
   ReturnTOS
 }
 ConstantPool {
   [0] = ArgDesc num-args 1, num-type-args 0, names []
   [1] = StaticICData target 'dart.core::Object::', arg-desc CP#0
-  [2] = Null
 }
 ]  synthetic constructor •() → void
     : super core::Object::•()
@@ -75,13 +72,12 @@
   PushConstant         CP#1
   IndirectStaticCall   1, CP#0
   Drop1
-  PushConstant         CP#2
+  PushNull
   ReturnTOS
 }
 ConstantPool {
   [0] = ArgDesc num-args 1, num-type-args 0, names []
   [1] = StaticICData target 'dart.core::Object::', arg-desc CP#0
-  [2] = Null
 }
 ]  synthetic constructor •() → void
     : super core::Object::•()
@@ -96,13 +92,12 @@
   PushConstant         CP#1
   IndirectStaticCall   1, CP#0
   Drop1
-  PushConstant         CP#2
+  PushNull
   ReturnTOS
 }
 ConstantPool {
   [0] = ArgDesc num-args 1, num-type-args 0, names []
   [1] = StaticICData target 'dart.core::Object::', arg-desc CP#0
-  [2] = Null
 }
 ]  synthetic constructor •() → void
     : super core::Object::•()
@@ -117,13 +112,12 @@
   PushConstant         CP#1
   IndirectStaticCall   1, CP#0
   Drop1
-  PushConstant         CP#2
+  PushNull
   ReturnTOS
 }
 ConstantPool {
   [0] = ArgDesc num-args 1, num-type-args 0, names []
   [1] = StaticICData target 'dart.core::Object::', arg-desc CP#0
-  [2] = Null
 }
 ]  synthetic constructor •() → void
     : super core::Object::•()
@@ -138,13 +132,12 @@
   PushConstant         CP#1
   IndirectStaticCall   1, CP#0
   Drop1
-  PushConstant         CP#2
+  PushNull
   ReturnTOS
 }
 ConstantPool {
   [0] = ArgDesc num-args 1, num-type-args 0, names []
   [1] = StaticICData target 'dart.core::Object::', arg-desc CP#0
-  [2] = Null
 }
 ]  synthetic constructor •() → void
     : super core::Object::•()
@@ -159,13 +152,12 @@
   PushConstant         CP#1
   IndirectStaticCall   1, CP#0
   Drop1
-  PushConstant         CP#2
+  PushNull
   ReturnTOS
 }
 ConstantPool {
   [0] = ArgDesc num-args 1, num-type-args 0, names []
   [1] = StaticICData target 'dart.core::Object::', arg-desc CP#0
-  [2] = Null
 }
 ]  synthetic constructor •() → void
     : super core::Object::•()
@@ -180,13 +172,12 @@
   PushConstant         CP#1
   IndirectStaticCall   1, CP#0
   Drop1
-  PushConstant         CP#2
+  PushNull
   ReturnTOS
 }
 ConstantPool {
   [0] = ArgDesc num-args 1, num-type-args 0, names []
   [1] = StaticICData target 'dart.core::Object::', arg-desc CP#0
-  [2] = Null
 }
 ]  synthetic constructor •() → void
     : super core::Object::•()
@@ -201,12 +192,12 @@
   Push                 r1
   Push                 FP[-5]
   StoreContextVar      0
-  Allocate             CP#41
+  Allocate             CP#31
   StoreLocal           r4
   Push                 r4
   Push                 FP[-5]
-  LoadTypeArgumentsField CP#20
-  StoreFieldTOS        CP#42
+  LoadTypeArgumentsField CP#15
+  StoreFieldTOS        CP#32
   Push                 r4
   Push                 r0
   StoreFieldTOS        CP#6
@@ -215,20 +206,20 @@
   StoreFieldTOS        CP#3
   Push                 r4
   PushConstant         CP#0
-  StoreFieldTOS        CP#44
+  StoreFieldTOS        CP#34
   Push                 r4
   Push                 r1
   StoreFieldTOS        CP#1
   PopLocal             r3
-  PushConstant         CP#54
+  PushConstant         CP#44
   Push                 r3
-  InstanceCall         2, CP#55
+  InstanceCall         2, CP#45
   Drop1
-  PushConstant         CP#56
+  PushConstant         CP#46
   Push                 r3
-  InstanceCall         2, CP#57
+  InstanceCall         2, CP#47
   Drop1
-  PushConstant         CP#21
+  PushNull
   ReturnTOS
 }
 ConstantPool {
@@ -240,58 +231,48 @@
   [5] = EmptyTypeArguments
   [6] = InstanceField dart.core::_Closure::_function_type_arguments
   [7] = Reserved
-  [8] = Int 2
-  [9] = Int 4
-  [10] = ArgDesc num-args 4, num-type-args 0, names []
-  [11] = StaticICData target 'dart._internal::_prependTypeArguments', arg-desc CP#10
-  [12] = ClosureFunction nested2 <T7 extends dart.core::Object = dynamic, T8 extends dart.core::Object = dynamic>() → void;
-  [13] = Int 6
-  [14] = StaticICData target 'dart._internal::_prependTypeArguments', arg-desc CP#10
-  [15] = ClosureFunction <anonymous closure> () → dart.core::Null;
-  [16] = TypeArgs [dart.core::Type]
-  [17] = Int 8
-  [18] = Int 0
-  [19] = Type #lib::A::T1
-  [20] = TypeArgumentsField #lib::A
-  [21] = Null
-  [22] = Int 1
-  [23] = Type #lib::A::T2
-  [24] = Type #lib::A::foo::T3
-  [25] = Int 3
-  [26] = Type #lib::A::foo::T4
-  [27] = Type T5
-  [28] = Int 5
-  [29] = Type T6
-  [30] = Type T7
-  [31] = Int 7
-  [32] = Type T8
-  [33] = ArgDesc num-args 2, num-type-args 0, names []
-  [34] = StaticICData target 'dart.core::List::_fromLiteral', arg-desc CP#33
-  [35] = ArgDesc num-args 1, num-type-args 0, names []
-  [36] = StaticICData target 'dart.core::print', arg-desc CP#35
-  [37] = TypeArgs [#lib::A::T1, #lib::A::T2, #lib::A::foo::T3, #lib::A::foo::T4, T5, T6, T7, T8]
-  [38] = ArgDesc num-args 0, num-type-args 8, names []
-  [39] = StaticICData target '#lib::callWithArgs', arg-desc CP#38
-  [40] = EndClosureFunctionScope
-  [41] = Class dart.core::_Closure
-  [42] = InstanceField dart.core::_Closure::_instantiator_type_arguments
-  [43] = Reserved
-  [44] = InstanceField dart.core::_Closure::_function
-  [45] = Reserved
-  [46] = ICData target-name 'call', arg-desc CP#35
-  [47] = EndClosureFunctionScope
-  [48] = TypeArgs [#lib::C7, #lib::C8]
-  [49] = ArgDesc num-args 1, num-type-args 2, names []
-  [50] = ICData target-name 'call', arg-desc CP#49
-  [51] = TypeArgs [dart.core::List<#lib::C7>, dart.core::List<#lib::C8>]
-  [52] = ICData target-name 'call', arg-desc CP#49
-  [53] = EndClosureFunctionScope
-  [54] = TypeArgs [#lib::C5, #lib::C6]
-  [55] = ICData target-name 'call', arg-desc CP#49
-  [56] = TypeArgs [dart.core::List<#lib::C5>, dart.core::List<#lib::C6>]
-  [57] = ICData target-name 'call', arg-desc CP#49
+  [8] = ArgDesc num-args 4, num-type-args 0, names []
+  [9] = StaticICData target 'dart._internal::_prependTypeArguments', arg-desc CP#8
+  [10] = ClosureFunction nested2 <T7 extends dart.core::Object = dynamic, T8 extends dart.core::Object = dynamic>() → void;
+  [11] = StaticICData target 'dart._internal::_prependTypeArguments', arg-desc CP#8
+  [12] = ClosureFunction <anonymous closure> () → dart.core::Null;
+  [13] = TypeArgs [dart.core::Type]
+  [14] = Type #lib::A::T1
+  [15] = TypeArgumentsField #lib::A
+  [16] = Type #lib::A::T2
+  [17] = Type #lib::A::foo::T3
+  [18] = Type #lib::A::foo::T4
+  [19] = Type T5
+  [20] = Type T6
+  [21] = Type T7
+  [22] = Type T8
+  [23] = ArgDesc num-args 2, num-type-args 0, names []
+  [24] = StaticICData target 'dart.core::List::_fromLiteral', arg-desc CP#23
+  [25] = ArgDesc num-args 1, num-type-args 0, names []
+  [26] = StaticICData target 'dart.core::print', arg-desc CP#25
+  [27] = TypeArgs [#lib::A::T1, #lib::A::T2, #lib::A::foo::T3, #lib::A::foo::T4, T5, T6, T7, T8]
+  [28] = ArgDesc num-args 0, num-type-args 8, names []
+  [29] = StaticICData target '#lib::callWithArgs', arg-desc CP#28
+  [30] = EndClosureFunctionScope
+  [31] = Class dart.core::_Closure
+  [32] = InstanceField dart.core::_Closure::_instantiator_type_arguments
+  [33] = Reserved
+  [34] = InstanceField dart.core::_Closure::_function
+  [35] = Reserved
+  [36] = ICData dynamic target-name 'call', arg-desc CP#25
+  [37] = EndClosureFunctionScope
+  [38] = TypeArgs [#lib::C7, #lib::C8]
+  [39] = ArgDesc num-args 1, num-type-args 2, names []
+  [40] = ICData dynamic target-name 'call', arg-desc CP#39
+  [41] = TypeArgs [dart.core::List<#lib::C7>, dart.core::List<#lib::C8>]
+  [42] = ICData dynamic target-name 'call', arg-desc CP#39
+  [43] = EndClosureFunctionScope
+  [44] = TypeArgs [#lib::C5, #lib::C6]
+  [45] = ICData dynamic target-name 'call', arg-desc CP#39
+  [46] = TypeArgs [dart.core::List<#lib::C5>, dart.core::List<#lib::C6>]
+  [47] = ICData dynamic target-name 'call', arg-desc CP#39
 }
-Closure CP#15 {
+Closure CP#12 {
   EntryFixed           1, 4
   CheckStack
   Push                 FP[-5]
@@ -300,83 +281,83 @@
   Push                 FP[-5]
   LoadFieldTOS         CP#6
   PopLocal             r0
-  PushConstant         CP#16
+  PushConstant         CP#13
   StoreLocal           r3
   Push                 r3
-  PushConstant         CP#17
+  PushInt              8
   CreateArrayTOS
   StoreLocal           r3
   Push                 r3
-  PushConstant         CP#18
+  PushInt              0
   Push                 r1
   LoadContextVar       0
-  LoadTypeArgumentsField CP#20
-  PushConstant         CP#21
+  LoadTypeArgumentsField CP#15
+  PushNull
+  InstantiateType      CP#14
+  StoreIndexedTOS
+  Push                 r3
+  PushInt              1
+  Push                 r1
+  LoadContextVar       0
+  LoadTypeArgumentsField CP#15
+  PushNull
+  InstantiateType      CP#16
+  StoreIndexedTOS
+  Push                 r3
+  PushInt              2
+  PushNull
+  Push                 r0
+  InstantiateType      CP#17
+  StoreIndexedTOS
+  Push                 r3
+  PushInt              3
+  PushNull
+  Push                 r0
+  InstantiateType      CP#18
+  StoreIndexedTOS
+  Push                 r3
+  PushInt              4
+  PushNull
+  Push                 r0
   InstantiateType      CP#19
   StoreIndexedTOS
   Push                 r3
-  PushConstant         CP#22
-  Push                 r1
-  LoadContextVar       0
-  LoadTypeArgumentsField CP#20
-  PushConstant         CP#21
-  InstantiateType      CP#23
+  PushInt              5
+  PushNull
+  Push                 r0
+  InstantiateType      CP#20
   StoreIndexedTOS
   Push                 r3
-  PushConstant         CP#8
-  PushConstant         CP#21
+  PushInt              6
+  PushNull
   Push                 r0
-  InstantiateType      CP#24
+  InstantiateType      CP#21
   StoreIndexedTOS
   Push                 r3
-  PushConstant         CP#25
-  PushConstant         CP#21
+  PushInt              7
+  PushNull
   Push                 r0
-  InstantiateType      CP#26
+  InstantiateType      CP#22
   StoreIndexedTOS
-  Push                 r3
-  PushConstant         CP#9
-  PushConstant         CP#21
-  Push                 r0
-  InstantiateType      CP#27
-  StoreIndexedTOS
-  Push                 r3
-  PushConstant         CP#28
-  PushConstant         CP#21
-  Push                 r0
-  InstantiateType      CP#29
-  StoreIndexedTOS
-  Push                 r3
-  PushConstant         CP#13
-  PushConstant         CP#21
-  Push                 r0
-  InstantiateType      CP#30
-  StoreIndexedTOS
-  Push                 r3
-  PushConstant         CP#31
-  PushConstant         CP#21
-  Push                 r0
-  InstantiateType      CP#32
-  StoreIndexedTOS
-  PushConstant         CP#34
-  IndirectStaticCall   2, CP#33
-  PushConstant         CP#36
-  IndirectStaticCall   1, CP#35
+  PushConstant         CP#24
+  IndirectStaticCall   2, CP#23
+  PushConstant         CP#26
+  IndirectStaticCall   1, CP#25
   Drop1
   Push                 r1
   LoadContextVar       0
-  LoadTypeArgumentsField CP#20
+  LoadTypeArgumentsField CP#15
   Push                 r0
-  InstantiateTypeArgumentsTOS 0, CP#37
-  PushConstant         CP#39
-  IndirectStaticCall   1, CP#38
+  InstantiateTypeArgumentsTOS 0, CP#27
+  PushConstant         CP#29
+  IndirectStaticCall   1, CP#28
   Drop1
-  PushConstant         CP#21
+  PushNull
   ReturnTOS
 
 }
 
-Closure CP#12 {
+Closure CP#10 {
   EntryFixed           1, 5
   CheckStack
   Push                 FP[-5]
@@ -396,18 +377,18 @@
   Push                 r0
   Push                 FP[-5]
   LoadFieldTOS         CP#6
-  PushConstant         CP#9
-  PushConstant         CP#13
-  PushConstant         CP#14
-  IndirectStaticCall   4, CP#10
+  PushInt              4
+  PushInt              6
+  PushConstant         CP#11
+  IndirectStaticCall   4, CP#8
   PopLocal             r0
-  Allocate             CP#41
+  Allocate             CP#31
   StoreLocal           r4
   Push                 r4
   Push                 r1
   LoadContextVar       0
-  LoadTypeArgumentsField CP#20
-  StoreFieldTOS        CP#42
+  LoadTypeArgumentsField CP#15
+  StoreFieldTOS        CP#32
   Push                 r4
   Push                 r0
   StoreFieldTOS        CP#6
@@ -415,16 +396,16 @@
   PushConstant         CP#5
   StoreFieldTOS        CP#3
   Push                 r4
-  PushConstant         CP#15
-  StoreFieldTOS        CP#44
+  PushConstant         CP#12
+  StoreFieldTOS        CP#34
   Push                 r4
   Push                 r1
   StoreFieldTOS        CP#1
   PopLocal             r3
   Push                 r3
-  InstanceCall         1, CP#46
+  InstanceCall         1, CP#36
   Drop1
-  PushConstant         CP#21
+  PushNull
   ReturnTOS
 
 }
@@ -449,18 +430,18 @@
   Push                 r0
   Push                 FP[-5]
   LoadFieldTOS         CP#6
-  PushConstant         CP#8
+  PushInt              2
+  PushInt              4
   PushConstant         CP#9
-  PushConstant         CP#11
-  IndirectStaticCall   4, CP#10
+  IndirectStaticCall   4, CP#8
   PopLocal             r0
-  Allocate             CP#41
+  Allocate             CP#31
   StoreLocal           r4
   Push                 r4
   Push                 r1
   LoadContextVar       0
-  LoadTypeArgumentsField CP#20
-  StoreFieldTOS        CP#42
+  LoadTypeArgumentsField CP#15
+  StoreFieldTOS        CP#32
   Push                 r4
   Push                 r0
   StoreFieldTOS        CP#6
@@ -468,21 +449,21 @@
   PushConstant         CP#5
   StoreFieldTOS        CP#3
   Push                 r4
-  PushConstant         CP#12
-  StoreFieldTOS        CP#44
+  PushConstant         CP#10
+  StoreFieldTOS        CP#34
   Push                 r4
   Push                 r1
   StoreFieldTOS        CP#1
   PopLocal             r3
-  PushConstant         CP#48
+  PushConstant         CP#38
   Push                 r3
-  InstanceCall         2, CP#50
+  InstanceCall         2, CP#40
   Drop1
-  PushConstant         CP#51
+  PushConstant         CP#41
   Push                 r3
-  InstanceCall         2, CP#52
+  InstanceCall         2, CP#42
   Drop1
-  PushConstant         CP#21
+  PushNull
   ReturnTOS
 
 }
@@ -512,13 +493,12 @@
   PushConstant         CP#1
   IndirectStaticCall   1, CP#0
   Drop1
-  PushConstant         CP#2
+  PushNull
   ReturnTOS
 }
 ConstantPool {
   [0] = ArgDesc num-args 1, num-type-args 0, names []
   [1] = StaticICData target 'dart.core::Object::', arg-desc CP#0
-  [2] = Null
 }
 ]  synthetic constructor •() → void
     : super core::Object::•()
@@ -533,162 +513,152 @@
   Push                 FP[-5]
   StoreContextVar      0
   Push                 r0
-  PushConstant         CP#0
+  PushInt              1
   StoreContextVar      1
-  PushConstant         CP#1
+  PushInt              2
   PopLocal             r2
   Push                 r0
-  PushConstant         CP#2
+  PushInt              3
   StoreContextVar      2
-  Allocate             CP#22
+  Allocate             CP#15
   StoreLocal           r4
   Push                 r4
-  PushConstant         CP#6
+  PushNull
+  StoreFieldTOS        CP#16
+  Push                 r4
+  PushNull
+  StoreFieldTOS        CP#18
+  Push                 r4
+  PushConstant         CP#20
+  StoreFieldTOS        CP#21
+  Push                 r4
+  PushConstant         CP#0
   StoreFieldTOS        CP#23
   Push                 r4
-  PushConstant         CP#6
-  StoreFieldTOS        CP#25
-  Push                 r4
-  PushConstant         CP#27
-  StoreFieldTOS        CP#28
-  Push                 r4
-  PushConstant         CP#3
-  StoreFieldTOS        CP#30
-  Push                 r4
   Push                 r0
-  StoreFieldTOS        CP#4
+  StoreFieldTOS        CP#1
   PopLocal             r3
   Push                 r3
-  PushConstant         CP#35
-  InstanceCall         2, CP#36
+  PushInt              10
+  InstanceCall         2, CP#28
   Drop1
   Push                 r3
-  PushConstant         CP#37
-  InstanceCall         2, CP#38
+  PushInt              11
+  InstanceCall         2, CP#29
   Drop1
   Push                 r2
-  PushConstant         CP#39
-  IndirectStaticCall   1, CP#18
+  PushConstant         CP#30
+  IndirectStaticCall   1, CP#11
   Drop1
   Push                 r0
   LoadContextVar       2
-  PushConstant         CP#40
-  IndirectStaticCall   1, CP#18
+  PushConstant         CP#31
+  IndirectStaticCall   1, CP#11
   Drop1
   Push                 r0
   LoadContextVar       1
-  PushConstant         CP#41
-  IndirectStaticCall   1, CP#18
+  PushConstant         CP#32
+  IndirectStaticCall   1, CP#11
   Drop1
   Push                 r0
-  PushConstant         CP#42
+  PushInt              42
   StoreContextVar      3
-  Allocate             CP#22
+  Allocate             CP#15
   StoreLocal           r3
   Push                 r3
-  PushConstant         CP#6
+  PushNull
+  StoreFieldTOS        CP#16
+  Push                 r3
+  PushNull
+  StoreFieldTOS        CP#18
+  Push                 r3
+  PushConstant         CP#20
+  StoreFieldTOS        CP#21
+  Push                 r3
+  PushConstant         CP#33
   StoreFieldTOS        CP#23
   Push                 r3
-  PushConstant         CP#6
-  StoreFieldTOS        CP#25
-  Push                 r3
-  PushConstant         CP#27
-  StoreFieldTOS        CP#28
-  Push                 r3
-  PushConstant         CP#43
-  StoreFieldTOS        CP#30
-  Push                 r3
   Push                 r0
-  StoreFieldTOS        CP#4
+  StoreFieldTOS        CP#1
   PopLocal             r2
   Push                 r2
-  InstanceCall         1, CP#46
+  InstanceCall         1, CP#36
   Drop1
-  PushConstant         CP#6
+  PushNull
   ReturnTOS
 }
 ConstantPool {
-  [0] = Int 1
-  [1] = Int 2
-  [2] = Int 3
-  [3] = ClosureFunction <anonymous closure> (dart.core::int y) → dart.core::Null;
-  [4] = InstanceField dart.core::_Closure::_context
-  [5] = Reserved
-  [6] = Null
-  [7] = Type dart.core::int
-  [8] = String 'y'
-  [9] = SubtypeTestCache
-  [10] = ArgDesc num-args 2, num-type-args 0, names []
-  [11] = ICData target-name '+', arg-desc CP#10
-  [12] = Int 5
-  [13] = ICData target-name '>', arg-desc CP#10
-  [14] = Bool true
-  [15] = Int 4
-  [16] = ClosureFunction closure2 () → void;
-  [17] = ICData target-name '+', arg-desc CP#10
-  [18] = ArgDesc num-args 1, num-type-args 0, names []
-  [19] = ICData get target-name 'foo', arg-desc CP#18
-  [20] = ICData target-name '+', arg-desc CP#10
-  [21] = EndClosureFunctionScope
-  [22] = Class dart.core::_Closure
-  [23] = InstanceField dart.core::_Closure::_instantiator_type_arguments
+  [0] = ClosureFunction <anonymous closure> (dart.core::int y) → dart.core::Null;
+  [1] = InstanceField dart.core::_Closure::_context
+  [2] = Reserved
+  [3] = Type dart.core::int
+  [4] = String 'y'
+  [5] = SubtypeTestCache
+  [6] = ArgDesc num-args 2, num-type-args 0, names []
+  [7] = ICData target-name '+', arg-desc CP#6
+  [8] = ICData target-name '>', arg-desc CP#6
+  [9] = ClosureFunction closure2 () → void;
+  [10] = ICData target-name '+', arg-desc CP#6
+  [11] = ArgDesc num-args 1, num-type-args 0, names []
+  [12] = ICData get target-name 'foo', arg-desc CP#11
+  [13] = ICData target-name '+', arg-desc CP#6
+  [14] = EndClosureFunctionScope
+  [15] = Class dart.core::_Closure
+  [16] = InstanceField dart.core::_Closure::_instantiator_type_arguments
+  [17] = Reserved
+  [18] = InstanceField dart.core::_Closure::_function_type_arguments
+  [19] = Reserved
+  [20] = EmptyTypeArguments
+  [21] = InstanceField dart.core::_Closure::_delayed_type_arguments
+  [22] = Reserved
+  [23] = InstanceField dart.core::_Closure::_function
   [24] = Reserved
-  [25] = InstanceField dart.core::_Closure::_function_type_arguments
-  [26] = Reserved
-  [27] = EmptyTypeArguments
-  [28] = InstanceField dart.core::_Closure::_delayed_type_arguments
-  [29] = Reserved
-  [30] = InstanceField dart.core::_Closure::_function
-  [31] = Reserved
-  [32] = ICData target-name 'call', arg-desc CP#18
-  [33] = StaticICData target 'dart.core::print', arg-desc CP#18
-  [34] = EndClosureFunctionScope
-  [35] = Int 10
-  [36] = ICData target-name 'call', arg-desc CP#10
-  [37] = Int 11
-  [38] = ICData target-name 'call', arg-desc CP#10
-  [39] = StaticICData target 'dart.core::print', arg-desc CP#18
-  [40] = StaticICData target 'dart.core::print', arg-desc CP#18
-  [41] = StaticICData target 'dart.core::print', arg-desc CP#18
-  [42] = Int 42
-  [43] = ClosureFunction <anonymous closure> () → dart.core::Null;
-  [44] = ICData set target-name 'foo', arg-desc CP#10
-  [45] = EndClosureFunctionScope
-  [46] = ICData target-name 'call', arg-desc CP#18
+  [25] = ICData dynamic target-name 'call', arg-desc CP#11
+  [26] = StaticICData target 'dart.core::print', arg-desc CP#11
+  [27] = EndClosureFunctionScope
+  [28] = ICData dynamic target-name 'call', arg-desc CP#6
+  [29] = ICData dynamic target-name 'call', arg-desc CP#6
+  [30] = StaticICData target 'dart.core::print', arg-desc CP#11
+  [31] = StaticICData target 'dart.core::print', arg-desc CP#11
+  [32] = StaticICData target 'dart.core::print', arg-desc CP#11
+  [33] = ClosureFunction <anonymous closure> () → dart.core::Null;
+  [34] = ICData set target-name 'foo', arg-desc CP#6
+  [35] = EndClosureFunctionScope
+  [36] = ICData dynamic target-name 'call', arg-desc CP#11
 }
-Closure CP#16 {
+Closure CP#9 {
   EntryFixed           1, 3
   CheckStack
   Push                 FP[-5]
-  LoadFieldTOS         CP#4
+  LoadFieldTOS         CP#1
   PopLocal             r0
   Push                 r0
   LoadContextParent
   Push                 r0
   LoadContextParent
   LoadContextVar       1
-  PushConstant         CP#1
-  InstanceCall         2, CP#17
+  PushInt              2
+  InstanceCall         2, CP#10
   StoreContextVar      2
   Push                 r0
   Push                 r0
   LoadContextParent
   LoadContextVar       0
-  InstanceCall         1, CP#19
+  InstanceCall         1, CP#12
   Push                 r0
   LoadContextVar       0
-  InstanceCall         2, CP#20
+  InstanceCall         2, CP#13
   StoreContextVar      1
-  PushConstant         CP#6
+  PushNull
   ReturnTOS
 
 }
 
-Closure CP#3 {
+Closure CP#0 {
   EntryFixed           2, 4
   CheckStack
   Push                 FP[-6]
-  LoadFieldTOS         CP#4
+  LoadFieldTOS         CP#1
   PopLocal             r0
   AllocateContext      2
   StoreLocal           r1
@@ -700,76 +670,76 @@
   Push                 FP[-5]
   StoreContextVar      0
   Push                 FP[-5]
-  PushConstant         CP#6
-  PushConstant         CP#6
-  PushConstant         CP#7
-  PushConstant         CP#8
-  AssertAssignable     1, CP#9
+  PushNull
+  PushNull
+  PushConstant         CP#3
+  PushConstant         CP#4
+  AssertAssignable     1, CP#5
   Drop1
   Push                 r0
   LoadContextParent
   Push                 r0
   LoadContextVar       0
-  PushConstant         CP#0
-  InstanceCall         2, CP#11
+  PushInt              1
+  InstanceCall         2, CP#7
   StoreContextVar      1
   Push                 r0
   LoadContextParent
   LoadContextVar       1
-  PushConstant         CP#12
-  InstanceCall         2, CP#13
+  PushInt              5
+  InstanceCall         2, CP#8
   AssertBoolean        0
-  PushConstant         CP#14
+  PushTrue
   IfNeStrictTOS
   Jump                 L1
   Push                 r0
-  PushConstant         CP#15
+  PushInt              4
   StoreContextVar      1
-  Allocate             CP#22
+  Allocate             CP#15
   StoreLocal           r2
   Push                 r2
-  PushConstant         CP#6
+  PushNull
+  StoreFieldTOS        CP#16
+  Push                 r2
+  PushNull
+  StoreFieldTOS        CP#18
+  Push                 r2
+  PushConstant         CP#20
+  StoreFieldTOS        CP#21
+  Push                 r2
+  PushConstant         CP#9
   StoreFieldTOS        CP#23
   Push                 r2
-  PushConstant         CP#6
-  StoreFieldTOS        CP#25
-  Push                 r2
-  PushConstant         CP#27
-  StoreFieldTOS        CP#28
-  Push                 r2
-  PushConstant         CP#16
-  StoreFieldTOS        CP#30
-  Push                 r2
   Push                 r0
-  StoreFieldTOS        CP#4
+  StoreFieldTOS        CP#1
   PopLocal             r3
   Push                 r3
-  InstanceCall         1, CP#32
+  InstanceCall         1, CP#25
   Drop1
   Push                 r0
   LoadContextVar       1
-  PushConstant         CP#33
-  IndirectStaticCall   1, CP#18
+  PushConstant         CP#26
+  IndirectStaticCall   1, CP#11
   Drop1
 L1:
-  PushConstant         CP#6
+  PushNull
   ReturnTOS
 
 }
 
-Closure CP#43 {
+Closure CP#33 {
   EntryFixed           1, 3
   CheckStack
   Push                 FP[-5]
-  LoadFieldTOS         CP#4
+  LoadFieldTOS         CP#1
   PopLocal             r0
   Push                 r0
   LoadContextVar       0
   Push                 r0
   LoadContextVar       3
-  InstanceCall         2, CP#44
+  InstanceCall         2, CP#34
   Drop1
-  PushConstant         CP#6
+  PushNull
   ReturnTOS
 
 }
@@ -816,13 +786,12 @@
   PushConstant         CP#1
   IndirectStaticCall   1, CP#0
   Drop1
-  PushConstant         CP#2
+  PushNull
   ReturnTOS
 }
 ConstantPool {
   [0] = ArgDesc num-args 1, num-type-args 0, names []
   [1] = StaticICData target 'dart.core::Object::', arg-desc CP#0
-  [2] = Null
 }
 ]  synthetic constructor •() → void
     : super core::Object::•()
@@ -834,25 +803,25 @@
   AllocateContext      1
   PopLocal             r0
   Push                 r0
-  PushConstant         CP#0
+  PushInt              0
   StoreContextVar      0
-  PushConstant         CP#1
+  PushConstant         CP#0
   StoreLocal           r3
   Push                 r3
+  PushInt              0
+  CreateArrayTOS
+  StoreLocal           r3
+  PushConstant         CP#2
+  IndirectStaticCall   2, CP#1
+  PopLocal             r2
   PushConstant         CP#0
+  StoreLocal           r3
+  Push                 r3
+  PushInt              0
   CreateArrayTOS
   StoreLocal           r3
   PushConstant         CP#3
-  IndirectStaticCall   2, CP#2
-  PopLocal             r2
-  PushConstant         CP#1
-  StoreLocal           r3
-  Push                 r3
-  PushConstant         CP#0
-  CreateArrayTOS
-  StoreLocal           r3
-  PushConstant         CP#4
-  IndirectStaticCall   2, CP#2
+  IndirectStaticCall   2, CP#1
   PopLocal             r4
   AllocateContext      1
   StoreLocal           r1
@@ -861,57 +830,57 @@
   StoreContextParent
   PopLocal             r0
   Push                 r0
-  PushConstant         CP#0
+  PushInt              0
   StoreContextVar      0
 L2:
   CheckStack
   Push                 r0
   LoadContextVar       0
-  PushConstant         CP#5
-  InstanceCall         2, CP#6
+  PushInt              10
+  InstanceCall         2, CP#4
   AssertBoolean        0
-  PushConstant         CP#7
+  PushTrue
   IfNeStrictTOS
   Jump                 L1
   Push                 r2
-  Allocate             CP#14
+  Allocate             CP#10
   StoreLocal           r3
   Push                 r3
-  PushConstant         CP#12
-  StoreFieldTOS        CP#15
+  PushNull
+  StoreFieldTOS        CP#11
   Push                 r3
-  PushConstant         CP#12
-  StoreFieldTOS        CP#17
+  PushNull
+  StoreFieldTOS        CP#13
   Push                 r3
-  PushConstant         CP#19
-  StoreFieldTOS        CP#20
+  PushConstant         CP#15
+  StoreFieldTOS        CP#16
   Push                 r3
-  PushConstant         CP#8
-  StoreFieldTOS        CP#22
+  PushConstant         CP#5
+  StoreFieldTOS        CP#18
   Push                 r3
   Push                 r0
-  StoreFieldTOS        CP#9
-  InstanceCall         2, CP#24
+  StoreFieldTOS        CP#6
+  InstanceCall         2, CP#20
   Drop1
   Push                 r4
-  Allocate             CP#14
+  Allocate             CP#10
   StoreLocal           r3
   Push                 r3
-  PushConstant         CP#12
-  StoreFieldTOS        CP#15
+  PushNull
+  StoreFieldTOS        CP#11
   Push                 r3
-  PushConstant         CP#12
-  StoreFieldTOS        CP#17
+  PushNull
+  StoreFieldTOS        CP#13
   Push                 r3
-  PushConstant         CP#19
-  StoreFieldTOS        CP#20
+  PushConstant         CP#15
+  StoreFieldTOS        CP#16
   Push                 r3
-  PushConstant         CP#25
-  StoreFieldTOS        CP#22
+  PushConstant         CP#21
+  StoreFieldTOS        CP#18
   Push                 r3
   Push                 r0
-  StoreFieldTOS        CP#9
-  InstanceCall         2, CP#31
+  StoreFieldTOS        CP#6
+  InstanceCall         2, CP#27
   Drop1
   Push                 r0
   CloneContext
@@ -919,8 +888,8 @@
   Push                 r0
   Push                 r0
   LoadContextVar       0
-  PushConstant         CP#32
-  InstanceCall         2, CP#33
+  PushInt              1
+  InstanceCall         2, CP#28
   StoreLocal           r3
   StoreContextVar      0
   Push                 r3
@@ -933,84 +902,79 @@
   Push                 r0
   LoadContextParent
   PopLocal             r0
-  PushConstant         CP#12
+  PushNull
   ReturnTOS
 }
 ConstantPool {
-  [0] = Int 0
-  [1] = TypeArgs [dart.core::Function]
-  [2] = ArgDesc num-args 2, num-type-args 0, names []
-  [3] = StaticICData target 'dart.core::List::_fromLiteral', arg-desc CP#2
-  [4] = StaticICData target 'dart.core::List::_fromLiteral', arg-desc CP#2
-  [5] = Int 10
-  [6] = ICData target-name '<', arg-desc CP#2
-  [7] = Bool true
-  [8] = ClosureFunction <anonymous closure> () → dart.core::int;
-  [9] = InstanceField dart.core::_Closure::_context
-  [10] = Reserved
-  [11] = ICData target-name '+', arg-desc CP#2
-  [12] = Null
-  [13] = EndClosureFunctionScope
-  [14] = Class dart.core::_Closure
-  [15] = InstanceField dart.core::_Closure::_instantiator_type_arguments
-  [16] = Reserved
-  [17] = InstanceField dart.core::_Closure::_function_type_arguments
-  [18] = Reserved
-  [19] = EmptyTypeArguments
-  [20] = InstanceField dart.core::_Closure::_delayed_type_arguments
-  [21] = Reserved
-  [22] = InstanceField dart.core::_Closure::_function
-  [23] = Reserved
-  [24] = ICData target-name 'add', arg-desc CP#2
-  [25] = ClosureFunction <anonymous closure> (dart.core::int ii) → dart.core::Null;
-  [26] = Type dart.core::int
-  [27] = String 'ii'
-  [28] = SubtypeTestCache
-  [29] = ICData target-name '+', arg-desc CP#2
-  [30] = EndClosureFunctionScope
-  [31] = ICData target-name 'add', arg-desc CP#2
-  [32] = Int 1
-  [33] = ICData target-name '+', arg-desc CP#2
+  [0] = TypeArgs [dart.core::Function]
+  [1] = ArgDesc num-args 2, num-type-args 0, names []
+  [2] = StaticICData target 'dart.core::List::_fromLiteral', arg-desc CP#1
+  [3] = StaticICData target 'dart.core::List::_fromLiteral', arg-desc CP#1
+  [4] = ICData target-name '<', arg-desc CP#1
+  [5] = ClosureFunction <anonymous closure> () → dart.core::int;
+  [6] = InstanceField dart.core::_Closure::_context
+  [7] = Reserved
+  [8] = ICData target-name '+', arg-desc CP#1
+  [9] = EndClosureFunctionScope
+  [10] = Class dart.core::_Closure
+  [11] = InstanceField dart.core::_Closure::_instantiator_type_arguments
+  [12] = Reserved
+  [13] = InstanceField dart.core::_Closure::_function_type_arguments
+  [14] = Reserved
+  [15] = EmptyTypeArguments
+  [16] = InstanceField dart.core::_Closure::_delayed_type_arguments
+  [17] = Reserved
+  [18] = InstanceField dart.core::_Closure::_function
+  [19] = Reserved
+  [20] = ICData target-name 'add', arg-desc CP#1
+  [21] = ClosureFunction <anonymous closure> (dart.core::int ii) → dart.core::Null;
+  [22] = Type dart.core::int
+  [23] = String 'ii'
+  [24] = SubtypeTestCache
+  [25] = ICData target-name '+', arg-desc CP#1
+  [26] = EndClosureFunctionScope
+  [27] = ICData target-name 'add', arg-desc CP#1
+  [28] = ICData target-name '+', arg-desc CP#1
 }
-Closure CP#8 {
+Closure CP#5 {
   EntryFixed           1, 2
   CheckStack
   Push                 FP[-5]
-  LoadFieldTOS         CP#9
+  LoadFieldTOS         CP#6
   PopLocal             r0
   Push                 r0
   LoadContextVar       0
   Push                 r0
   LoadContextParent
   LoadContextVar       0
-  InstanceCall         2, CP#11
+  InstanceCall         2, CP#8
   ReturnTOS
-  PushConstant         CP#12
+  PushNull
   ReturnTOS
 
 }
 
-Closure CP#25 {
+Closure CP#21 {
   EntryFixed           2, 3
   CheckStack
   Push                 FP[-6]
-  LoadFieldTOS         CP#9
+  LoadFieldTOS         CP#6
   PopLocal             r0
   Push                 FP[-5]
-  PushConstant         CP#12
-  PushConstant         CP#12
-  PushConstant         CP#26
-  PushConstant         CP#27
-  AssertAssignable     1, CP#28
+  PushNull
+  PushNull
+  PushConstant         CP#22
+  PushConstant         CP#23
+  AssertAssignable     1, CP#24
   Drop1
   Push                 r0
   Push                 FP[-5]
   Push                 r0
   LoadContextParent
   LoadContextVar       0
-  InstanceCall         2, CP#29
+  InstanceCall         2, CP#25
   StoreContextVar      0
-  PushConstant         CP#12
+  PushNull
   ReturnTOS
 
 }
@@ -1030,105 +994,92 @@
   Entry                5
   CheckStack
   Push                 FP[-5]
-  PushConstant         CP#0
-  PushConstant         CP#0
-  PushConstant         CP#1
-  PushConstant         CP#2
-  AssertAssignable     0, CP#3
-  Drop1
-  Push                 FP[-5]
-  InstanceCall         1, CP#5
+  InstanceCall         1, CP#1
   PopLocal             r2
 L2:
   CheckStack
   Push                 r2
-  InstanceCall         1, CP#6
-  PushConstant         CP#7
+  InstanceCall         1, CP#2
+  PushTrue
   IfNeStrictTOS
   Jump                 L1
   AllocateContext      1
   PopLocal             r0
   Push                 r0
   Push                 r2
-  InstanceCall         1, CP#8
+  InstanceCall         1, CP#3
   StoreContextVar      0
-  Allocate             CP#16
+  Allocate             CP#10
   StoreLocal           r4
   Push                 r4
-  PushConstant         CP#0
-  StoreFieldTOS        CP#17
+  PushNull
+  StoreFieldTOS        CP#11
   Push                 r4
-  PushConstant         CP#0
-  StoreFieldTOS        CP#19
+  PushNull
+  StoreFieldTOS        CP#13
   Push                 r4
-  PushConstant         CP#21
-  StoreFieldTOS        CP#22
+  PushConstant         CP#15
+  StoreFieldTOS        CP#16
   Push                 r4
-  PushConstant         CP#9
-  StoreFieldTOS        CP#24
+  PushConstant         CP#4
+  StoreFieldTOS        CP#18
   Push                 r4
   Push                 r0
-  StoreFieldTOS        CP#10
+  StoreFieldTOS        CP#5
   PopLocal             r3
   Push                 r3
-  InstanceCall         1, CP#26
+  InstanceCall         1, CP#20
   Drop1
   Push                 r0
   LoadContextVar       0
-  PushConstant         CP#27
-  IndirectStaticCall   1, CP#4
+  PushConstant         CP#21
+  IndirectStaticCall   1, CP#0
   Drop1
   Push                 r0
   LoadContextParent
   PopLocal             r0
   Jump                 L2
 L1:
-  PushConstant         CP#0
+  PushNull
   ReturnTOS
 }
 ConstantPool {
-  [0] = Null
-  [1] = Type dart.core::List<dart.core::int>
-  [2] = String 'list'
-  [3] = SubtypeTestCache
-  [4] = ArgDesc num-args 1, num-type-args 0, names []
-  [5] = ICData get target-name 'iterator', arg-desc CP#4
-  [6] = ICData target-name 'moveNext', arg-desc CP#4
-  [7] = Bool true
-  [8] = ICData get target-name 'current', arg-desc CP#4
-  [9] = ClosureFunction <anonymous closure> () → dart.core::Null;
-  [10] = InstanceField dart.core::_Closure::_context
-  [11] = Reserved
-  [12] = Int 1
-  [13] = ArgDesc num-args 2, num-type-args 0, names []
-  [14] = ICData target-name '+', arg-desc CP#13
-  [15] = EndClosureFunctionScope
-  [16] = Class dart.core::_Closure
-  [17] = InstanceField dart.core::_Closure::_instantiator_type_arguments
-  [18] = Reserved
-  [19] = InstanceField dart.core::_Closure::_function_type_arguments
-  [20] = Reserved
-  [21] = EmptyTypeArguments
-  [22] = InstanceField dart.core::_Closure::_delayed_type_arguments
-  [23] = Reserved
-  [24] = InstanceField dart.core::_Closure::_function
-  [25] = Reserved
-  [26] = ICData target-name 'call', arg-desc CP#4
-  [27] = StaticICData target 'dart.core::print', arg-desc CP#4
+  [0] = ArgDesc num-args 1, num-type-args 0, names []
+  [1] = ICData get target-name 'iterator', arg-desc CP#0
+  [2] = ICData target-name 'moveNext', arg-desc CP#0
+  [3] = ICData get target-name 'current', arg-desc CP#0
+  [4] = ClosureFunction <anonymous closure> () → dart.core::Null;
+  [5] = InstanceField dart.core::_Closure::_context
+  [6] = Reserved
+  [7] = ArgDesc num-args 2, num-type-args 0, names []
+  [8] = ICData target-name '+', arg-desc CP#7
+  [9] = EndClosureFunctionScope
+  [10] = Class dart.core::_Closure
+  [11] = InstanceField dart.core::_Closure::_instantiator_type_arguments
+  [12] = Reserved
+  [13] = InstanceField dart.core::_Closure::_function_type_arguments
+  [14] = Reserved
+  [15] = EmptyTypeArguments
+  [16] = InstanceField dart.core::_Closure::_delayed_type_arguments
+  [17] = Reserved
+  [18] = InstanceField dart.core::_Closure::_function
+  [19] = Reserved
+  [20] = ICData dynamic target-name 'call', arg-desc CP#0
+  [21] = StaticICData target 'dart.core::print', arg-desc CP#0
 }
-Closure CP#9 {
+Closure CP#4 {
   EntryFixed           1, 3
   CheckStack
   Push                 FP[-5]
-  LoadFieldTOS         CP#10
+  LoadFieldTOS         CP#5
   PopLocal             r0
   Push                 r0
   Push                 r0
   LoadContextVar       0
-  PushConstant         CP#12
-  InstanceCall         2, CP#14
+  PushInt              1
+  InstanceCall         2, CP#8
   StoreContextVar      0
-  PushConstant         CP#0
+  PushNull
   ReturnTOS
 
 }
@@ -1151,13 +1102,12 @@
   PushConstant         CP#1
   IndirectStaticCall   1, CP#0
   Drop1
-  PushConstant         CP#2
+  PushNull
   ReturnTOS
 }
 ConstantPool {
   [0] = ArgDesc num-args 1, num-type-args 0, names []
   [1] = StaticICData target 'dart.core::Object::', arg-desc CP#0
-  [2] = Null
 }
 ]  synthetic constructor •() → void
     : super core::Object::•()
@@ -1174,64 +1124,63 @@
   Push                 FP[-5]
   Push                 FP[-6]
   LoadTypeArgumentsField CP#0
+  PushNull
   PushConstant         CP#1
   PushConstant         CP#2
-  PushConstant         CP#3
-  AssertAssignable     0, CP#4
+  AssertAssignable     0, CP#3
   Drop1
-  Allocate             CP#9
+  Allocate             CP#8
   StoreLocal           r2
   Push                 r2
   Push                 FP[-6]
   LoadTypeArgumentsField CP#0
-  StoreFieldTOS        CP#10
+  StoreFieldTOS        CP#9
   Push                 r2
-  PushConstant         CP#1
-  StoreFieldTOS        CP#12
+  PushNull
+  StoreFieldTOS        CP#11
   Push                 r2
-  PushConstant         CP#14
-  StoreFieldTOS        CP#15
+  PushConstant         CP#13
+  StoreFieldTOS        CP#14
   Push                 r2
-  PushConstant         CP#5
-  StoreFieldTOS        CP#17
+  PushConstant         CP#4
+  StoreFieldTOS        CP#16
   Push                 r2
   Push                 r0
-  StoreFieldTOS        CP#6
+  StoreFieldTOS        CP#5
   ReturnTOS
-  PushConstant         CP#1
+  PushNull
   ReturnTOS
 }
 ConstantPool {
   [0] = TypeArgumentsField #lib::D
-  [1] = Null
-  [2] = Type #lib::D::T
-  [3] = String 't'
-  [4] = SubtypeTestCache
-  [5] = ClosureFunction <anonymous closure> () → #lib::D::T;
-  [6] = InstanceField dart.core::_Closure::_context
-  [7] = Reserved
-  [8] = EndClosureFunctionScope
-  [9] = Class dart.core::_Closure
-  [10] = InstanceField dart.core::_Closure::_instantiator_type_arguments
-  [11] = Reserved
-  [12] = InstanceField dart.core::_Closure::_function_type_arguments
-  [13] = Reserved
-  [14] = EmptyTypeArguments
-  [15] = InstanceField dart.core::_Closure::_delayed_type_arguments
-  [16] = Reserved
-  [17] = InstanceField dart.core::_Closure::_function
-  [18] = Reserved
+  [1] = Type #lib::D::T
+  [2] = String 't'
+  [3] = SubtypeTestCache
+  [4] = ClosureFunction <anonymous closure> () → #lib::D::T;
+  [5] = InstanceField dart.core::_Closure::_context
+  [6] = Reserved
+  [7] = EndClosureFunctionScope
+  [8] = Class dart.core::_Closure
+  [9] = InstanceField dart.core::_Closure::_instantiator_type_arguments
+  [10] = Reserved
+  [11] = InstanceField dart.core::_Closure::_function_type_arguments
+  [12] = Reserved
+  [13] = EmptyTypeArguments
+  [14] = InstanceField dart.core::_Closure::_delayed_type_arguments
+  [15] = Reserved
+  [16] = InstanceField dart.core::_Closure::_function
+  [17] = Reserved
 }
-Closure CP#5 {
+Closure CP#4 {
   EntryFixed           1, 2
   CheckStack
   Push                 FP[-5]
-  LoadFieldTOS         CP#6
+  LoadFieldTOS         CP#5
   PopLocal             r0
   Push                 r0
   LoadContextVar       0
   ReturnTOS
-  PushConstant         CP#1
+  PushNull
   ReturnTOS
 
 }
@@ -1246,29 +1195,29 @@
   AllocateContext      1
   PopLocal             r0
   Push                 r0
-  PushConstant         CP#0
+  PushInt              5
   StoreContextVar      0
-  Allocate             CP#11
+  Allocate             CP#9
   StoreLocal           r3
   Push                 r3
-  PushConstant         CP#4
+  PushNull
+  StoreFieldTOS        CP#10
+  Push                 r3
+  PushNull
   StoreFieldTOS        CP#12
   Push                 r3
-  PushConstant         CP#4
-  StoreFieldTOS        CP#14
+  PushConstant         CP#14
+  StoreFieldTOS        CP#15
   Push                 r3
-  PushConstant         CP#16
+  PushConstant         CP#0
   StoreFieldTOS        CP#17
   Push                 r3
-  PushConstant         CP#1
-  StoreFieldTOS        CP#19
-  Push                 r3
   Push                 r0
-  StoreFieldTOS        CP#2
+  StoreFieldTOS        CP#1
   PopLocal             r2
   Push                 r2
-  PushConstant         CP#21
-  InstanceCall         2, CP#22
+  PushInt              3
+  InstanceCall         2, CP#19
   Drop1
   Push                 r0
   LoadContextVar       0
@@ -1276,54 +1225,51 @@
   Push                 r0
   LoadContextParent
   PopLocal             r0
-  PushConstant         CP#4
+  PushNull
   ReturnTOS
 }
 ConstantPool {
-  [0] = Int 5
-  [1] = ClosureFunction <anonymous closure> (dart.core::int y) → dart.core::Null;
-  [2] = InstanceField dart.core::_Closure::_context
-  [3] = Reserved
-  [4] = Null
-  [5] = Type dart.core::int
-  [6] = String 'y'
-  [7] = SubtypeTestCache
-  [8] = ArgDesc num-args 2, num-type-args 0, names []
-  [9] = ICData target-name '+', arg-desc CP#8
-  [10] = EndClosureFunctionScope
-  [11] = Class dart.core::_Closure
-  [12] = InstanceField dart.core::_Closure::_instantiator_type_arguments
+  [0] = ClosureFunction <anonymous closure> (dart.core::int y) → dart.core::Null;
+  [1] = InstanceField dart.core::_Closure::_context
+  [2] = Reserved
+  [3] = Type dart.core::int
+  [4] = String 'y'
+  [5] = SubtypeTestCache
+  [6] = ArgDesc num-args 2, num-type-args 0, names []
+  [7] = ICData target-name '+', arg-desc CP#6
+  [8] = EndClosureFunctionScope
+  [9] = Class dart.core::_Closure
+  [10] = InstanceField dart.core::_Closure::_instantiator_type_arguments
+  [11] = Reserved
+  [12] = InstanceField dart.core::_Closure::_function_type_arguments
   [13] = Reserved
-  [14] = InstanceField dart.core::_Closure::_function_type_arguments
-  [15] = Reserved
-  [16] = EmptyTypeArguments
-  [17] = InstanceField dart.core::_Closure::_delayed_type_arguments
+  [14] = EmptyTypeArguments
+  [15] = InstanceField dart.core::_Closure::_delayed_type_arguments
+  [16] = Reserved
+  [17] = InstanceField dart.core::_Closure::_function
   [18] = Reserved
-  [19] = InstanceField dart.core::_Closure::_function
-  [20] = Reserved
-  [21] = Int 3
-  [22] = ICData target-name 'call', arg-desc CP#8
+  [19] = ICData dynamic target-name 'call', arg-desc CP#6
 }
-Closure CP#1 {
+Closure CP#0 {
   EntryFixed           2, 3
   CheckStack
   Push                 FP[-6]
-  LoadFieldTOS         CP#2
+  LoadFieldTOS         CP#1
   PopLocal             r0
   Push                 FP[-5]
+  PushNull
+  PushNull
+  PushConstant         CP#3
   PushConstant         CP#4
-  PushConstant         CP#4
-  PushConstant         CP#5
-  PushConstant         CP#6
-  AssertAssignable     1, CP#7
+  AssertAssignable     1, CP#5
   Drop1
   Push                 r0
   Push                 r0
   LoadContextVar       0
   Push                 FP[-5]
-  InstanceCall         2, CP#9
+  InstanceCall         2, CP#7
   StoreContextVar      0
-  PushConstant         CP#4
+  PushNull
   ReturnTOS
 
 }
@@ -1343,89 +1289,79 @@
   PushConstant         CP#0
   StoreLocal           r1
   Push                 r1
-  PushConstant         CP#1
+  PushInt              8
   CreateArrayTOS
   StoreLocal           r1
   Push                 r1
-  PushConstant         CP#2
-  PushConstant         CP#4
+  PushInt              0
+  PushNull
+  Push                 r0
+  InstantiateType      CP#1
+  StoreIndexedTOS
+  Push                 r1
+  PushInt              1
+  PushNull
+  Push                 r0
+  InstantiateType      CP#2
+  StoreIndexedTOS
+  Push                 r1
+  PushInt              2
+  PushNull
   Push                 r0
   InstantiateType      CP#3
   StoreIndexedTOS
   Push                 r1
-  PushConstant         CP#5
-  PushConstant         CP#4
+  PushInt              3
+  PushNull
+  Push                 r0
+  InstantiateType      CP#4
+  StoreIndexedTOS
+  Push                 r1
+  PushInt              4
+  PushNull
+  Push                 r0
+  InstantiateType      CP#5
+  StoreIndexedTOS
+  Push                 r1
+  PushInt              5
+  PushNull
   Push                 r0
   InstantiateType      CP#6
   StoreIndexedTOS
   Push                 r1
-  PushConstant         CP#7
-  PushConstant         CP#4
+  PushInt              6
+  PushNull
+  Push                 r0
+  InstantiateType      CP#7
+  StoreIndexedTOS
+  Push                 r1
+  PushInt              7
+  PushNull
   Push                 r0
   InstantiateType      CP#8
   StoreIndexedTOS
-  Push                 r1
-  PushConstant         CP#9
-  PushConstant         CP#4
-  Push                 r0
-  InstantiateType      CP#10
-  StoreIndexedTOS
-  Push                 r1
-  PushConstant         CP#11
-  PushConstant         CP#4
-  Push                 r0
-  InstantiateType      CP#12
-  StoreIndexedTOS
-  Push                 r1
-  PushConstant         CP#13
-  PushConstant         CP#4
-  Push                 r0
-  InstantiateType      CP#14
-  StoreIndexedTOS
-  Push                 r1
-  PushConstant         CP#15
-  PushConstant         CP#4
-  Push                 r0
-  InstantiateType      CP#16
-  StoreIndexedTOS
-  Push                 r1
-  PushConstant         CP#17
-  PushConstant         CP#4
-  Push                 r0
-  InstantiateType      CP#18
-  StoreIndexedTOS
-  PushConstant         CP#20
-  IndirectStaticCall   2, CP#19
-  PushConstant         CP#22
-  IndirectStaticCall   1, CP#21
+  PushConstant         CP#10
+  IndirectStaticCall   2, CP#9
+  PushConstant         CP#12
+  IndirectStaticCall   1, CP#11
   Drop1
-  PushConstant         CP#4
+  PushNull
   ReturnTOS
 }
 ConstantPool {
   [0] = TypeArgs [dart.core::Type]
-  [1] = Int 8
-  [2] = Int 0
-  [3] = Type #lib::callWithArgs::T1
-  [4] = Null
-  [5] = Int 1
-  [6] = Type #lib::callWithArgs::T2
-  [7] = Int 2
-  [8] = Type #lib::callWithArgs::T3
-  [9] = Int 3
-  [10] = Type #lib::callWithArgs::T4
-  [11] = Int 4
-  [12] = Type #lib::callWithArgs::T5
-  [13] = Int 5
-  [14] = Type #lib::callWithArgs::T6
-  [15] = Int 6
-  [16] = Type #lib::callWithArgs::T7
-  [17] = Int 7
-  [18] = Type #lib::callWithArgs::T8
-  [19] = ArgDesc num-args 2, num-type-args 0, names []
-  [20] = StaticICData target 'dart.core::List::_fromLiteral', arg-desc CP#19
-  [21] = ArgDesc num-args 1, num-type-args 0, names []
-  [22] = StaticICData target 'dart.core::print', arg-desc CP#21
+  [1] = Type #lib::callWithArgs::T1
+  [2] = Type #lib::callWithArgs::T2
+  [3] = Type #lib::callWithArgs::T3
+  [4] = Type #lib::callWithArgs::T4
+  [5] = Type #lib::callWithArgs::T5
+  [6] = Type #lib::callWithArgs::T6
+  [7] = Type #lib::callWithArgs::T7
+  [8] = Type #lib::callWithArgs::T8
+  [9] = ArgDesc num-args 2, num-type-args 0, names []
+  [10] = StaticICData target 'dart.core::List::_fromLiteral', arg-desc CP#9
+  [11] = ArgDesc num-args 1, num-type-args 0, names []
+  [12] = StaticICData target 'dart.core::print', arg-desc CP#11
 }
 ]static method callWithArgs<T1 extends core::Object = dynamic, T2 extends core::Object = dynamic, T3 extends core::Object = dynamic, T4 extends core::Object = dynamic, T5 extends core::Object = dynamic, T6 extends core::Object = dynamic, T7 extends core::Object = dynamic, T8 extends core::Object = dynamic>() → void {
   core::print(<core::Type>[self::callWithArgs::T1, self::callWithArgs::T2, self::callWithArgs::T3, self::callWithArgs::T4, self::callWithArgs::T5, self::callWithArgs::T6, self::callWithArgs::T7, self::callWithArgs::T8]);
@@ -1467,7 +1403,7 @@
   Drop1
   InstanceCall         2, CP#12
   Drop1
-  PushConstant         CP#13
+  PushNull
   ReturnTOS
 }
 ConstantPool {
@@ -1484,7 +1420,6 @@
   [10] = TypeArgumentsForInstanceAllocation #lib::A [dart.core::List<#lib::C1>, dart.core::List<#lib::C2>]
   [11] = StaticICData target '#lib::A::', arg-desc CP#3
   [12] = ICData target-name 'foo', arg-desc CP#5
-  [13] = Null
 }
 ]static method callA() → void {
   new self::A::•<self::C1, self::C2>().{self::A::foo}<self::C3, self::C4>();
@@ -1495,47 +1430,47 @@
 Bytecode {
   Entry                7
   CheckStack
-  Allocate             CP#17
+  Allocate             CP#14
   StoreLocal           r3
   Push                 r3
-  PushConstant         CP#12
-  StoreFieldTOS        CP#18
+  PushNull
+  StoreFieldTOS        CP#15
   Push                 r3
-  PushConstant         CP#12
+  PushNull
   StoreFieldTOS        CP#6
   Push                 r3
   PushConstant         CP#5
   StoreFieldTOS        CP#3
   Push                 r3
   PushConstant         CP#0
-  StoreFieldTOS        CP#20
+  StoreFieldTOS        CP#17
   Push                 r3
   Push                 r0
   StoreFieldTOS        CP#1
   PopLocal             r2
   Push                 r2
   StoreLocal           r3
-  PushConstant         CP#22
+  PushConstant         CP#19
   StoreLocal           r6
-  PushConstant         CP#24
-  IndirectStaticCall   2, CP#23
+  PushConstant         CP#21
+  IndirectStaticCall   2, CP#20
   Drop1
-  Allocate             CP#17
+  Allocate             CP#14
   StoreLocal           r5
   Push                 r6
   StoreFieldTOS        CP#3
   Push                 r5
   Push                 r3
-  LoadFieldTOS         CP#18
-  StoreFieldTOS        CP#18
+  LoadFieldTOS         CP#15
+  StoreFieldTOS        CP#15
   Push                 r5
   Push                 r3
   LoadFieldTOS         CP#6
   StoreFieldTOS        CP#6
   Push                 r5
   Push                 r3
-  LoadFieldTOS         CP#20
-  StoreFieldTOS        CP#20
+  LoadFieldTOS         CP#17
+  StoreFieldTOS        CP#17
   Push                 r5
   Push                 r3
   LoadFieldTOS         CP#1
@@ -1544,7 +1479,7 @@
   PopLocal             r4
   Push                 r4
   ReturnTOS
-  PushConstant         CP#12
+  PushNull
   ReturnTOS
 }
 ConstantPool {
@@ -1556,23 +1491,20 @@
   [5] = EmptyTypeArguments
   [6] = InstanceField dart.core::_Closure::_function_type_arguments
   [7] = Reserved
-  [8] = Int 0
-  [9] = Int 1
-  [10] = ArgDesc num-args 4, num-type-args 0, names []
-  [11] = StaticICData target 'dart._internal::_prependTypeArguments', arg-desc CP#10
-  [12] = Null
-  [13] = Type T
-  [14] = String 't'
-  [15] = SubtypeTestCache
-  [16] = EndClosureFunctionScope
-  [17] = Class dart.core::_Closure
-  [18] = InstanceField dart.core::_Closure::_instantiator_type_arguments
-  [19] = Reserved
-  [20] = InstanceField dart.core::_Closure::_function
-  [21] = Reserved
-  [22] = TypeArgs [dart.core::int]
-  [23] = ArgDesc num-args 2, num-type-args 0, names []
-  [24] = StaticICData target 'dart._internal::_boundsCheckForPartialInstantiation', arg-desc CP#23
+  [8] = ArgDesc num-args 4, num-type-args 0, names []
+  [9] = StaticICData target 'dart._internal::_prependTypeArguments', arg-desc CP#8
+  [10] = Type T
+  [11] = String 't'
+  [12] = SubtypeTestCache
+  [13] = EndClosureFunctionScope
+  [14] = Class dart.core::_Closure
+  [15] = InstanceField dart.core::_Closure::_instantiator_type_arguments
+  [16] = Reserved
+  [17] = InstanceField dart.core::_Closure::_function
+  [18] = Reserved
+  [19] = TypeArgs [dart.core::int]
+  [20] = ArgDesc num-args 2, num-type-args 0, names []
+  [21] = StaticICData target 'dart._internal::_boundsCheckForPartialInstantiation', arg-desc CP#20
 }
 Closure CP#0 {
   EntryFixed           2, 3
@@ -1594,19 +1526,19 @@
   Push                 r0
   Push                 FP[-6]
   LoadFieldTOS         CP#6
-  PushConstant         CP#8
+  PushInt              0
+  PushInt              1
   PushConstant         CP#9
-  PushConstant         CP#11
-  IndirectStaticCall   4, CP#10
+  IndirectStaticCall   4, CP#8
   PopLocal             r0
   Push                 FP[-5]
-  PushConstant         CP#12
+  PushNull
   Push                 r0
-  PushConstant         CP#13
-  PushConstant         CP#14
-  AssertAssignable     0, CP#15
+  PushConstant         CP#10
+  PushConstant         CP#11
+  AssertAssignable     0, CP#12
   Drop1
-  PushConstant         CP#12
+  PushNull
   ReturnTOS
 
 }
@@ -1619,10 +1551,9 @@
 Bytecode {
   Entry                0
   CheckStack
-  PushConstant         CP#0
+  PushNull
   ReturnTOS
 }
 ConstantPool {
-  [0] = Null
 }
 ]static method main() → dynamic {}
diff --git a/pkg/vm/testcases/bytecode/deferred_lib.dart.expect b/pkg/vm/testcases/bytecode/deferred_lib.dart.expect
index 8d4cb94..cf966e1 100644
--- a/pkg/vm/testcases/bytecode/deferred_lib.dart.expect
+++ b/pkg/vm/testcases/bytecode/deferred_lib.dart.expect
@@ -6,22 +6,21 @@
 Bytecode {
   Entry                1
   CheckStack
-  PushConstant         CP#0
-  PushConstant         CP#2
-  IndirectStaticCall   1, CP#1
+  PushNull
+  PushConstant         CP#1
+  IndirectStaticCall   1, CP#0
   PopLocal             r0
-  PushConstant         CP#4
-  IndirectStaticCall   0, CP#3
+  PushConstant         CP#3
+  IndirectStaticCall   0, CP#2
   ReturnTOS
-  PushConstant         CP#0
+  PushNull
   ReturnTOS
 }
 ConstantPool {
-  [0] = Null
-  [1] = ArgDesc num-args 1, num-type-args 0, names []
-  [2] = StaticICData target 'dart.async::Future::value', arg-desc CP#1
-  [3] = ArgDesc num-args 0, num-type-args 0, names []
-  [4] = StaticICData target '#lib1::main', arg-desc CP#3
+  [0] = ArgDesc num-args 1, num-type-args 0, names []
+  [1] = StaticICData target 'dart.async::Future::value', arg-desc CP#0
+  [2] = ArgDesc num-args 0, num-type-args 0, names []
+  [3] = StaticICData target '#lib1::main', arg-desc CP#2
 }
 ]static method callDeferred() → dynamic
   return let final dynamic #t1 = CheckLibraryIsLoaded(lib) in hel::main();
@@ -29,17 +28,16 @@
 Bytecode {
   Entry                0
   CheckStack
-  PushConstant         CP#0
-  PushConstant         CP#2
-  IndirectStaticCall   1, CP#1
+  PushNull
+  PushConstant         CP#1
+  IndirectStaticCall   1, CP#0
   ReturnTOS
-  PushConstant         CP#0
+  PushNull
   ReturnTOS
 }
 ConstantPool {
-  [0] = Null
-  [1] = ArgDesc num-args 1, num-type-args 0, names []
-  [2] = StaticICData target 'dart.async::Future::value', arg-desc CP#1
+  [0] = ArgDesc num-args 1, num-type-args 0, names []
+  [1] = StaticICData target 'dart.async::Future::value', arg-desc CP#0
 }
 ]static method testLoadLibrary() → dynamic
   return LoadLibrary(lib);
@@ -47,10 +45,9 @@
 Bytecode {
   Entry                0
   CheckStack
-  PushConstant         CP#0
+  PushNull
   ReturnTOS
 }
 ConstantPool {
-  [0] = Null
 }
 ]static method main() → dynamic {}
diff --git a/pkg/vm/testcases/bytecode/field_initializers.dart.expect b/pkg/vm/testcases/bytecode/field_initializers.dart.expect
index 5e795aa..5268d47 100644
--- a/pkg/vm/testcases/bytecode/field_initializers.dart.expect
+++ b/pkg/vm/testcases/bytecode/field_initializers.dart.expect
@@ -13,37 +13,33 @@
   Entry                0
   CheckStack
   Push                 FP[-6]
-  PushConstant         CP#0
-  StoreFieldTOS        CP#1
+  PushInt              42
+  StoreFieldTOS        CP#0
   Push                 FP[-6]
-  PushConstant         CP#3
-  StoreFieldTOS        CP#4
+  PushInt              43
+  StoreFieldTOS        CP#2
   Push                 FP[-6]
   Push                 FP[-5]
-  StoreFieldTOS        CP#6
-  Push                 FP[-6]
-  PushConstant         CP#8
   StoreFieldTOS        CP#4
   Push                 FP[-6]
-  PushConstant         CP#10
-  IndirectStaticCall   1, CP#9
+  PushInt              44
+  StoreFieldTOS        CP#2
+  Push                 FP[-6]
+  PushConstant         CP#7
+  IndirectStaticCall   1, CP#6
   Drop1
-  PushConstant         CP#11
+  PushNull
   ReturnTOS
 }
 ConstantPool {
-  [0] = Int 42
-  [1] = InstanceField #lib::A::foo3
-  [2] = Reserved
-  [3] = Int 43
-  [4] = InstanceField #lib::A::foo5
+  [0] = InstanceField #lib::A::foo3
+  [1] = Reserved
+  [2] = InstanceField #lib::A::foo5
+  [3] = Reserved
+  [4] = InstanceField #lib::A::foo4
   [5] = Reserved
-  [6] = InstanceField #lib::A::foo4
-  [7] = Reserved
-  [8] = Int 44
-  [9] = ArgDesc num-args 1, num-type-args 0, names []
-  [10] = StaticICData target 'dart.core::Object::', arg-desc CP#9
-  [11] = Null
+  [6] = ArgDesc num-args 1, num-type-args 0, names []
+  [7] = StaticICData target 'dart.core::Object::', arg-desc CP#6
 }
 ]  constructor •(core::int foo4) → void
     : self::A::foo1 = null, self::A::foo4 = foo4, self::A::foo5 = 44, super core::Object::•()
@@ -53,41 +49,37 @@
   Entry                0
   CheckStack
   Push                 FP[-7]
-  PushConstant         CP#0
-  StoreFieldTOS        CP#1
+  PushInt              42
+  StoreFieldTOS        CP#0
   Push                 FP[-7]
-  PushConstant         CP#3
-  StoreFieldTOS        CP#4
+  PushInt              43
+  StoreFieldTOS        CP#2
   Push                 FP[-7]
   Push                 FP[-6]
-  StoreFieldTOS        CP#6
-  Push                 FP[-7]
-  Push                 FP[-5]
-  PushConstant         CP#8
-  InstanceCall         2, CP#10
   StoreFieldTOS        CP#4
   Push                 FP[-7]
-  PushConstant         CP#12
-  IndirectStaticCall   1, CP#11
+  Push                 FP[-5]
+  PushInt              1
+  InstanceCall         2, CP#7
+  StoreFieldTOS        CP#2
+  Push                 FP[-7]
+  PushConstant         CP#9
+  IndirectStaticCall   1, CP#8
   Drop1
-  PushConstant         CP#13
+  PushNull
   ReturnTOS
 }
 ConstantPool {
-  [0] = Int 42
-  [1] = InstanceField #lib::A::foo3
-  [2] = Reserved
-  [3] = Int 43
-  [4] = InstanceField #lib::A::foo5
+  [0] = InstanceField #lib::A::foo3
+  [1] = Reserved
+  [2] = InstanceField #lib::A::foo5
+  [3] = Reserved
+  [4] = InstanceField #lib::A::foo1
   [5] = Reserved
-  [6] = InstanceField #lib::A::foo1
-  [7] = Reserved
-  [8] = Int 1
-  [9] = ArgDesc num-args 2, num-type-args 0, names []
-  [10] = ICData target-name '+', arg-desc CP#9
-  [11] = ArgDesc num-args 1, num-type-args 0, names []
-  [12] = StaticICData target 'dart.core::Object::', arg-desc CP#11
-  [13] = Null
+  [6] = ArgDesc num-args 2, num-type-args 0, names []
+  [7] = ICData target-name '+', arg-desc CP#6
+  [8] = ArgDesc num-args 1, num-type-args 0, names []
+  [9] = StaticICData target 'dart.core::Object::', arg-desc CP#8
 }
 ]  constructor constr2(core::int x, core::int y) → void
     : self::A::foo4 = null, self::A::foo1 = x, self::A::foo5 = y.{core::num::+}(1), super core::Object::•()
@@ -97,18 +89,16 @@
   Entry                0
   CheckStack
   Push                 FP[-5]
-  PushConstant         CP#0
-  PushConstant         CP#2
-  IndirectStaticCall   2, CP#1
+  PushInt              45
+  PushConstant         CP#1
+  IndirectStaticCall   2, CP#0
   Drop1
-  PushConstant         CP#3
+  PushNull
   ReturnTOS
 }
 ConstantPool {
-  [0] = Int 45
-  [1] = ArgDesc num-args 2, num-type-args 0, names []
-  [2] = StaticICData target '#lib::A::', arg-desc CP#1
-  [3] = Null
+  [0] = ArgDesc num-args 2, num-type-args 0, names []
+  [1] = StaticICData target '#lib::A::', arg-desc CP#0
 }
 ]  constructor redirecting1() → void
     : this self::A::•(45)
@@ -125,7 +115,7 @@
   PushConstant         CP#3
   IndirectStaticCall   3, CP#2
   Drop1
-  PushConstant         CP#4
+  PushNull
   ReturnTOS
 }
 ConstantPool {
@@ -133,7 +123,6 @@
   [1] = ICData target-name '*', arg-desc CP#0
   [2] = ArgDesc num-args 3, num-type-args 0, names []
   [3] = StaticICData target '#lib::A::constr2', arg-desc CP#2
-  [4] = Null
 }
 ]  constructor redirecting2(core::int a, core::int b, core::int c) → void
     : this self::A::constr2(a, b.{core::num::*}(c))
@@ -148,24 +137,21 @@
   Entry                0
   CheckStack
   Push                 FP[-5]
-  PushConstant         CP#0
-  StoreFieldTOS        CP#1
+  PushInt              46
+  StoreFieldTOS        CP#0
   Push                 FP[-5]
+  PushInt              49
   PushConstant         CP#3
-  PushConstant         CP#5
-  IndirectStaticCall   2, CP#4
+  IndirectStaticCall   2, CP#2
   Drop1
-  PushConstant         CP#6
+  PushNull
   ReturnTOS
 }
 ConstantPool {
-  [0] = Int 46
-  [1] = InstanceField #lib::B::foo6
-  [2] = Reserved
-  [3] = Int 49
-  [4] = ArgDesc num-args 2, num-type-args 0, names []
-  [5] = StaticICData target '#lib::A::', arg-desc CP#4
-  [6] = Null
+  [0] = InstanceField #lib::B::foo6
+  [1] = Reserved
+  [2] = ArgDesc num-args 2, num-type-args 0, names []
+  [3] = StaticICData target '#lib::A::', arg-desc CP#2
 }
 ]  constructor •() → void
     : super self::A::•(49)
@@ -175,30 +161,26 @@
   Entry                0
   CheckStack
   Push                 FP[-7]
-  PushConstant         CP#0
-  StoreFieldTOS        CP#1
+  PushInt              46
+  StoreFieldTOS        CP#0
   Push                 FP[-7]
-  PushConstant         CP#3
-  StoreFieldTOS        CP#1
+  PushInt              50
+  StoreFieldTOS        CP#0
   Push                 FP[-7]
   Push                 FP[-6]
   Push                 FP[-5]
-  PushConstant         CP#4
-  PushConstant         CP#6
-  IndirectStaticCall   4, CP#5
+  PushInt              51
+  PushConstant         CP#3
+  IndirectStaticCall   4, CP#2
   Drop1
-  PushConstant         CP#7
+  PushNull
   ReturnTOS
 }
 ConstantPool {
-  [0] = Int 46
-  [1] = InstanceField #lib::B::foo6
-  [2] = Reserved
-  [3] = Int 50
-  [4] = Int 51
-  [5] = ArgDesc num-args 4, num-type-args 0, names []
-  [6] = StaticICData target '#lib::A::redirecting2', arg-desc CP#5
-  [7] = Null
+  [0] = InstanceField #lib::B::foo6
+  [1] = Reserved
+  [2] = ArgDesc num-args 4, num-type-args 0, names []
+  [3] = StaticICData target '#lib::A::redirecting2', arg-desc CP#2
 }
 ]  constructor c2(core::int i, core::int j) → void
     : self::B::foo6 = 50, super self::A::redirecting2(i, j, 51)
@@ -208,10 +190,9 @@
 Bytecode {
   Entry                0
   CheckStack
-  PushConstant         CP#0
+  PushNull
   ReturnTOS
 }
 ConstantPool {
-  [0] = Null
 }
 ]static method main() → dynamic {}
diff --git a/pkg/vm/testcases/bytecode/hello.dart.expect b/pkg/vm/testcases/bytecode/hello.dart.expect
index 7147dbc..b9c0903 100644
--- a/pkg/vm/testcases/bytecode/hello.dart.expect
+++ b/pkg/vm/testcases/bytecode/hello.dart.expect
@@ -10,14 +10,13 @@
   PushConstant         CP#2
   IndirectStaticCall   1, CP#1
   Drop1
-  PushConstant         CP#3
+  PushNull
   ReturnTOS
 }
 ConstantPool {
   [0] = String 'Hello, Dart Bytecode!'
   [1] = ArgDesc num-args 1, num-type-args 0, names []
   [2] = StaticICData target 'dart.core::print', arg-desc CP#1
-  [3] = Null
 }
 ]static method main() → dynamic {
   core::print("Hello, Dart Bytecode!");
diff --git a/pkg/vm/testcases/bytecode/instance_creation.dart.expect b/pkg/vm/testcases/bytecode/instance_creation.dart.expect
index be1eedc..127251d 100644
--- a/pkg/vm/testcases/bytecode/instance_creation.dart.expect
+++ b/pkg/vm/testcases/bytecode/instance_creation.dart.expect
@@ -14,56 +14,50 @@
   PushConstant         CP#1
   IndirectStaticCall   1, CP#0
   Drop1
-  PushConstant         CP#2
-  PushConstant         CP#3
+  PushNull
+  PushInt              4
   CreateArrayTOS
   StoreLocal           r0
   Push                 r0
-  PushConstant         CP#4
+  PushInt              0
+  PushConstant         CP#2
+  StoreIndexedTOS
+  Push                 r0
+  PushInt              1
+  Push                 FP[-5]
+  LoadTypeArgumentsField CP#4
+  PushNull
+  InstantiateType      CP#3
+  StoreIndexedTOS
+  Push                 r0
+  PushInt              2
   PushConstant         CP#5
   StoreIndexedTOS
   Push                 r0
-  PushConstant         CP#6
+  PushInt              3
   Push                 FP[-5]
-  LoadTypeArgumentsField CP#8
-  PushConstant         CP#2
-  InstantiateType      CP#7
+  LoadTypeArgumentsField CP#4
+  PushNull
+  InstantiateType      CP#6
   StoreIndexedTOS
-  Push                 r0
-  PushConstant         CP#9
-  PushConstant         CP#10
-  StoreIndexedTOS
-  Push                 r0
-  PushConstant         CP#11
-  Push                 FP[-5]
-  LoadTypeArgumentsField CP#8
-  PushConstant         CP#2
-  InstantiateType      CP#12
-  StoreIndexedTOS
-  PushConstant         CP#13
+  PushConstant         CP#7
   IndirectStaticCall   1, CP#0
-  PushConstant         CP#14
+  PushConstant         CP#8
   IndirectStaticCall   1, CP#0
   Drop1
-  PushConstant         CP#2
+  PushNull
   ReturnTOS
 }
 ConstantPool {
   [0] = ArgDesc num-args 1, num-type-args 0, names []
   [1] = StaticICData target 'dart.core::Object::', arg-desc CP#0
-  [2] = Null
-  [3] = Int 4
-  [4] = Int 0
-  [5] = String 'Base: '
-  [6] = Int 1
-  [7] = Type #lib::Base::T1
-  [8] = TypeArgumentsField #lib::Base
-  [9] = Int 2
-  [10] = String ', '
-  [11] = Int 3
-  [12] = Type #lib::Base::T2
-  [13] = StaticICData target 'dart.core::_StringBase::_interpolate', arg-desc CP#0
-  [14] = StaticICData target 'dart.core::print', arg-desc CP#0
+  [2] = String 'Base: '
+  [3] = Type #lib::Base::T1
+  [4] = TypeArgumentsField #lib::Base
+  [5] = String ', '
+  [6] = Type #lib::Base::T2
+  [7] = StaticICData target 'dart.core::_StringBase::_interpolate', arg-desc CP#0
+  [8] = StaticICData target 'dart.core::print', arg-desc CP#0
 }
 ]  constructor •() → void
     : super core::Object::•() {
@@ -79,13 +73,12 @@
   PushConstant         CP#1
   IndirectStaticCall   1, CP#0
   Drop1
-  PushConstant         CP#2
+  PushNull
   ReturnTOS
 }
 ConstantPool {
   [0] = ArgDesc num-args 1, num-type-args 0, names []
   [1] = StaticICData target '#lib::Base::', arg-desc CP#0
-  [2] = Null
 }
 ]  constructor •(core::String s) → void
     : super self::Base::•()
@@ -100,41 +93,37 @@
   PushConstant         CP#1
   IndirectStaticCall   1, CP#0
   Drop1
-  PushConstant         CP#2
-  PushConstant         CP#3
+  PushNull
+  PushInt              2
   CreateArrayTOS
   StoreLocal           r0
   Push                 r0
-  PushConstant         CP#4
-  PushConstant         CP#5
+  PushInt              0
+  PushConstant         CP#2
   StoreIndexedTOS
   Push                 r0
-  PushConstant         CP#6
+  PushInt              1
   Push                 FP[-5]
-  LoadTypeArgumentsField CP#8
-  PushConstant         CP#2
-  InstantiateType      CP#7
+  LoadTypeArgumentsField CP#4
+  PushNull
+  InstantiateType      CP#3
   StoreIndexedTOS
-  PushConstant         CP#9
+  PushConstant         CP#5
   IndirectStaticCall   1, CP#0
-  PushConstant         CP#10
+  PushConstant         CP#6
   IndirectStaticCall   1, CP#0
   Drop1
-  PushConstant         CP#2
+  PushNull
   ReturnTOS
 }
 ConstantPool {
   [0] = ArgDesc num-args 1, num-type-args 0, names []
   [1] = StaticICData target '#lib::Base::', arg-desc CP#0
-  [2] = Null
-  [3] = Int 2
-  [4] = Int 0
-  [5] = String 'B: '
-  [6] = Int 1
-  [7] = Type #lib::B::T
-  [8] = TypeArgumentsField #lib::B
-  [9] = StaticICData target 'dart.core::_StringBase::_interpolate', arg-desc CP#0
-  [10] = StaticICData target 'dart.core::print', arg-desc CP#0
+  [2] = String 'B: '
+  [3] = Type #lib::B::T
+  [4] = TypeArgumentsField #lib::B
+  [5] = StaticICData target 'dart.core::_StringBase::_interpolate', arg-desc CP#0
+  [6] = StaticICData target 'dart.core::print', arg-desc CP#0
 }
 ]  constructor •() → void
     : super self::Base::•() {
@@ -150,36 +139,32 @@
   PushConstant         CP#1
   IndirectStaticCall   1, CP#0
   Drop1
-  PushConstant         CP#2
-  PushConstant         CP#3
+  PushNull
+  PushInt              2
   CreateArrayTOS
   StoreLocal           r0
   Push                 r0
-  PushConstant         CP#4
-  PushConstant         CP#5
+  PushInt              0
+  PushConstant         CP#2
   StoreIndexedTOS
   Push                 r0
-  PushConstant         CP#6
+  PushInt              1
   Push                 FP[-5]
   StoreIndexedTOS
-  PushConstant         CP#7
+  PushConstant         CP#3
   IndirectStaticCall   1, CP#0
-  PushConstant         CP#8
+  PushConstant         CP#4
   IndirectStaticCall   1, CP#0
   Drop1
-  PushConstant         CP#2
+  PushNull
   ReturnTOS
 }
 ConstantPool {
   [0] = ArgDesc num-args 1, num-type-args 0, names []
   [1] = StaticICData target 'dart.core::Object::', arg-desc CP#0
-  [2] = Null
-  [3] = Int 2
-  [4] = Int 0
-  [5] = String 'C: '
-  [6] = Int 1
-  [7] = StaticICData target 'dart.core::_StringBase::_interpolate', arg-desc CP#0
-  [8] = StaticICData target 'dart.core::print', arg-desc CP#0
+  [2] = String 'C: '
+  [3] = StaticICData target 'dart.core::_StringBase::_interpolate', arg-desc CP#0
+  [4] = StaticICData target 'dart.core::print', arg-desc CP#0
 }
 ]  constructor •(core::String s) → void
     : super core::Object::•() {
@@ -195,13 +180,12 @@
   PushConstant         CP#1
   IndirectStaticCall   1, CP#0
   Drop1
-  PushConstant         CP#2
+  PushNull
   ReturnTOS
 }
 ConstantPool {
   [0] = ArgDesc num-args 1, num-type-args 0, names []
   [1] = StaticICData target 'dart.core::Object::', arg-desc CP#0
-  [2] = Null
 }
 ]  synthetic constructor •() → void
     : super core::Object::•()
@@ -215,14 +199,13 @@
   PushConstant         CP#2
   IndirectStaticCall   1, CP#1
   ReturnTOS
-  PushConstant         CP#3
+  PushNull
   ReturnTOS
 }
 ConstantPool {
   [0] = TypeArgumentsField #lib::E
   [1] = ArgDesc num-args 1, num-type-args 0, names []
   [2] = StaticICData target 'dart.core::Map::', arg-desc CP#1
-  [3] = Null
 }
 ]  method test_reuse1() → dynamic
     return core::Map::•<self::E::K, self::E::V>();
@@ -236,13 +219,12 @@
   PushConstant         CP#1
   IndirectStaticCall   1, CP#0
   Drop1
-  PushConstant         CP#2
+  PushNull
   ReturnTOS
 }
 ConstantPool {
   [0] = ArgDesc num-args 1, num-type-args 0, names []
   [1] = StaticICData target '#lib::E::', arg-desc CP#0
-  [2] = Null
 }
 ]  synthetic constructor •() → void
     : super self::E::•()
@@ -256,14 +238,13 @@
   PushConstant         CP#2
   IndirectStaticCall   1, CP#1
   ReturnTOS
-  PushConstant         CP#3
+  PushNull
   ReturnTOS
 }
 ConstantPool {
   [0] = TypeArgumentsField #lib::F
   [1] = ArgDesc num-args 1, num-type-args 0, names []
   [2] = StaticICData target 'dart.core::Map::', arg-desc CP#1
-  [3] = Null
 }
 ]  method test_reuse2() → dynamic
     return core::Map::•<core::String, core::List<self::F::V>>();
@@ -277,13 +258,12 @@
   PushConstant         CP#1
   IndirectStaticCall   1, CP#0
   Drop1
-  PushConstant         CP#2
+  PushNull
   ReturnTOS
 }
 ConstantPool {
   [0] = ArgDesc num-args 1, num-type-args 0, names []
   [1] = StaticICData target 'dart.core::Object::', arg-desc CP#0
-  [2] = Null
 }
 ]  constructor •() → void
     : super core::Object::•()
@@ -293,25 +273,24 @@
   Entry                1
   CheckStack
   Push                 FP[-5]
-  PushConstant         CP#1
-  InstantiateTypeArgumentsTOS 0, CP#2
+  PushNull
+  InstantiateTypeArgumentsTOS 0, CP#1
   PushConstant         CP#0
   AllocateT
   StoreLocal           r0
   Push                 r0
-  PushConstant         CP#4
-  IndirectStaticCall   1, CP#3
+  PushConstant         CP#3
+  IndirectStaticCall   1, CP#2
   Drop1
   ReturnTOS
-  PushConstant         CP#1
+  PushNull
   ReturnTOS
 }
 ConstantPool {
   [0] = Class #lib::H
-  [1] = Null
-  [2] = TypeArgumentsForInstanceAllocation #lib::H [dart.core::String, #lib::G::test_factory::K, #lib::G::test_factory::V]
-  [3] = ArgDesc num-args 1, num-type-args 0, names []
-  [4] = StaticICData target '#lib::H::', arg-desc CP#3
+  [1] = TypeArgumentsForInstanceAllocation #lib::H [dart.core::String, #lib::G::test_factory::K, #lib::G::test_factory::V]
+  [2] = ArgDesc num-args 1, num-type-args 0, names []
+  [3] = StaticICData target '#lib::H::', arg-desc CP#2
 }
 ]  static factory test_factory<K extends core::Object = dynamic, V extends core::Object = dynamic>() → self::G<self::G::test_factory::K, self::G::test_factory::V>
     return new self::H::•<core::String, self::G::test_factory::K, self::G::test_factory::V>();
@@ -325,13 +304,12 @@
   PushConstant         CP#1
   IndirectStaticCall   1, CP#0
   Drop1
-  PushConstant         CP#2
+  PushNull
   ReturnTOS
 }
 ConstantPool {
   [0] = ArgDesc num-args 1, num-type-args 0, names []
   [1] = StaticICData target '#lib::G::', arg-desc CP#0
-  [2] = Null
 }
 ]  synthetic constructor •() → void
     : super self::G::•()
@@ -346,13 +324,12 @@
   PushConstant         CP#1
   IndirectStaticCall   1, CP#0
   Drop1
-  PushConstant         CP#2
+  PushNull
   ReturnTOS
 }
 ConstantPool {
   [0] = ArgDesc num-args 1, num-type-args 0, names []
   [1] = StaticICData target 'dart.core::Object::', arg-desc CP#0
-  [2] = Null
 }
 ]  constructor •(dynamic param) → void
     : super core::Object::•()
@@ -372,7 +349,7 @@
   IndirectStaticCall   2, CP#3
   Drop1
   ReturnTOS
-  PushConstant         CP#1
+  PushNull
   ReturnTOS
 }
 ConstantPool {
@@ -414,14 +391,13 @@
   IndirectStaticCall   1, CP#1
   Drop1
   ReturnTOS
-  PushConstant         CP#3
+  PushNull
   ReturnTOS
 }
 ConstantPool {
   [0] = Class #lib::TestTypeArgReuse
   [1] = ArgDesc num-args 1, num-type-args 0, names []
   [2] = StaticICData target '#lib::TestTypeArgReuse::', arg-desc CP#1
-  [3] = Null
 }
 ]  static factory •<A extends core::Object = dynamic, B extends core::Object = dynamic>() → self::K<self::K::•::A, self::K::•::B>
     return new self::TestTypeArgReuse::•<self::K::•::A, self::K::•::B>();
@@ -435,13 +411,12 @@
   PushConstant         CP#1
   IndirectStaticCall   1, CP#0
   Drop1
-  PushConstant         CP#2
+  PushNull
   ReturnTOS
 }
 ConstantPool {
   [0] = ArgDesc num-args 1, num-type-args 0, names []
   [1] = StaticICData target '#lib::Base::', arg-desc CP#0
-  [2] = Null
 }
 ]  synthetic constructor •() → void
     : super self::Base::•()
@@ -459,7 +434,7 @@
   IndirectStaticCall   2, CP#2
   Drop1
   ReturnTOS
-  PushConstant         CP#4
+  PushNull
   ReturnTOS
 }
 ConstantPool {
@@ -467,7 +442,6 @@
   [1] = String 'hello'
   [2] = ArgDesc num-args 2, num-type-args 0, names []
   [3] = StaticICData target '#lib::C::', arg-desc CP#2
-  [4] = Null
 }
 ]static method foo1() → dynamic
   return new self::C::•("hello");
@@ -494,7 +468,7 @@
   IndirectStaticCall   1, CP#7
   Drop1
   Drop1
-  PushConstant         CP#9
+  PushNull
   ReturnTOS
 }
 ConstantPool {
@@ -507,7 +481,6 @@
   [6] = TypeArgumentsForInstanceAllocation #lib::B [dart.core::int]
   [7] = ArgDesc num-args 1, num-type-args 0, names []
   [8] = StaticICData target '#lib::B::', arg-desc CP#7
-  [9] = Null
 }
 ]static method foo2() → void {
   new self::A::•("hi");
@@ -518,26 +491,25 @@
   Entry                2
   CheckStack
   CheckFunctionTypeArgs 1, 0
-  PushConstant         CP#1
+  PushNull
   Push                 r0
-  InstantiateTypeArgumentsTOS 0, CP#2
+  InstantiateTypeArgumentsTOS 0, CP#1
   PushConstant         CP#0
   AllocateT
   StoreLocal           r1
   Push                 r1
-  PushConstant         CP#4
-  IndirectStaticCall   1, CP#3
+  PushConstant         CP#3
+  IndirectStaticCall   1, CP#2
   Drop1
   Drop1
-  PushConstant         CP#1
+  PushNull
   ReturnTOS
 }
 ConstantPool {
   [0] = Class #lib::B
-  [1] = Null
-  [2] = TypeArgumentsForInstanceAllocation #lib::B [dart.core::List<#lib::foo3::T>]
-  [3] = ArgDesc num-args 1, num-type-args 0, names []
-  [4] = StaticICData target '#lib::B::', arg-desc CP#3
+  [1] = TypeArgumentsForInstanceAllocation #lib::B [dart.core::List<#lib::foo3::T>]
+  [2] = ArgDesc num-args 1, num-type-args 0, names []
+  [3] = StaticICData target '#lib::B::', arg-desc CP#2
 }
 ]static method foo3<T extends core::Object = dynamic>() → void {
   new self::B::•<core::List<self::foo3::T>>();
@@ -550,14 +522,13 @@
   PushConstant         CP#2
   IndirectStaticCall   1, CP#1
   Drop1
-  PushConstant         CP#3
+  PushNull
   ReturnTOS
 }
 ConstantPool {
   [0] = TypeArgumentsForInstanceAllocation #lib::G [dart.core::int, dart.core::List<dart.core::String>]
   [1] = ArgDesc num-args 1, num-type-args 0, names []
   [2] = StaticICData target '#lib::G::test_factory', arg-desc CP#1
-  [3] = Null
 }
 ]static method foo4() → void {
   self::G::test_factory<core::int, core::List<core::String>>();
@@ -566,25 +537,23 @@
 Bytecode {
   Entry                0
   CheckStack
-  PushConstant         CP#0
-  PushConstant         CP#2
-  IndirectStaticCall   1, CP#1
+  PushNull
+  PushConstant         CP#1
+  IndirectStaticCall   1, CP#0
   Drop1
-  PushConstant         CP#0
+  PushNull
+  PushInt              42
   PushConstant         CP#3
-  PushConstant         CP#5
-  IndirectStaticCall   2, CP#4
+  IndirectStaticCall   2, CP#2
   Drop1
-  PushConstant         CP#0
+  PushNull
   ReturnTOS
 }
 ConstantPool {
-  [0] = Null
-  [1] = ArgDesc num-args 1, num-type-args 0, names []
-  [2] = StaticICData target '#lib::I::test_factory2', arg-desc CP#1
-  [3] = Int 42
-  [4] = ArgDesc num-args 2, num-type-args 0, names [param]
-  [5] = StaticICData target '#lib::I::test_factory2', arg-desc CP#4
+  [0] = ArgDesc num-args 1, num-type-args 0, names []
+  [1] = StaticICData target '#lib::I::test_factory2', arg-desc CP#0
+  [2] = ArgDesc num-args 2, num-type-args 0, names [param]
+  [3] = StaticICData target '#lib::I::test_factory2', arg-desc CP#2
 }
 ]static method foo5() → void {
   self::I::test_factory2();
@@ -604,7 +573,7 @@
   PushConstant         CP#5
   IndirectStaticCall   1, CP#4
   Drop1
-  PushConstant         CP#6
+  PushNull
   ReturnTOS
 }
 ConstantPool {
@@ -614,7 +583,6 @@
   [3] = TypeArgs [dart.core::String]
   [4] = ArgDesc num-args 0, num-type-args 1, names []
   [5] = StaticICData target '#lib::foo3', arg-desc CP#4
-  [6] = Null
 }
 ]static method main() → dynamic {
   self::foo1();
diff --git a/pkg/vm/testcases/bytecode/literals.dart b/pkg/vm/testcases/bytecode/literals.dart
index a1266ed..c4c3ea8 100644
--- a/pkg/vm/testcases/bytecode/literals.dart
+++ b/pkg/vm/testcases/bytecode/literals.dart
@@ -65,6 +65,7 @@
 
 void test_symbol() {
   print(#test_symbol);
+  print(#_private_symbol);
 }
 
 void test_type_literal<T>() {
diff --git a/pkg/vm/testcases/bytecode/literals.dart.expect b/pkg/vm/testcases/bytecode/literals.dart.expect
index 1e7fbae..be1bb2e 100644
--- a/pkg/vm/testcases/bytecode/literals.dart.expect
+++ b/pkg/vm/testcases/bytecode/literals.dart.expect
@@ -100,7 +100,7 @@
   PushConstant         CP#5
   IndirectStaticCall   1, CP#4
   Drop1
-  PushConstant         CP#6
+  PushNull
   ReturnTOS
 }
 ConstantPool {
@@ -110,7 +110,6 @@
   [3] = Reserved
   [4] = ArgDesc num-args 1, num-type-args 0, names []
   [5] = StaticICData target 'dart.core::Object::', arg-desc CP#4
-  [6] = Null
 }
 ]  const constructor •(core::int index, core::String _name) → void
     : self::A::index = index, self::A::_name = _name, super core::Object::•()
@@ -123,13 +122,12 @@
   PushConstant         CP#1
   IndirectStaticCall   1, CP#0
   ReturnTOS
-  PushConstant         CP#2
+  PushNull
   ReturnTOS
 }
 ConstantPool {
   [0] = ArgDesc num-args 1, num-type-args 0, names []
   [1] = StaticICData get target '#lib::A::_name', arg-desc CP#0
-  [2] = Null
 }
 ]  method toString() → core::String
     return this.{=self::A::_name};
@@ -147,7 +145,7 @@
   PushConstant         CP#3
   IndirectStaticCall   1, CP#2
   Drop1
-  PushConstant         CP#4
+  PushNull
   ReturnTOS
 }
 ConstantPool {
@@ -155,7 +153,6 @@
   [1] = Reserved
   [2] = ArgDesc num-args 1, num-type-args 0, names []
   [3] = StaticICData target 'dart.core::Object::', arg-desc CP#2
-  [4] = Null
 }
 ]  const constructor •(core::int i) → void
     : self::B::i = i, super core::Object::•()
@@ -174,12 +171,12 @@
   StoreFieldTOS        CP#2
   Push                 FP[-8]
   Push                 FP[-5]
-  PushConstant         CP#4
-  InstanceCall         2, CP#5
-  PushConstant         CP#6
+  PushInt              5
+  InstanceCall         2, CP#4
+  PushConstant         CP#5
   IndirectStaticCall   2, CP#0
   Drop1
-  PushConstant         CP#7
+  PushNull
   ReturnTOS
 }
 ConstantPool {
@@ -187,10 +184,8 @@
   [1] = ICData target-name '+', arg-desc CP#0
   [2] = InstanceField #lib::C::j
   [3] = Reserved
-  [4] = Int 5
-  [5] = ICData target-name '*', arg-desc CP#0
-  [6] = StaticICData target '#lib::B::', arg-desc CP#0
-  [7] = Null
+  [4] = ICData target-name '*', arg-desc CP#0
+  [5] = StaticICData target '#lib::B::', arg-desc CP#0
 }
 ]  const constructor •(core::int a, core::int b, core::int c) → void
     : self::C::j = a.{core::num::+}(b), super self::B::•(c.{core::num::*}(5))
@@ -215,7 +210,7 @@
   PushConstant         CP#6
   IndirectStaticCall   1, CP#5
   Drop1
-  PushConstant         CP#0
+  PushNull
   ReturnTOS
 }
 ConstantPool {
@@ -240,13 +235,12 @@
   PushConstant         CP#1
   IndirectStaticCall   1, CP#0
   Drop1
-  PushConstant         CP#2
+  PushNull
   ReturnTOS
 }
 ConstantPool {
   [0] = ArgDesc num-args 1, num-type-args 0, names []
   [1] = StaticICData target 'dart.core::Object::', arg-desc CP#0
-  [2] = Null
 }
 ]  const constructor •() → void
     : super core::Object::•()
@@ -261,13 +255,12 @@
   PushConstant         CP#1
   IndirectStaticCall   1, CP#0
   Drop1
-  PushConstant         CP#2
+  PushNull
   ReturnTOS
 }
 ConstantPool {
   [0] = ArgDesc num-args 1, num-type-args 0, names []
   [1] = StaticICData target '#lib::E::', arg-desc CP#0
-  [2] = Null
 }
 ]  const constructor •() → void
     : super self::E::•()
@@ -292,11 +285,10 @@
 Bytecode {
   Entry                0
   CheckStack
-  PushConstant         CP#0
+  PushInt              6
   ReturnTOS
 }
 ConstantPool {
-  [0] = Int 6
 }
 ]static const field core::int c3 = self::c2.{core::String::length};
 [@vm.bytecode=
@@ -340,19 +332,19 @@
   PushConstant         CP#7
   IndirectStaticCall   1, CP#4
   Drop1
+  PushInt              6
   PushConstant         CP#8
-  PushConstant         CP#9
   IndirectStaticCall   1, CP#4
   Drop1
+  PushConstant         CP#11
   PushConstant         CP#12
-  PushConstant         CP#13
   IndirectStaticCall   1, CP#4
   Drop1
+  PushConstant         CP#15
   PushConstant         CP#16
-  PushConstant         CP#17
   IndirectStaticCall   1, CP#4
   Drop1
-  PushConstant         CP#0
+  PushNull
   ReturnTOS
 }
 ConstantPool {
@@ -364,16 +356,15 @@
   [5] = StaticICData target 'dart.core::print', arg-desc CP#4
   [6] = String 'hello!'
   [7] = StaticICData target 'dart.core::print', arg-desc CP#4
-  [8] = Int 6
-  [9] = StaticICData target 'dart.core::print', arg-desc CP#4
-  [10] = Int 3
-  [11] = Int 15
-  [12] = Instance #lib::C type-args CP#0 {j: CP#10, i: CP#11}
-  [13] = StaticICData target 'dart.core::print', arg-desc CP#4
-  [14] = Int 4
-  [15] = Instance #lib::B type-args CP#0 {i: CP#14}
-  [16] = Instance #lib::D type-args CP#0 {x: CP#15, y: CP#0}
-  [17] = StaticICData target 'dart.core::print', arg-desc CP#4
+  [8] = StaticICData target 'dart.core::print', arg-desc CP#4
+  [9] = Int 3
+  [10] = Int 15
+  [11] = Instance #lib::C type-args CP#0 {j: CP#9, i: CP#10}
+  [12] = StaticICData target 'dart.core::print', arg-desc CP#4
+  [13] = Int 4
+  [14] = Instance #lib::B type-args CP#0 {i: CP#13}
+  [15] = Instance #lib::D type-args CP#0 {x: CP#14, y: CP#0}
+  [16] = StaticICData target 'dart.core::print', arg-desc CP#4
 }
 ]static method test_constants1() → void {
   core::print(self::c1);
@@ -386,67 +377,67 @@
 Bytecode {
   Entry                0
   CheckStack
-  PushConstant         CP#0
+  PushInt              42
+  PushConstant         CP#1
+  IndirectStaticCall   1, CP#0
+  Drop1
   PushConstant         CP#2
-  IndirectStaticCall   1, CP#1
-  Drop1
   PushConstant         CP#3
-  PushConstant         CP#4
-  IndirectStaticCall   1, CP#1
+  IndirectStaticCall   1, CP#0
   Drop1
+  PushConstant         CP#7
   PushConstant         CP#8
-  PushConstant         CP#9
-  IndirectStaticCall   1, CP#1
+  IndirectStaticCall   1, CP#0
   Drop1
   PushConstant         CP#11
   PushConstant         CP#12
-  IndirectStaticCall   1, CP#1
+  IndirectStaticCall   1, CP#0
   Drop1
   PushConstant         CP#20
   PushConstant         CP#21
-  IndirectStaticCall   1, CP#1
+  IndirectStaticCall   1, CP#0
   Drop1
   PushConstant         CP#31
   PushConstant         CP#32
-  IndirectStaticCall   1, CP#1
+  IndirectStaticCall   1, CP#0
   Drop1
-  PushConstant         CP#5
+  PushNull
   ReturnTOS
 }
 ConstantPool {
-  [0] = Int 42
-  [1] = ArgDesc num-args 1, num-type-args 0, names []
-  [2] = StaticICData target 'dart.core::print', arg-desc CP#1
-  [3] = String 'foo'
-  [4] = StaticICData target 'dart.core::print', arg-desc CP#1
-  [5] = Null
-  [6] = Int 1
-  [7] = String 'A.elem2'
-  [8] = Instance #lib::A type-args CP#5 {index: CP#6, _name: CP#7}
-  [9] = StaticICData target 'dart.core::print', arg-desc CP#1
+  [0] = ArgDesc num-args 1, num-type-args 0, names []
+  [1] = StaticICData target 'dart.core::print', arg-desc CP#0
+  [2] = String 'foo'
+  [3] = StaticICData target 'dart.core::print', arg-desc CP#0
+  [4] = Null
+  [5] = Int 1
+  [6] = String 'A.elem2'
+  [7] = Instance #lib::A type-args CP#4 {index: CP#5, _name: CP#6}
+  [8] = StaticICData target 'dart.core::print', arg-desc CP#0
+  [9] = Int 42
   [10] = Type dart.core::int
-  [11] = List type-arg dart.core::Object, entries CP# [0, 3, 10]
-  [12] = StaticICData target 'dart.core::print', arg-desc CP#1
+  [11] = List type-arg dart.core::Object, entries CP# [9, 2, 10]
+  [12] = StaticICData target 'dart.core::print', arg-desc CP#0
   [13] = TypeArgumentsForInstanceAllocation dart.core::_ImmutableMap [dart.core::String, #lib::A]
   [14] = String 'E2'
   [15] = String 'E4'
   [16] = Int 3
   [17] = String 'A.elem4'
-  [18] = Instance #lib::A type-args CP#5 {index: CP#16, _name: CP#17}
-  [19] = List type-arg dynamic, entries CP# [14, 8, 15, 18]
+  [18] = Instance #lib::A type-args CP#4 {index: CP#16, _name: CP#17}
+  [19] = List type-arg dynamic, entries CP# [14, 7, 15, 18]
   [20] = Instance dart.core::_ImmutableMap type-args CP#13 {_kvPairs: CP#19}
-  [21] = StaticICData target 'dart.core::print', arg-desc CP#1
+  [21] = StaticICData target 'dart.core::print', arg-desc CP#0
   [22] = Int 9
   [23] = Int 30
-  [24] = Instance #lib::C type-args CP#5 {j: CP#22, i: CP#23}
+  [24] = Instance #lib::C type-args CP#4 {j: CP#22, i: CP#23}
   [25] = TypeArgumentsForInstanceAllocation dart.core::_ImmutableMap [dart.core::String, dart.core::Object]
   [26] = String 'bar'
   [27] = Int 6
-  [28] = Instance #lib::B type-args CP#5 {i: CP#27}
-  [29] = List type-arg dynamic, entries CP# [3, 0, 26, 28]
+  [28] = Instance #lib::B type-args CP#4 {i: CP#27}
+  [29] = List type-arg dynamic, entries CP# [2, 9, 26, 28]
   [30] = Instance dart.core::_ImmutableMap type-args CP#25 {_kvPairs: CP#29}
-  [31] = Instance #lib::D type-args CP#5 {x: CP#24, y: CP#30}
-  [32] = StaticICData target 'dart.core::print', arg-desc CP#1
+  [31] = Instance #lib::D type-args CP#4 {x: CP#24, y: CP#30}
+  [32] = StaticICData target 'dart.core::print', arg-desc CP#0
 }
 ]static method test_constants2() → void {
   core::print(42);
@@ -463,70 +454,65 @@
   PushConstant         CP#0
   StoreLocal           r0
   Push                 r0
-  PushConstant         CP#1
+  PushInt              3
   CreateArrayTOS
   StoreLocal           r0
   Push                 r0
-  PushConstant         CP#2
-  PushConstant         CP#3
+  PushInt              0
+  PushInt              1
   StoreIndexedTOS
   Push                 r0
-  PushConstant         CP#3
+  PushInt              1
   Push                 FP[-5]
   StoreIndexedTOS
   Push                 r0
-  PushConstant         CP#4
-  PushConstant         CP#1
+  PushInt              2
+  PushInt              3
   StoreIndexedTOS
+  PushConstant         CP#2
+  IndirectStaticCall   2, CP#1
+  PushConstant         CP#4
+  IndirectStaticCall   1, CP#3
+  Drop1
+  PushConstant         CP#5
+  StoreLocal           r0
+  Push                 r0
+  PushInt              3
+  CreateArrayTOS
+  StoreLocal           r0
+  Push                 r0
+  PushInt              0
   PushConstant         CP#6
-  IndirectStaticCall   2, CP#5
-  PushConstant         CP#8
-  IndirectStaticCall   1, CP#7
-  Drop1
-  PushConstant         CP#9
-  StoreLocal           r0
-  Push                 r0
-  PushConstant         CP#1
-  CreateArrayTOS
-  StoreLocal           r0
-  Push                 r0
-  PushConstant         CP#2
-  PushConstant         CP#10
   StoreIndexedTOS
   Push                 r0
-  PushConstant         CP#3
+  PushInt              1
   Push                 FP[-5]
-  InstanceCall         1, CP#11
+  InstanceCall         1, CP#7
   StoreIndexedTOS
   Push                 r0
-  PushConstant         CP#4
-  PushConstant         CP#12
+  PushInt              2
+  PushConstant         CP#8
   StoreIndexedTOS
-  PushConstant         CP#13
-  IndirectStaticCall   2, CP#5
-  PushConstant         CP#14
-  IndirectStaticCall   1, CP#7
+  PushConstant         CP#9
+  IndirectStaticCall   2, CP#1
+  PushConstant         CP#10
+  IndirectStaticCall   1, CP#3
   Drop1
-  PushConstant         CP#15
+  PushNull
   ReturnTOS
 }
 ConstantPool {
   [0] = TypeArgs [dart.core::int]
-  [1] = Int 3
-  [2] = Int 0
-  [3] = Int 1
-  [4] = Int 2
-  [5] = ArgDesc num-args 2, num-type-args 0, names []
-  [6] = StaticICData target 'dart.core::List::_fromLiteral', arg-desc CP#5
-  [7] = ArgDesc num-args 1, num-type-args 0, names []
-  [8] = StaticICData target 'dart.core::print', arg-desc CP#7
-  [9] = TypeArgs [dart.core::String]
-  [10] = String 'a'
-  [11] = ICData target-name 'toString', arg-desc CP#7
-  [12] = String 'b'
-  [13] = StaticICData target 'dart.core::List::_fromLiteral', arg-desc CP#5
-  [14] = StaticICData target 'dart.core::print', arg-desc CP#7
-  [15] = Null
+  [1] = ArgDesc num-args 2, num-type-args 0, names []
+  [2] = StaticICData target 'dart.core::List::_fromLiteral', arg-desc CP#1
+  [3] = ArgDesc num-args 1, num-type-args 0, names []
+  [4] = StaticICData target 'dart.core::print', arg-desc CP#3
+  [5] = TypeArgs [dart.core::String]
+  [6] = String 'a'
+  [7] = ICData target-name 'toString', arg-desc CP#3
+  [8] = String 'b'
+  [9] = StaticICData target 'dart.core::List::_fromLiteral', arg-desc CP#1
+  [10] = StaticICData target 'dart.core::print', arg-desc CP#3
 }
 ]static method test_list_literal(core::int a) → void {
   core::print(<core::int>[1, a, 3]);
@@ -539,114 +525,108 @@
   CheckFunctionTypeArgs 1, 0
   PushConstant         CP#0
   PushConstant         CP#1
-  PushConstant         CP#2
+  PushInt              4
   CreateArrayTOS
   StoreLocal           r1
   Push                 r1
-  PushConstant         CP#3
-  PushConstant         CP#4
+  PushInt              0
+  PushInt              1
   StoreIndexedTOS
   Push                 r1
-  PushConstant         CP#4
+  PushInt              1
   Push                 FP[-7]
   StoreIndexedTOS
   Push                 r1
-  PushConstant         CP#5
+  PushInt              2
   Push                 FP[-6]
   StoreIndexedTOS
   Push                 r1
-  PushConstant         CP#6
-  PushConstant         CP#5
+  PushInt              3
+  PushInt              2
   StoreIndexedTOS
-  PushConstant         CP#8
-  IndirectStaticCall   2, CP#7
+  PushConstant         CP#3
+  IndirectStaticCall   2, CP#2
+  PushConstant         CP#5
+  IndirectStaticCall   1, CP#4
+  Drop1
+  PushConstant         CP#6
+  PushConstant         CP#1
+  PushInt              4
+  CreateArrayTOS
+  StoreLocal           r1
+  Push                 r1
+  PushInt              0
+  PushConstant         CP#7
+  StoreIndexedTOS
+  Push                 r1
+  PushInt              1
+  Push                 FP[-7]
+  StoreIndexedTOS
+  Push                 r1
+  PushInt              2
+  Push                 FP[-6]
+  InstanceCall         1, CP#8
+  StoreIndexedTOS
+  Push                 r1
+  PushInt              3
+  PushInt              3
+  StoreIndexedTOS
+  PushConstant         CP#9
+  IndirectStaticCall   2, CP#2
   PushConstant         CP#10
-  IndirectStaticCall   1, CP#9
+  IndirectStaticCall   1, CP#4
   Drop1
-  PushConstant         CP#11
-  PushConstant         CP#1
-  PushConstant         CP#2
-  CreateArrayTOS
-  StoreLocal           r1
-  Push                 r1
-  PushConstant         CP#3
+  PushNull
+  Push                 r0
+  InstantiateTypeArgumentsTOS 0, CP#11
   PushConstant         CP#12
-  StoreIndexedTOS
-  Push                 r1
-  PushConstant         CP#4
-  Push                 FP[-7]
-  StoreIndexedTOS
-  Push                 r1
-  PushConstant         CP#5
-  Push                 FP[-6]
-  InstanceCall         1, CP#13
-  StoreIndexedTOS
-  Push                 r1
-  PushConstant         CP#6
-  PushConstant         CP#6
-  StoreIndexedTOS
+  PushConstant         CP#13
+  IndirectStaticCall   2, CP#2
   PushConstant         CP#14
-  IndirectStaticCall   2, CP#7
-  PushConstant         CP#15
-  IndirectStaticCall   1, CP#9
+  IndirectStaticCall   1, CP#4
   Drop1
-  PushConstant         CP#16
+  PushNull
   Push                 r0
-  InstantiateTypeArgumentsTOS 0, CP#17
-  PushConstant         CP#18
-  PushConstant         CP#19
-  IndirectStaticCall   2, CP#7
-  PushConstant         CP#20
-  IndirectStaticCall   1, CP#9
-  Drop1
-  PushConstant         CP#16
-  Push                 r0
-  InstantiateTypeArgumentsTOS 0, CP#21
+  InstantiateTypeArgumentsTOS 0, CP#15
   PushConstant         CP#1
-  PushConstant         CP#5
+  PushInt              2
   CreateArrayTOS
   StoreLocal           r1
   Push                 r1
-  PushConstant         CP#3
+  PushInt              0
   Push                 FP[-5]
   StoreIndexedTOS
   Push                 r1
-  PushConstant         CP#4
-  PushConstant         CP#2
+  PushInt              1
+  PushInt              4
   StoreIndexedTOS
-  PushConstant         CP#22
-  IndirectStaticCall   2, CP#7
-  PushConstant         CP#23
-  IndirectStaticCall   1, CP#9
-  Drop1
   PushConstant         CP#16
+  IndirectStaticCall   2, CP#2
+  PushConstant         CP#17
+  IndirectStaticCall   1, CP#4
+  Drop1
+  PushNull
   ReturnTOS
 }
 ConstantPool {
   [0] = TypeArgs [dart.core::int, dart.core::int]
   [1] = TypeArgs [dynamic]
-  [2] = Int 4
-  [3] = Int 0
-  [4] = Int 1
-  [5] = Int 2
-  [6] = Int 3
-  [7] = ArgDesc num-args 2, num-type-args 0, names []
-  [8] = StaticICData target 'dart.core::Map::_fromLiteral', arg-desc CP#7
-  [9] = ArgDesc num-args 1, num-type-args 0, names []
-  [10] = StaticICData target 'dart.core::print', arg-desc CP#9
-  [11] = TypeArgs [dart.core::String, dart.core::int]
-  [12] = String 'foo'
-  [13] = ICData target-name 'toString', arg-desc CP#9
-  [14] = StaticICData target 'dart.core::Map::_fromLiteral', arg-desc CP#7
-  [15] = StaticICData target 'dart.core::print', arg-desc CP#9
-  [16] = Null
-  [17] = TypeArgs [dart.core::String, #lib::test_map_literal::T]
-  [18] = List type-arg dynamic, entries CP# []
-  [19] = StaticICData target 'dart.core::Map::_fromLiteral', arg-desc CP#7
-  [20] = StaticICData target 'dart.core::print', arg-desc CP#9
-  [21] = TypeArgs [#lib::test_map_literal::T, dart.core::int]
-  [22] = StaticICData target 'dart.core::Map::_fromLiteral', arg-desc CP#7
-  [23] = StaticICData target 'dart.core::print', arg-desc CP#9
+  [2] = ArgDesc num-args 2, num-type-args 0, names []
+  [3] = StaticICData target 'dart.core::Map::_fromLiteral', arg-desc CP#2
+  [4] = ArgDesc num-args 1, num-type-args 0, names []
+  [5] = StaticICData target 'dart.core::print', arg-desc CP#4
+  [6] = TypeArgs [dart.core::String, dart.core::int]
+  [7] = String 'foo'
+  [8] = ICData target-name 'toString', arg-desc CP#4
+  [9] = StaticICData target 'dart.core::Map::_fromLiteral', arg-desc CP#2
+  [10] = StaticICData target 'dart.core::print', arg-desc CP#4
+  [11] = TypeArgs [dart.core::String, #lib::test_map_literal::T]
+  [12] = List type-arg dynamic, entries CP# []
+  [13] = StaticICData target 'dart.core::Map::_fromLiteral', arg-desc CP#2
+  [14] = StaticICData target 'dart.core::print', arg-desc CP#4
+  [15] = TypeArgs [#lib::test_map_literal::T, dart.core::int]
+  [16] = StaticICData target 'dart.core::Map::_fromLiteral', arg-desc CP#2
+  [17] = StaticICData target 'dart.core::print', arg-desc CP#4
 }
 ]static method test_map_literal<T extends core::Object = dynamic>(core::int a, core::int b, self::test_map_literal::T c) → void {
   core::print(<core::int, core::int>{1: a, b: 2});
@@ -658,22 +638,27 @@
 Bytecode {
   Entry                0
   CheckStack
-  PushConstant         CP#2
-  PushConstant         CP#4
-  IndirectStaticCall   1, CP#3
-  Drop1
   PushConstant         CP#0
+  PushConstant         CP#2
+  IndirectStaticCall   1, CP#1
+  Drop1
+  PushConstant         CP#3
+  PushConstant         CP#4
+  IndirectStaticCall   1, CP#1
+  Drop1
+  PushNull
   ReturnTOS
 }
 ConstantPool {
-  [0] = Null
-  [1] = String 'test_symbol'
-  [2] = Instance dart._internal::Symbol type-args CP#0 {_name: CP#1}
-  [3] = ArgDesc num-args 1, num-type-args 0, names []
-  [4] = StaticICData target 'dart.core::print', arg-desc CP#3
+  [0] = Symbol 'test_symbol'
+  [1] = ArgDesc num-args 1, num-type-args 0, names []
+  [2] = StaticICData target 'dart.core::print', arg-desc CP#1
+  [3] = Symbol #lib::'_private_symbol'
+  [4] = StaticICData target 'dart.core::print', arg-desc CP#1
 }
 ]static method test_symbol() → void {
   core::print(#test_symbol);
+  core::print(#_private_symbol);
 }
 [@vm.bytecode=
 Bytecode {
@@ -684,13 +669,13 @@
   PushConstant         CP#2
   IndirectStaticCall   1, CP#1
   Drop1
-  PushConstant         CP#4
+  PushNull
   Push                 r0
   InstantiateType      CP#3
-  PushConstant         CP#5
+  PushConstant         CP#4
   IndirectStaticCall   1, CP#1
   Drop1
-  PushConstant         CP#4
+  PushNull
   ReturnTOS
 }
 ConstantPool {
@@ -698,8 +683,7 @@
   [1] = ArgDesc num-args 1, num-type-args 0, names []
   [2] = StaticICData target 'dart.core::print', arg-desc CP#1
   [3] = Type #lib::test_type_literal::T
-  [4] = Null
-  [5] = StaticICData target 'dart.core::print', arg-desc CP#1
+  [4] = StaticICData target 'dart.core::print', arg-desc CP#1
 }
 ]static method test_type_literal<T extends core::Object = dynamic>() → void {
   core::print(core::String);
@@ -711,13 +695,12 @@
   CheckStack
   PushConstant         CP#1
   ReturnTOS
-  PushConstant         CP#2
+  PushNull
   ReturnTOS
 }
 ConstantPool {
   [0] = TypeArgumentsForInstanceAllocation #lib::F [dart.core::int, dart.core::String]
   [1] = Instance #lib::F type-args CP#0 {}
-  [2] = Null
 }
 ]static method testGenericConstInstance() → dynamic
   return const self::F::•<core::int, core::String>();
@@ -727,12 +710,11 @@
   CheckStack
   PushConstant         CP#0
   ReturnTOS
-  PushConstant         CP#1
+  PushNull
   ReturnTOS
 }
 ConstantPool {
   [0] = Type <X extends dart.core::Object = dynamic>(X) → X
-  [1] = Null
 }
 ]static method testGenericFunctionTypeLiteral() → dynamic
   return <X extends core::Object = dynamic>(X) → X;
@@ -743,12 +725,11 @@
   PushConstant         CP#0
   PushStatic           CP#0
   ReturnTOS
-  PushConstant         CP#1
+  PushNull
   ReturnTOS
 }
 ConstantPool {
   [0] = StaticField #lib::fieldWithDoubleLiteralInitializer
-  [1] = Null
 }
 ]static method testFieldWithDoubleLiteralInitializer() → dynamic
   return self::fieldWithDoubleLiteralInitializer;
@@ -756,10 +737,9 @@
 Bytecode {
   Entry                0
   CheckStack
-  PushConstant         CP#0
+  PushNull
   ReturnTOS
 }
 ConstantPool {
-  [0] = Null
 }
 ]static method main() → dynamic {}
diff --git a/pkg/vm/testcases/bytecode/loops.dart.expect b/pkg/vm/testcases/bytecode/loops.dart.expect
index 4112fe8..1a03e54 100644
--- a/pkg/vm/testcases/bytecode/loops.dart.expect
+++ b/pkg/vm/testcases/bytecode/loops.dart.expect
@@ -6,50 +6,46 @@
 Bytecode {
   Entry                2
   CheckStack
-  PushConstant         CP#0
+  PushInt              0
   PopLocal             r0
-  PushConstant         CP#0
+  PushInt              0
   PopLocal             r1
 L2:
   CheckStack
   Push                 r1
   Push                 FP[-5]
-  InstanceCall         1, CP#2
-  InstanceCall         2, CP#4
+  InstanceCall         1, CP#1
+  InstanceCall         2, CP#3
   AssertBoolean        0
-  PushConstant         CP#5
+  PushTrue
   IfNeStrictTOS
   Jump                 L1
   Push                 r0
   Push                 FP[-5]
   Push                 r1
-  InstanceCall         2, CP#6
-  InstanceCall         2, CP#7
+  InstanceCall         2, CP#4
+  InstanceCall         2, CP#5
   PopLocal             r0
   Push                 r1
-  PushConstant         CP#8
-  InstanceCall         2, CP#9
+  PushInt              1
+  InstanceCall         2, CP#6
   StoreLocal           r1
   Drop1
   Jump                 L2
 L1:
   Push                 r0
   ReturnTOS
-  PushConstant         CP#10
+  PushNull
   ReturnTOS
 }
 ConstantPool {
-  [0] = Int 0
-  [1] = ArgDesc num-args 1, num-type-args 0, names []
-  [2] = ICData get target-name 'length', arg-desc CP#1
-  [3] = ArgDesc num-args 2, num-type-args 0, names []
-  [4] = ICData target-name '<', arg-desc CP#3
-  [5] = Bool true
-  [6] = ICData target-name '[]', arg-desc CP#3
-  [7] = ICData target-name '+', arg-desc CP#3
-  [8] = Int 1
-  [9] = ICData target-name '+', arg-desc CP#3
-  [10] = Null
+  [0] = ArgDesc num-args 1, num-type-args 0, names []
+  [1] = ICData get target-name 'length', arg-desc CP#0
+  [2] = ArgDesc num-args 2, num-type-args 0, names []
+  [3] = ICData target-name '<', arg-desc CP#2
+  [4] = ICData target-name '[]', arg-desc CP#2
+  [5] = ICData target-name '+', arg-desc CP#2
+  [6] = ICData target-name '+', arg-desc CP#2
 }
 ]static method test_for(core::List<core::int> list) → core::int {
   core::int sum = 0;
@@ -62,25 +58,25 @@
 Bytecode {
   Entry                2
   CheckStack
-  PushConstant         CP#0
+  PushInt              0
   PopLocal             r0
-  PushConstant         CP#0
+  PushInt              0
   PopLocal             r1
 L3:
   CheckStack
   Push                 r1
-  PushConstant         CP#0
-  InstanceCall         2, CP#2
+  PushInt              0
+  InstanceCall         2, CP#1
   AssertBoolean        0
-  PushConstant         CP#3
+  PushTrue
   IfNeStrictTOS
   Jump                 L1
   Push                 r1
   Push                 FP[-5]
-  InstanceCall         1, CP#5
-  InstanceCall         2, CP#6
+  InstanceCall         1, CP#3
+  InstanceCall         2, CP#4
   AssertBoolean        0
-  PushConstant         CP#3
+  PushTrue
   IfNeStrictTOS
   Jump                 L2
   Jump                 L1
@@ -88,34 +84,30 @@
   Push                 r0
   Push                 FP[-5]
   Push                 r1
-  InstanceCall         2, CP#7
-  InstanceCall         2, CP#8
+  InstanceCall         2, CP#5
+  InstanceCall         2, CP#6
   PopLocal             r0
   Push                 r1
-  PushConstant         CP#9
-  InstanceCall         2, CP#10
+  PushInt              1
+  InstanceCall         2, CP#7
   StoreLocal           r1
   Drop1
   Jump                 L3
 L1:
   Push                 r0
   ReturnTOS
-  PushConstant         CP#11
+  PushNull
   ReturnTOS
 }
 ConstantPool {
-  [0] = Int 0
-  [1] = ArgDesc num-args 2, num-type-args 0, names []
-  [2] = ICData target-name '>=', arg-desc CP#1
-  [3] = Bool true
-  [4] = ArgDesc num-args 1, num-type-args 0, names []
-  [5] = ICData get target-name 'length', arg-desc CP#4
-  [6] = ICData target-name '>=', arg-desc CP#1
-  [7] = ICData target-name '[]', arg-desc CP#1
-  [8] = ICData target-name '+', arg-desc CP#1
-  [9] = Int 1
-  [10] = ICData target-name '+', arg-desc CP#1
-  [11] = Null
+  [0] = ArgDesc num-args 2, num-type-args 0, names []
+  [1] = ICData target-name '>=', arg-desc CP#0
+  [2] = ArgDesc num-args 1, num-type-args 0, names []
+  [3] = ICData get target-name 'length', arg-desc CP#2
+  [4] = ICData target-name '>=', arg-desc CP#0
+  [5] = ICData target-name '[]', arg-desc CP#0
+  [6] = ICData target-name '+', arg-desc CP#0
+  [7] = ICData target-name '+', arg-desc CP#0
 }
 ]static method test_for_break(core::List<core::int> list) → core::int {
   core::int sum = 0;
@@ -132,26 +124,26 @@
 Bytecode {
   Entry                2
   CheckStack
-  PushConstant         CP#0
+  PushInt              0
   PopLocal             r0
-  PushConstant         CP#1
-  InstanceCall         1, CP#3
+  PushInt              100
+  InstanceCall         1, CP#1
   PopLocal             r1
 L4:
   CheckStack
   Push                 r1
   Push                 FP[-5]
-  InstanceCall         1, CP#4
-  InstanceCall         2, CP#6
+  InstanceCall         1, CP#2
+  InstanceCall         2, CP#4
   AssertBoolean        0
-  PushConstant         CP#7
+  PushTrue
   IfNeStrictTOS
   Jump                 L1
   Push                 r1
-  PushConstant         CP#0
-  InstanceCall         2, CP#8
+  PushInt              0
+  InstanceCall         2, CP#5
   AssertBoolean        0
-  PushConstant         CP#7
+  PushTrue
   IfNeStrictTOS
   Jump                 L2
   Jump                 L3
@@ -159,37 +151,32 @@
   Push                 r0
   Push                 FP[-5]
   Push                 r1
-  InstanceCall         2, CP#9
-  InstanceCall         2, CP#10
+  InstanceCall         2, CP#6
+  InstanceCall         2, CP#7
   PopLocal             r0
 L3:
   Push                 r1
-  PushConstant         CP#11
-  InstanceCall         2, CP#12
+  PushInt              1
+  InstanceCall         2, CP#8
   StoreLocal           r1
   Drop1
   Jump                 L4
 L1:
   Push                 r0
   ReturnTOS
-  PushConstant         CP#13
+  PushNull
   ReturnTOS
 }
 ConstantPool {
-  [0] = Int 0
-  [1] = Int 100
-  [2] = ArgDesc num-args 1, num-type-args 0, names []
-  [3] = ICData target-name 'unary-', arg-desc CP#2
-  [4] = ICData get target-name 'length', arg-desc CP#2
-  [5] = ArgDesc num-args 2, num-type-args 0, names []
-  [6] = ICData target-name '<', arg-desc CP#5
-  [7] = Bool true
-  [8] = ICData target-name '<', arg-desc CP#5
-  [9] = ICData target-name '[]', arg-desc CP#5
-  [10] = ICData target-name '+', arg-desc CP#5
-  [11] = Int 1
-  [12] = ICData target-name '+', arg-desc CP#5
-  [13] = Null
+  [0] = ArgDesc num-args 1, num-type-args 0, names []
+  [1] = ICData target-name 'unary-', arg-desc CP#0
+  [2] = ICData get target-name 'length', arg-desc CP#0
+  [3] = ArgDesc num-args 2, num-type-args 0, names []
+  [4] = ICData target-name '<', arg-desc CP#3
+  [5] = ICData target-name '<', arg-desc CP#3
+  [6] = ICData target-name '[]', arg-desc CP#3
+  [7] = ICData target-name '+', arg-desc CP#3
+  [8] = ICData target-name '+', arg-desc CP#3
 }
 ]static method test_for_continue(core::List<core::int> list) → core::int {
   core::int sum = 0;
@@ -207,18 +194,18 @@
 Bytecode {
   Entry                4
   CheckStack
-  PushConstant         CP#0
+  PushInt              0
   PopLocal             r0
-  PushConstant         CP#0
+  PushInt              0
   PopLocal             r1
 L2:
   CheckStack
   Push                 r1
   Push                 FP[-5]
-  InstanceCall         1, CP#2
-  InstanceCall         2, CP#4
+  InstanceCall         1, CP#1
+  InstanceCall         2, CP#3
   AssertBoolean        0
-  PushConstant         CP#5
+  PushTrue
   IfNeStrictTOS
   Jump                 L1
   Push                 r0
@@ -226,33 +213,29 @@
   Push                 r1
   PopLocal             r2
   Push                 r2
-  PushConstant         CP#6
-  InstanceCall         2, CP#7
+  PushInt              1
+  InstanceCall         2, CP#4
   StoreLocal           r1
   PopLocal             r3
   Push                 r2
-  InstanceCall         2, CP#8
-  InstanceCall         2, CP#9
+  InstanceCall         2, CP#5
+  InstanceCall         2, CP#6
   PopLocal             r0
   Jump                 L2
 L1:
   Push                 r0
   ReturnTOS
-  PushConstant         CP#10
+  PushNull
   ReturnTOS
 }
 ConstantPool {
-  [0] = Int 0
-  [1] = ArgDesc num-args 1, num-type-args 0, names []
-  [2] = ICData get target-name 'length', arg-desc CP#1
-  [3] = ArgDesc num-args 2, num-type-args 0, names []
-  [4] = ICData target-name '<', arg-desc CP#3
-  [5] = Bool true
-  [6] = Int 1
-  [7] = ICData target-name '+', arg-desc CP#3
-  [8] = ICData target-name '[]', arg-desc CP#3
-  [9] = ICData target-name '+', arg-desc CP#3
-  [10] = Null
+  [0] = ArgDesc num-args 1, num-type-args 0, names []
+  [1] = ICData get target-name 'length', arg-desc CP#0
+  [2] = ArgDesc num-args 2, num-type-args 0, names []
+  [3] = ICData target-name '<', arg-desc CP#2
+  [4] = ICData target-name '+', arg-desc CP#2
+  [5] = ICData target-name '[]', arg-desc CP#2
+  [6] = ICData target-name '+', arg-desc CP#2
 }
 ]static method test_while(core::List<core::int> list) → core::int {
   core::int sum = 0;
@@ -266,47 +249,43 @@
 Bytecode {
   Entry                2
   CheckStack
-  PushConstant         CP#0
+  PushInt              0
   PopLocal             r0
-  PushConstant         CP#0
+  PushInt              0
   PopLocal             r1
 L1:
   CheckStack
   Push                 r0
   Push                 FP[-5]
   Push                 r1
+  InstanceCall         2, CP#1
   InstanceCall         2, CP#2
-  InstanceCall         2, CP#3
   PopLocal             r0
   Push                 r1
-  PushConstant         CP#4
-  InstanceCall         2, CP#5
+  PushInt              1
+  InstanceCall         2, CP#3
   PopLocal             r1
   Push                 r1
   Push                 FP[-5]
-  InstanceCall         1, CP#7
-  InstanceCall         2, CP#8
+  InstanceCall         1, CP#5
+  InstanceCall         2, CP#6
   AssertBoolean        0
-  PushConstant         CP#9
+  PushTrue
   IfEqStrictTOS
   Jump                 L1
   Push                 r0
   ReturnTOS
-  PushConstant         CP#10
+  PushNull
   ReturnTOS
 }
 ConstantPool {
-  [0] = Int 0
-  [1] = ArgDesc num-args 2, num-type-args 0, names []
-  [2] = ICData target-name '[]', arg-desc CP#1
-  [3] = ICData target-name '+', arg-desc CP#1
-  [4] = Int 1
-  [5] = ICData target-name '+', arg-desc CP#1
-  [6] = ArgDesc num-args 1, num-type-args 0, names []
-  [7] = ICData get target-name 'length', arg-desc CP#6
-  [8] = ICData target-name '<', arg-desc CP#1
-  [9] = Bool true
-  [10] = Null
+  [0] = ArgDesc num-args 2, num-type-args 0, names []
+  [1] = ICData target-name '[]', arg-desc CP#0
+  [2] = ICData target-name '+', arg-desc CP#0
+  [3] = ICData target-name '+', arg-desc CP#0
+  [4] = ArgDesc num-args 1, num-type-args 0, names []
+  [5] = ICData get target-name 'length', arg-desc CP#4
+  [6] = ICData target-name '<', arg-desc CP#0
 }
 ]static method test_do_while(core::List<core::int> list) → core::int {
   core::int sum = 0;
@@ -322,42 +301,39 @@
 Bytecode {
   Entry                3
   CheckStack
-  PushConstant         CP#0
+  PushInt              0
   PopLocal             r0
   Push                 FP[-5]
-  InstanceCall         1, CP#2
+  InstanceCall         1, CP#1
   PopLocal             r1
 L2:
   CheckStack
   Push                 r1
-  InstanceCall         1, CP#3
-  PushConstant         CP#4
+  InstanceCall         1, CP#2
+  PushTrue
   IfNeStrictTOS
   Jump                 L1
   Push                 r1
-  InstanceCall         1, CP#5
+  InstanceCall         1, CP#3
   PopLocal             r2
   Push                 r0
   Push                 r2
-  InstanceCall         2, CP#7
+  InstanceCall         2, CP#5
   PopLocal             r0
   Jump                 L2
 L1:
   Push                 r0
   ReturnTOS
-  PushConstant         CP#8
+  PushNull
   ReturnTOS
 }
 ConstantPool {
-  [0] = Int 0
-  [1] = ArgDesc num-args 1, num-type-args 0, names []
-  [2] = ICData get target-name 'iterator', arg-desc CP#1
-  [3] = ICData target-name 'moveNext', arg-desc CP#1
-  [4] = Bool true
-  [5] = ICData get target-name 'current', arg-desc CP#1
-  [6] = ArgDesc num-args 2, num-type-args 0, names []
-  [7] = ICData target-name '+', arg-desc CP#6
-  [8] = Null
+  [0] = ArgDesc num-args 1, num-type-args 0, names []
+  [1] = ICData get target-name 'iterator', arg-desc CP#0
+  [2] = ICData target-name 'moveNext', arg-desc CP#0
+  [3] = ICData get target-name 'current', arg-desc CP#0
+  [4] = ArgDesc num-args 2, num-type-args 0, names []
+  [5] = ICData target-name '+', arg-desc CP#4
 }
 ]static method test_for_in(core::List<core::int> list) → core::int {
   core::int sum = 0;
@@ -370,47 +346,43 @@
 Bytecode {
   Entry                4
   CheckStack
-  PushConstant         CP#0
+  PushInt              0
   PopLocal             r0
-  PushConstant         CP#1
+  PushInt              42
   PopLocal             r1
   Push                 FP[-5]
-  InstanceCall         1, CP#3
+  InstanceCall         1, CP#1
   PopLocal             r2
 L2:
   CheckStack
   Push                 r2
-  InstanceCall         1, CP#4
-  PushConstant         CP#5
+  InstanceCall         1, CP#2
+  PushTrue
   IfNeStrictTOS
   Jump                 L1
   Push                 r2
-  InstanceCall         1, CP#6
+  InstanceCall         1, CP#3
   PopLocal             r3
   Push                 r3
   PopLocal             r1
   Push                 r0
   Push                 r1
-  InstanceCall         2, CP#8
+  InstanceCall         2, CP#5
   PopLocal             r0
   Jump                 L2
 L1:
   Push                 r0
   ReturnTOS
-  PushConstant         CP#9
+  PushNull
   ReturnTOS
 }
 ConstantPool {
-  [0] = Int 0
-  [1] = Int 42
-  [2] = ArgDesc num-args 1, num-type-args 0, names []
-  [3] = ICData get target-name 'iterator', arg-desc CP#2
-  [4] = ICData target-name 'moveNext', arg-desc CP#2
-  [5] = Bool true
-  [6] = ICData get target-name 'current', arg-desc CP#2
-  [7] = ArgDesc num-args 2, num-type-args 0, names []
-  [8] = ICData target-name '+', arg-desc CP#7
-  [9] = Null
+  [0] = ArgDesc num-args 1, num-type-args 0, names []
+  [1] = ICData get target-name 'iterator', arg-desc CP#0
+  [2] = ICData target-name 'moveNext', arg-desc CP#0
+  [3] = ICData get target-name 'current', arg-desc CP#0
+  [4] = ArgDesc num-args 2, num-type-args 0, names []
+  [5] = ICData target-name '+', arg-desc CP#4
 }
 ]static method test_for_in_with_outer_var(core::List<core::int> list) → core::int {
   core::int sum = 0;
@@ -425,10 +397,9 @@
 Bytecode {
   Entry                0
   CheckStack
-  PushConstant         CP#0
+  PushNull
   ReturnTOS
 }
 ConstantPool {
-  [0] = Null
 }
 ]static method main() → dynamic {}
diff --git a/pkg/vm/testcases/bytecode/optional_params.dart.expect b/pkg/vm/testcases/bytecode/optional_params.dart.expect
index 306a642..265c758 100644
--- a/pkg/vm/testcases/bytecode/optional_params.dart.expect
+++ b/pkg/vm/testcases/bytecode/optional_params.dart.expect
@@ -9,77 +9,73 @@
   LoadConstant         r2, CP#1
   Frame                1
   CheckStack
-  PushConstant         CP#2
-  PushConstant         CP#3
+  PushNull
+  PushInt              2
   CreateArrayTOS
   StoreLocal           r3
   Push                 r3
-  PushConstant         CP#4
-  PushConstant         CP#5
+  PushInt              0
+  PushConstant         CP#2
   StoreIndexedTOS
   Push                 r3
-  PushConstant         CP#6
+  PushInt              1
   Push                 r0
   StoreIndexedTOS
-  PushConstant         CP#8
-  IndirectStaticCall   1, CP#7
-  PushConstant         CP#9
-  IndirectStaticCall   1, CP#7
+  PushConstant         CP#4
+  IndirectStaticCall   1, CP#3
+  PushConstant         CP#5
+  IndirectStaticCall   1, CP#3
   Drop1
-  PushConstant         CP#2
-  PushConstant         CP#3
+  PushNull
+  PushInt              2
   CreateArrayTOS
   StoreLocal           r3
   Push                 r3
-  PushConstant         CP#4
-  PushConstant         CP#10
+  PushInt              0
+  PushConstant         CP#6
   StoreIndexedTOS
   Push                 r3
-  PushConstant         CP#6
+  PushInt              1
   Push                 r1
   StoreIndexedTOS
-  PushConstant         CP#11
-  IndirectStaticCall   1, CP#7
-  PushConstant         CP#12
-  IndirectStaticCall   1, CP#7
+  PushConstant         CP#7
+  IndirectStaticCall   1, CP#3
+  PushConstant         CP#8
+  IndirectStaticCall   1, CP#3
   Drop1
-  PushConstant         CP#2
-  PushConstant         CP#3
+  PushNull
+  PushInt              2
   CreateArrayTOS
   StoreLocal           r3
   Push                 r3
-  PushConstant         CP#4
-  PushConstant         CP#13
+  PushInt              0
+  PushConstant         CP#9
   StoreIndexedTOS
   Push                 r3
-  PushConstant         CP#6
+  PushInt              1
   Push                 r2
   StoreIndexedTOS
-  PushConstant         CP#14
-  IndirectStaticCall   1, CP#7
-  PushConstant         CP#15
-  IndirectStaticCall   1, CP#7
+  PushConstant         CP#10
+  IndirectStaticCall   1, CP#3
+  PushConstant         CP#11
+  IndirectStaticCall   1, CP#3
   Drop1
-  PushConstant         CP#2
+  PushNull
   ReturnTOS
 }
 ConstantPool {
   [0] = String 'default_a'
   [1] = String 'default_b'
-  [2] = Null
-  [3] = Int 2
-  [4] = Int 0
-  [5] = String 'x = '
-  [6] = Int 1
-  [7] = ArgDesc num-args 1, num-type-args 0, names []
-  [8] = StaticICData target 'dart.core::_StringBase::_interpolate', arg-desc CP#7
-  [9] = StaticICData target 'dart.core::print', arg-desc CP#7
-  [10] = String 'a = '
-  [11] = StaticICData target 'dart.core::_StringBase::_interpolate', arg-desc CP#7
-  [12] = StaticICData target 'dart.core::print', arg-desc CP#7
-  [13] = String 'b = '
-  [14] = StaticICData target 'dart.core::_StringBase::_interpolate', arg-desc CP#7
-  [15] = StaticICData target 'dart.core::print', arg-desc CP#7
+  [2] = String 'x = '
+  [3] = ArgDesc num-args 1, num-type-args 0, names []
+  [4] = StaticICData target 'dart.core::_StringBase::_interpolate', arg-desc CP#3
+  [5] = StaticICData target 'dart.core::print', arg-desc CP#3
+  [6] = String 'a = '
+  [7] = StaticICData target 'dart.core::_StringBase::_interpolate', arg-desc CP#3
+  [8] = StaticICData target 'dart.core::print', arg-desc CP#3
+  [9] = String 'b = '
+  [10] = StaticICData target 'dart.core::_StringBase::_interpolate', arg-desc CP#3
+  [11] = StaticICData target 'dart.core::print', arg-desc CP#3
 }
 ]static method foo1(dynamic x, [dynamic a = "default_a", dynamic b = "default_b"]) → void {
   core::print("x = ${x}");
@@ -97,92 +93,92 @@
   LoadConstant         r4, CP#6
   Frame                1
   CheckStack
-  PushConstant         CP#7
-  PushConstant         CP#8
+  PushNull
+  PushInt              2
   CreateArrayTOS
   StoreLocal           r5
   Push                 r5
-  PushConstant         CP#9
-  PushConstant         CP#10
+  PushInt              0
+  PushConstant         CP#7
   StoreIndexedTOS
   Push                 r5
-  PushConstant         CP#11
+  PushInt              1
   Push                 r0
   StoreIndexedTOS
-  PushConstant         CP#13
-  IndirectStaticCall   1, CP#12
-  PushConstant         CP#14
-  IndirectStaticCall   1, CP#12
+  PushConstant         CP#9
+  IndirectStaticCall   1, CP#8
+  PushConstant         CP#10
+  IndirectStaticCall   1, CP#8
   Drop1
-  PushConstant         CP#7
-  PushConstant         CP#8
+  PushNull
+  PushInt              2
   CreateArrayTOS
   StoreLocal           r5
   Push                 r5
-  PushConstant         CP#9
-  PushConstant         CP#15
+  PushInt              0
+  PushConstant         CP#11
   StoreIndexedTOS
   Push                 r5
-  PushConstant         CP#11
+  PushInt              1
   Push                 r1
   StoreIndexedTOS
-  PushConstant         CP#16
-  IndirectStaticCall   1, CP#12
-  PushConstant         CP#17
-  IndirectStaticCall   1, CP#12
+  PushConstant         CP#12
+  IndirectStaticCall   1, CP#8
+  PushConstant         CP#13
+  IndirectStaticCall   1, CP#8
   Drop1
-  PushConstant         CP#7
-  PushConstant         CP#8
+  PushNull
+  PushInt              2
   CreateArrayTOS
   StoreLocal           r5
   Push                 r5
-  PushConstant         CP#9
-  PushConstant         CP#18
+  PushInt              0
+  PushConstant         CP#14
   StoreIndexedTOS
   Push                 r5
-  PushConstant         CP#11
+  PushInt              1
   Push                 r2
   StoreIndexedTOS
-  PushConstant         CP#19
-  IndirectStaticCall   1, CP#12
-  PushConstant         CP#20
-  IndirectStaticCall   1, CP#12
+  PushConstant         CP#15
+  IndirectStaticCall   1, CP#8
+  PushConstant         CP#16
+  IndirectStaticCall   1, CP#8
   Drop1
-  PushConstant         CP#7
-  PushConstant         CP#8
+  PushNull
+  PushInt              2
   CreateArrayTOS
   StoreLocal           r5
   Push                 r5
-  PushConstant         CP#9
-  PushConstant         CP#21
+  PushInt              0
+  PushConstant         CP#17
   StoreIndexedTOS
   Push                 r5
-  PushConstant         CP#11
+  PushInt              1
   Push                 r3
   StoreIndexedTOS
-  PushConstant         CP#22
-  IndirectStaticCall   1, CP#12
-  PushConstant         CP#23
-  IndirectStaticCall   1, CP#12
+  PushConstant         CP#18
+  IndirectStaticCall   1, CP#8
+  PushConstant         CP#19
+  IndirectStaticCall   1, CP#8
   Drop1
-  PushConstant         CP#7
-  PushConstant         CP#8
+  PushNull
+  PushInt              2
   CreateArrayTOS
   StoreLocal           r5
   Push                 r5
-  PushConstant         CP#9
-  PushConstant         CP#24
+  PushInt              0
+  PushConstant         CP#20
   StoreIndexedTOS
   Push                 r5
-  PushConstant         CP#11
+  PushInt              1
   Push                 r4
   StoreIndexedTOS
-  PushConstant         CP#25
-  IndirectStaticCall   1, CP#12
-  PushConstant         CP#26
-  IndirectStaticCall   1, CP#12
+  PushConstant         CP#21
+  IndirectStaticCall   1, CP#8
+  PushConstant         CP#22
+  IndirectStaticCall   1, CP#8
   Drop1
-  PushConstant         CP#7
+  PushNull
   ReturnTOS
 }
 ConstantPool {
@@ -193,26 +189,22 @@
   [4] = List type-arg dart.core::String, entries CP# [3]
   [5] = String 'c'
   [6] = String 'default_c'
-  [7] = Null
-  [8] = Int 2
-  [9] = Int 0
-  [10] = String 'y = '
-  [11] = Int 1
-  [12] = ArgDesc num-args 1, num-type-args 0, names []
-  [13] = StaticICData target 'dart.core::_StringBase::_interpolate', arg-desc CP#12
-  [14] = StaticICData target 'dart.core::print', arg-desc CP#12
-  [15] = String 'z = '
-  [16] = StaticICData target 'dart.core::_StringBase::_interpolate', arg-desc CP#12
-  [17] = StaticICData target 'dart.core::print', arg-desc CP#12
-  [18] = String 'a = '
-  [19] = StaticICData target 'dart.core::_StringBase::_interpolate', arg-desc CP#12
-  [20] = StaticICData target 'dart.core::print', arg-desc CP#12
-  [21] = String 'b = '
-  [22] = StaticICData target 'dart.core::_StringBase::_interpolate', arg-desc CP#12
-  [23] = StaticICData target 'dart.core::print', arg-desc CP#12
-  [24] = String 'c = '
-  [25] = StaticICData target 'dart.core::_StringBase::_interpolate', arg-desc CP#12
-  [26] = StaticICData target 'dart.core::print', arg-desc CP#12
+  [7] = String 'y = '
+  [8] = ArgDesc num-args 1, num-type-args 0, names []
+  [9] = StaticICData target 'dart.core::_StringBase::_interpolate', arg-desc CP#8
+  [10] = StaticICData target 'dart.core::print', arg-desc CP#8
+  [11] = String 'z = '
+  [12] = StaticICData target 'dart.core::_StringBase::_interpolate', arg-desc CP#8
+  [13] = StaticICData target 'dart.core::print', arg-desc CP#8
+  [14] = String 'a = '
+  [15] = StaticICData target 'dart.core::_StringBase::_interpolate', arg-desc CP#8
+  [16] = StaticICData target 'dart.core::print', arg-desc CP#8
+  [17] = String 'b = '
+  [18] = StaticICData target 'dart.core::_StringBase::_interpolate', arg-desc CP#8
+  [19] = StaticICData target 'dart.core::print', arg-desc CP#8
+  [20] = String 'c = '
+  [21] = StaticICData target 'dart.core::_StringBase::_interpolate', arg-desc CP#8
+  [22] = StaticICData target 'dart.core::print', arg-desc CP#8
 }
 ]static method foo2(dynamic y, dynamic z, {dynamic c = "default_c", dynamic a = 42, dynamic b = const <core::String>["default_b"]}) → void {
   core::print("y = ${y}");
@@ -231,7 +223,7 @@
   Frame                1
   CheckStack
   CheckFunctionTypeArgs 2, 4
-  PushConstant         CP#3
+  PushNull
   Push                 r4
   InstantiateType      CP#4
   PushConstant         CP#6
@@ -245,7 +237,7 @@
   PushConstant         CP#8
   IndirectStaticCall   1, CP#5
   Drop1
-  PushConstant         CP#3
+  PushNull
   ReturnTOS
 }
 ConstantPool {
@@ -279,7 +271,7 @@
   PushConstant         CP#7
   IndirectStaticCall   3, CP#6
   Drop1
-  PushConstant         CP#8
+  PushNull
   ReturnTOS
 }
 ConstantPool {
@@ -291,7 +283,6 @@
   [5] = String 'fixed_z'
   [6] = ArgDesc num-args 3, num-type-args 0, names [a]
   [7] = StaticICData target '#lib::foo2', arg-desc CP#6
-  [8] = Null
 }
 ]static method main() → dynamic {
   self::foo1("fixed_x", "concrete_a");
diff --git a/pkg/vm/testcases/bytecode/super_calls.dart.expect b/pkg/vm/testcases/bytecode/super_calls.dart.expect
index 64c96cf..c234538 100644
--- a/pkg/vm/testcases/bytecode/super_calls.dart.expect
+++ b/pkg/vm/testcases/bytecode/super_calls.dart.expect
@@ -11,13 +11,12 @@
   PushConstant         CP#1
   IndirectStaticCall   1, CP#0
   Drop1
-  PushConstant         CP#2
+  PushNull
   ReturnTOS
 }
 ConstantPool {
   [0] = ArgDesc num-args 1, num-type-args 0, names []
   [1] = StaticICData target 'dart.core::Object::', arg-desc CP#0
-  [2] = Null
 }
 ]  synthetic constructor •() → void
     : super core::Object::•()
@@ -27,45 +26,22 @@
   Entry                1
   CheckStack
   CheckFunctionTypeArgs 1, 0
-  Push                 FP[-6]
-  PushConstant         CP#0
-  Push                 r0
-  PushConstant         CP#1
-  PushConstant         CP#2
-  AssertAssignable     0, CP#3
-  Drop1
-  Push                 FP[-5]
-  PushConstant         CP#0
-  PushConstant         CP#0
-  PushConstant         CP#4
-  PushConstant         CP#5
-  AssertAssignable     1, CP#6
-  Drop1
-  PushConstant         CP#0
+  PushNull
   ReturnTOS
 }
 ConstantPool {
-  [0] = Null
-  [1] = Type #lib::Base1::foo::T
-  [2] = String 'a1'
-  [3] = SubtypeTestCache
-  [4] = Type dart.core::int
-  [5] = String 'a2'
-  [6] = SubtypeTestCache
 }
 ]  method foo<T extends core::Object = dynamic>(self::Base1::foo::T a1, core::int a2) → void {}
 [@vm.bytecode=
 Bytecode {
   Entry                0
   CheckStack
-  PushConstant         CP#0
+  PushInt              42
   ReturnTOS
-  PushConstant         CP#1
+  PushNull
   ReturnTOS
 }
 ConstantPool {
-  [0] = Int 42
-  [1] = Null
 }
 ]  get bar() → dynamic
     return 42;
@@ -73,21 +49,10 @@
 Bytecode {
   Entry                0
   CheckStack
-  Push                 FP[-5]
-  PushConstant         CP#0
-  PushConstant         CP#0
-  PushConstant         CP#1
-  PushConstant         CP#2
-  AssertAssignable     1, CP#3
-  Drop1
-  PushConstant         CP#0
+  PushNull
   ReturnTOS
 }
 ConstantPool {
-  [0] = Null
-  [1] = Type dart.core::int
-  [2] = String 'x'
-  [3] = SubtypeTestCache
 }
 ]  set bazz(core::int x) → void {}
 }
@@ -100,13 +65,12 @@
   PushConstant         CP#1
   IndirectStaticCall   1, CP#0
   Drop1
-  PushConstant         CP#2
+  PushNull
   ReturnTOS
 }
 ConstantPool {
   [0] = ArgDesc num-args 1, num-type-args 0, names []
   [1] = StaticICData target '#lib::Base1::', arg-desc CP#0
-  [2] = Null
 }
 ]  synthetic constructor •() → void
     : super self::Base1::•()
@@ -115,33 +79,21 @@
 Bytecode {
   Entry                1
   CheckStack
-  Push                 FP[-5]
   PushConstant         CP#0
-  PushConstant         CP#0
-  PushConstant         CP#1
-  PushConstant         CP#2
-  AssertAssignable     1, CP#3
-  Drop1
-  PushConstant         CP#4
   Push                 FP[-6]
-  PushConstant         CP#5
-  PushConstant         CP#6
-  PushConstant         CP#8
-  IndirectStaticCall   4, CP#7
+  PushConstant         CP#1
+  PushInt              2
+  PushConstant         CP#3
+  IndirectStaticCall   4, CP#2
   ReturnTOS
-  PushConstant         CP#0
+  PushNull
   ReturnTOS
 }
 ConstantPool {
-  [0] = Null
-  [1] = Type dart.core::int
-  [2] = String 'x'
-  [3] = SubtypeTestCache
-  [4] = TypeArgs [dart.core::String]
-  [5] = String 'a1'
-  [6] = Int 2
-  [7] = ArgDesc num-args 3, num-type-args 1, names []
-  [8] = StaticICData target '#lib::Base1::foo', arg-desc CP#7
+  [0] = TypeArgs [dart.core::String]
+  [1] = String 'a1'
+  [2] = ArgDesc num-args 3, num-type-args 1, names []
+  [3] = StaticICData target '#lib::Base1::foo', arg-desc CP#2
 }
 ]  method testSuperCall(core::int x) → dynamic
     return super.{self::Base1::foo}<core::String>("a1", 2);
@@ -153,13 +105,12 @@
   PushConstant         CP#1
   IndirectStaticCall   1, CP#0
   ReturnTOS
-  PushConstant         CP#2
+  PushNull
   ReturnTOS
 }
 ConstantPool {
   [0] = ArgDesc num-args 1, num-type-args 0, names []
   [1] = StaticICData get target '#lib::Base1::foo', arg-desc CP#0
-  [2] = Null
 }
 ]  method testSuperTearOff() → dynamic
     return super.{self::Base1::foo};
@@ -171,13 +122,12 @@
   PushConstant         CP#1
   IndirectStaticCall   1, CP#0
   ReturnTOS
-  PushConstant         CP#2
+  PushNull
   ReturnTOS
 }
 ConstantPool {
   [0] = ArgDesc num-args 1, num-type-args 0, names []
   [1] = StaticICData get target '#lib::Base1::bar', arg-desc CP#0
-  [2] = Null
 }
 ]  method testSuperGet() → dynamic
     return super.{self::Base1::bar};
@@ -192,7 +142,7 @@
   PushConstant         CP#3
   InstanceCall         3, CP#5
   ReturnTOS
-  PushConstant         CP#6
+  PushNull
   ReturnTOS
 }
 ConstantPool {
@@ -201,8 +151,7 @@
   [2] = StaticICData get target '#lib::Base1::bar', arg-desc CP#1
   [3] = String 'param'
   [4] = ArgDesc num-args 2, num-type-args 1, names []
-  [5] = ICData target-name 'call', arg-desc CP#4
-  [6] = Null
+  [5] = ICData dynamic target-name 'call', arg-desc CP#4
 }
 ]  method testSuperCallViaGetter() → dynamic
     return [@vm.call-site-attributes.metadata=receiverType:dynamic] super.{self::Base1::bar}.call<core::int>("param");
@@ -211,18 +160,16 @@
   Entry                1
   CheckStack
   Push                 FP[-5]
-  PushConstant         CP#0
-  PushConstant         CP#2
-  IndirectStaticCall   2, CP#1
+  PushInt              3
+  PushConstant         CP#1
+  IndirectStaticCall   2, CP#0
   Drop1
-  PushConstant         CP#3
+  PushNull
   ReturnTOS
 }
 ConstantPool {
-  [0] = Int 3
-  [1] = ArgDesc num-args 2, num-type-args 0, names []
-  [2] = StaticICData set target '#lib::Base1::bazz', arg-desc CP#1
-  [3] = Null
+  [0] = ArgDesc num-args 2, num-type-args 0, names []
+  [1] = StaticICData set target '#lib::Base1::bazz', arg-desc CP#0
 }
 ]  method testSuperSet() → dynamic {
     super.{self::Base1::bazz} = 3;
@@ -237,13 +184,12 @@
   PushConstant         CP#1
   IndirectStaticCall   1, CP#0
   Drop1
-  PushConstant         CP#2
+  PushNull
   ReturnTOS
 }
 ConstantPool {
   [0] = ArgDesc num-args 1, num-type-args 0, names []
   [1] = StaticICData target 'dart.core::Object::', arg-desc CP#0
-  [2] = Null
 }
 ]  synthetic constructor •() → void
     : super core::Object::•()
@@ -261,13 +207,12 @@
   PushConstant         CP#1
   IndirectStaticCall   1, CP#0
   Drop1
-  PushConstant         CP#2
+  PushNull
   ReturnTOS
 }
 ConstantPool {
   [0] = ArgDesc num-args 1, num-type-args 0, names []
   [1] = StaticICData target '#lib::Base2::', arg-desc CP#0
-  [2] = Null
 }
 ]  synthetic constructor •() → void
     : super self::Base2::•()
@@ -276,71 +221,53 @@
 Bytecode {
   Entry                1
   CheckStack
-  Push                 FP[-5]
-  PushConstant         CP#0
+  Push                 FP[-6]
   PushConstant         CP#0
   PushConstant         CP#1
   PushConstant         CP#2
-  AssertAssignable     1, CP#3
-  Drop1
-  Push                 FP[-6]
-  PushConstant         CP#4
-  PushConstant         CP#5
-  PushConstant         CP#6
-  PushConstant         CP#7
+  PushInt              5
   CreateArrayTOS
   StoreLocal           r0
   Push                 r0
-  PushConstant         CP#8
-  PushConstant         CP#9
+  PushInt              0
+  PushConstant         CP#3
   StoreIndexedTOS
   Push                 r0
-  PushConstant         CP#10
+  PushInt              1
   Push                 FP[-6]
   StoreIndexedTOS
   Push                 r0
-  PushConstant         CP#11
-  PushConstant         CP#12
+  PushInt              2
+  PushConstant         CP#4
   StoreIndexedTOS
   Push                 r0
-  PushConstant         CP#13
-  PushConstant         CP#14
+  PushInt              3
+  PushConstant         CP#5
   StoreIndexedTOS
   Push                 r0
-  PushConstant         CP#15
+  PushInt              4
+  PushInt              5
+  StoreIndexedTOS
+  PushTrue
   PushConstant         CP#7
-  StoreIndexedTOS
-  PushConstant         CP#16
-  PushConstant         CP#18
-  IndirectStaticCall   4, CP#17
-  PushConstant         CP#20
-  IndirectStaticCall   2, CP#19
+  IndirectStaticCall   4, CP#6
+  PushConstant         CP#9
+  IndirectStaticCall   2, CP#8
   ReturnTOS
-  PushConstant         CP#0
+  PushNull
   ReturnTOS
 }
 ConstantPool {
-  [0] = Null
-  [1] = Type dart.core::int
-  [2] = String 'x'
-  [3] = SubtypeTestCache
-  [4] = String 'foo'
-  [5] = ArgDesc num-args 4, num-type-args 1, names []
-  [6] = TypeArgs [dynamic]
-  [7] = Int 5
-  [8] = Int 0
-  [9] = TypeArgs [dart.core::double]
-  [10] = Int 1
-  [11] = Int 2
-  [12] = String 'a1'
-  [13] = Int 3
-  [14] = Double 3.14
-  [15] = Int 4
-  [16] = Bool true
-  [17] = ArgDesc num-args 4, num-type-args 0, names []
-  [18] = StaticICData target 'dart.core::_InvocationMirror::_allocateInvocationMirror', arg-desc CP#17
-  [19] = ArgDesc num-args 2, num-type-args 0, names []
-  [20] = StaticICData target 'dart.core::Object::noSuchMethod', arg-desc CP#19
+  [0] = String 'foo'
+  [1] = ArgDesc num-args 4, num-type-args 1, names []
+  [2] = TypeArgs [dynamic]
+  [3] = TypeArgs [dart.core::double]
+  [4] = String 'a1'
+  [5] = Double 3.14
+  [6] = ArgDesc num-args 4, num-type-args 0, names []
+  [7] = StaticICData target 'dart.core::_InvocationMirror::_allocateInvocationMirror', arg-desc CP#6
+  [8] = ArgDesc num-args 2, num-type-args 0, names []
+  [9] = StaticICData target 'dart.core::Object::noSuchMethod', arg-desc CP#8
 }
 ]  method testSuperCall(core::int x) → dynamic
     return super.{self::Base2::foo}<core::double>("a1", 3.14, 5);
@@ -352,34 +279,30 @@
   PushConstant         CP#0
   PushConstant         CP#1
   PushConstant         CP#2
-  PushConstant         CP#3
+  PushInt              1
   CreateArrayTOS
   StoreLocal           r0
   Push                 r0
-  PushConstant         CP#4
+  PushInt              0
   Push                 FP[-5]
   StoreIndexedTOS
-  PushConstant         CP#5
-  PushConstant         CP#7
-  IndirectStaticCall   4, CP#6
-  PushConstant         CP#9
-  IndirectStaticCall   2, CP#8
+  PushTrue
+  PushConstant         CP#4
+  IndirectStaticCall   4, CP#3
+  PushConstant         CP#6
+  IndirectStaticCall   2, CP#5
   ReturnTOS
-  PushConstant         CP#10
+  PushNull
   ReturnTOS
 }
 ConstantPool {
   [0] = String 'foo'
   [1] = ArgDesc num-args 1, num-type-args 0, names []
   [2] = TypeArgs [dynamic]
-  [3] = Int 1
-  [4] = Int 0
-  [5] = Bool true
-  [6] = ArgDesc num-args 4, num-type-args 0, names []
-  [7] = StaticICData target 'dart.core::_InvocationMirror::_allocateInvocationMirror', arg-desc CP#6
-  [8] = ArgDesc num-args 2, num-type-args 0, names []
-  [9] = StaticICData target 'dart.core::Object::noSuchMethod', arg-desc CP#8
-  [10] = Null
+  [3] = ArgDesc num-args 4, num-type-args 0, names []
+  [4] = StaticICData target 'dart.core::_InvocationMirror::_allocateInvocationMirror', arg-desc CP#3
+  [5] = ArgDesc num-args 2, num-type-args 0, names []
+  [6] = StaticICData target 'dart.core::Object::noSuchMethod', arg-desc CP#5
 }
 ]  method testSuperTearOff() → dynamic
     return super.{self::Base2::foo};
@@ -391,34 +314,30 @@
   PushConstant         CP#0
   PushConstant         CP#1
   PushConstant         CP#2
-  PushConstant         CP#3
+  PushInt              1
   CreateArrayTOS
   StoreLocal           r0
   Push                 r0
-  PushConstant         CP#4
+  PushInt              0
   Push                 FP[-5]
   StoreIndexedTOS
-  PushConstant         CP#5
-  PushConstant         CP#7
-  IndirectStaticCall   4, CP#6
-  PushConstant         CP#9
-  IndirectStaticCall   2, CP#8
+  PushTrue
+  PushConstant         CP#4
+  IndirectStaticCall   4, CP#3
+  PushConstant         CP#6
+  IndirectStaticCall   2, CP#5
   ReturnTOS
-  PushConstant         CP#10
+  PushNull
   ReturnTOS
 }
 ConstantPool {
   [0] = String 'bar'
   [1] = ArgDesc num-args 1, num-type-args 0, names []
   [2] = TypeArgs [dynamic]
-  [3] = Int 1
-  [4] = Int 0
-  [5] = Bool true
-  [6] = ArgDesc num-args 4, num-type-args 0, names []
-  [7] = StaticICData target 'dart.core::_InvocationMirror::_allocateInvocationMirror', arg-desc CP#6
-  [8] = ArgDesc num-args 2, num-type-args 0, names []
-  [9] = StaticICData target 'dart.core::Object::noSuchMethod', arg-desc CP#8
-  [10] = Null
+  [3] = ArgDesc num-args 4, num-type-args 0, names []
+  [4] = StaticICData target 'dart.core::_InvocationMirror::_allocateInvocationMirror', arg-desc CP#3
+  [5] = ArgDesc num-args 2, num-type-args 0, names []
+  [6] = StaticICData target 'dart.core::Object::noSuchMethod', arg-desc CP#5
 }
 ]  method testSuperGet() → dynamic
     return super.{self::Base2::bar};
@@ -431,22 +350,22 @@
   PushConstant         CP#1
   PushConstant         CP#2
   PushConstant         CP#3
-  PushConstant         CP#4
+  PushInt              1
   CreateArrayTOS
   StoreLocal           r0
   Push                 r0
-  PushConstant         CP#5
+  PushInt              0
   Push                 FP[-5]
   StoreIndexedTOS
-  PushConstant         CP#6
+  PushTrue
+  PushConstant         CP#5
+  IndirectStaticCall   4, CP#4
+  PushConstant         CP#7
+  IndirectStaticCall   2, CP#6
   PushConstant         CP#8
-  IndirectStaticCall   4, CP#7
-  PushConstant         CP#10
-  IndirectStaticCall   2, CP#9
-  PushConstant         CP#11
-  InstanceCall         3, CP#13
+  InstanceCall         3, CP#10
   ReturnTOS
-  PushConstant         CP#14
+  PushNull
   ReturnTOS
 }
 ConstantPool {
@@ -454,17 +373,13 @@
   [1] = String 'bar'
   [2] = ArgDesc num-args 1, num-type-args 0, names []
   [3] = TypeArgs [dynamic]
-  [4] = Int 1
-  [5] = Int 0
-  [6] = Bool true
-  [7] = ArgDesc num-args 4, num-type-args 0, names []
-  [8] = StaticICData target 'dart.core::_InvocationMirror::_allocateInvocationMirror', arg-desc CP#7
-  [9] = ArgDesc num-args 2, num-type-args 0, names []
-  [10] = StaticICData target 'dart.core::Object::noSuchMethod', arg-desc CP#9
-  [11] = String 'param'
-  [12] = ArgDesc num-args 2, num-type-args 1, names []
-  [13] = ICData target-name 'call', arg-desc CP#12
-  [14] = Null
+  [4] = ArgDesc num-args 4, num-type-args 0, names []
+  [5] = StaticICData target 'dart.core::_InvocationMirror::_allocateInvocationMirror', arg-desc CP#4
+  [6] = ArgDesc num-args 2, num-type-args 0, names []
+  [7] = StaticICData target 'dart.core::Object::noSuchMethod', arg-desc CP#6
+  [8] = String 'param'
+  [9] = ArgDesc num-args 2, num-type-args 1, names []
+  [10] = ICData dynamic target-name 'call', arg-desc CP#9
 }
 ]  method testSuperCallViaGetter() → dynamic
     return [@vm.call-site-attributes.metadata=receiverType:dynamic] super.{self::Base2::bar}.call<core::int>("param");
@@ -476,39 +391,33 @@
   PushConstant         CP#0
   PushConstant         CP#1
   PushConstant         CP#2
-  PushConstant         CP#3
+  PushInt              2
   CreateArrayTOS
   StoreLocal           r0
   Push                 r0
-  PushConstant         CP#4
+  PushInt              0
   Push                 FP[-5]
   StoreIndexedTOS
   Push                 r0
-  PushConstant         CP#5
-  PushConstant         CP#6
+  PushInt              1
+  PushInt              3
   StoreIndexedTOS
-  PushConstant         CP#7
-  PushConstant         CP#9
-  IndirectStaticCall   4, CP#8
-  PushConstant         CP#10
+  PushTrue
+  PushConstant         CP#4
+  IndirectStaticCall   4, CP#3
+  PushConstant         CP#5
   IndirectStaticCall   2, CP#1
   Drop1
-  PushConstant         CP#11
+  PushNull
   ReturnTOS
 }
 ConstantPool {
   [0] = String 'bazz'
   [1] = ArgDesc num-args 2, num-type-args 0, names []
   [2] = TypeArgs [dynamic]
-  [3] = Int 2
-  [4] = Int 0
-  [5] = Int 1
-  [6] = Int 3
-  [7] = Bool true
-  [8] = ArgDesc num-args 4, num-type-args 0, names []
-  [9] = StaticICData target 'dart.core::_InvocationMirror::_allocateInvocationMirror', arg-desc CP#8
-  [10] = StaticICData target 'dart.core::Object::noSuchMethod', arg-desc CP#1
-  [11] = Null
+  [3] = ArgDesc num-args 4, num-type-args 0, names []
+  [4] = StaticICData target 'dart.core::_InvocationMirror::_allocateInvocationMirror', arg-desc CP#3
+  [5] = StaticICData target 'dart.core::Object::noSuchMethod', arg-desc CP#1
 }
 ]  method testSuperSet() → dynamic {
     super.{self::Base2::bazz} = 3;
@@ -518,10 +427,9 @@
 Bytecode {
   Entry                0
   CheckStack
-  PushConstant         CP#0
+  PushNull
   ReturnTOS
 }
 ConstantPool {
-  [0] = Null
 }
 ]static method main() → dynamic {}
diff --git a/pkg/vm/testcases/bytecode/switch.dart.expect b/pkg/vm/testcases/bytecode/switch.dart.expect
index ed998c2..bf66bbf 100644
--- a/pkg/vm/testcases/bytecode/switch.dart.expect
+++ b/pkg/vm/testcases/bytecode/switch.dart.expect
@@ -6,60 +6,52 @@
 Bytecode {
   Entry                2
   CheckStack
-  PushConstant         CP#0
+  PushNull
   PopLocal             r0
   Push                 FP[-5]
   PopLocal             r1
   Push                 r1
-  PushConstant         CP#2
-  InstanceCall         2, CP#3
-  PushConstant         CP#4
+  PushInt              1
+  InstanceCall         2, CP#1
+  PushTrue
   IfEqStrictTOS
   Jump                 L1
   Push                 r1
-  PushConstant         CP#5
-  InstanceCall         2, CP#6
-  PushConstant         CP#4
+  PushInt              2
+  InstanceCall         2, CP#2
+  PushTrue
   IfEqStrictTOS
   Jump                 L2
   Push                 r1
-  PushConstant         CP#7
-  InstanceCall         2, CP#8
-  PushConstant         CP#4
+  PushInt              3
+  InstanceCall         2, CP#3
+  PushTrue
   IfEqStrictTOS
   Jump                 L3
   Jump                 L4
 L1:
-  PushConstant         CP#9
+  PushInt              11
   PopLocal             r0
   Jump                 L4
 L2:
-  PushConstant         CP#10
+  PushInt              22
   PopLocal             r0
   Jump                 L4
 L3:
-  PushConstant         CP#11
+  PushInt              33
   PopLocal             r0
   Jump                 L4
 L4:
   Push                 r0
   ReturnTOS
-  PushConstant         CP#0
+  PushNull
   ReturnTOS
 }
 ConstantPool {
-  [0] = Null
-  [1] = ArgDesc num-args 2, num-type-args 0, names []
-  [2] = Int 1
-  [3] = ICData target-name '==', arg-desc CP#1
-  [4] = Bool true
-  [5] = Int 2
-  [6] = ICData target-name '==', arg-desc CP#1
-  [7] = Int 3
-  [8] = ICData target-name '==', arg-desc CP#1
-  [9] = Int 11
-  [10] = Int 22
-  [11] = Int 33
+  [0] = ArgDesc num-args 2, num-type-args 0, names []
+  [1] = ICData target-name '==', arg-desc CP#0
+  [2] = ICData target-name '==', arg-desc CP#0
+  [3] = ICData target-name '==', arg-desc CP#0
 }
 ]static method foo1(core::int x) → core::int {
   core::int y;
@@ -90,83 +82,72 @@
 Bytecode {
   Entry                2
   CheckStack
-  PushConstant         CP#0
+  PushNull
   PopLocal             r0
   Push                 FP[-5]
   PopLocal             r1
   Push                 r1
-  PushConstant         CP#2
+  PushInt              1
+  InstanceCall         2, CP#1
+  PushTrue
+  IfEqStrictTOS
+  Jump                 L1
+  Push                 r1
+  PushInt              2
+  InstanceCall         2, CP#2
+  PushTrue
+  IfEqStrictTOS
+  Jump                 L1
+  Push                 r1
+  PushInt              3
   InstanceCall         2, CP#3
-  PushConstant         CP#4
+  PushTrue
   IfEqStrictTOS
   Jump                 L1
   Push                 r1
-  PushConstant         CP#5
+  PushInt              4
+  InstanceCall         2, CP#4
+  PushTrue
+  IfEqStrictTOS
+  Jump                 L2
+  Push                 r1
+  PushInt              5
+  InstanceCall         2, CP#5
+  PushTrue
+  IfEqStrictTOS
+  Jump                 L2
+  Push                 r1
+  PushInt              6
   InstanceCall         2, CP#6
-  PushConstant         CP#4
-  IfEqStrictTOS
-  Jump                 L1
-  Push                 r1
-  PushConstant         CP#7
-  InstanceCall         2, CP#8
-  PushConstant         CP#4
-  IfEqStrictTOS
-  Jump                 L1
-  Push                 r1
-  PushConstant         CP#9
-  InstanceCall         2, CP#10
-  PushConstant         CP#4
-  IfEqStrictTOS
-  Jump                 L2
-  Push                 r1
-  PushConstant         CP#11
-  InstanceCall         2, CP#12
-  PushConstant         CP#4
-  IfEqStrictTOS
-  Jump                 L2
-  Push                 r1
-  PushConstant         CP#13
-  InstanceCall         2, CP#14
-  PushConstant         CP#4
+  PushTrue
   IfEqStrictTOS
   Jump                 L2
   Jump                 L3
 L1:
-  PushConstant         CP#15
+  PushInt              11
   PopLocal             r0
   Jump                 L4
 L2:
-  PushConstant         CP#16
+  PushInt              22
   PopLocal             r0
   Jump                 L4
 L3:
-  PushConstant         CP#17
+  PushInt              33
   PopLocal             r0
 L4:
   Push                 r0
   ReturnTOS
-  PushConstant         CP#0
+  PushNull
   ReturnTOS
 }
 ConstantPool {
-  [0] = Null
-  [1] = ArgDesc num-args 2, num-type-args 0, names []
-  [2] = Int 1
-  [3] = ICData target-name '==', arg-desc CP#1
-  [4] = Bool true
-  [5] = Int 2
-  [6] = ICData target-name '==', arg-desc CP#1
-  [7] = Int 3
-  [8] = ICData target-name '==', arg-desc CP#1
-  [9] = Int 4
-  [10] = ICData target-name '==', arg-desc CP#1
-  [11] = Int 5
-  [12] = ICData target-name '==', arg-desc CP#1
-  [13] = Int 6
-  [14] = ICData target-name '==', arg-desc CP#1
-  [15] = Int 11
-  [16] = Int 22
-  [17] = Int 33
+  [0] = ArgDesc num-args 2, num-type-args 0, names []
+  [1] = ICData target-name '==', arg-desc CP#0
+  [2] = ICData target-name '==', arg-desc CP#0
+  [3] = ICData target-name '==', arg-desc CP#0
+  [4] = ICData target-name '==', arg-desc CP#0
+  [5] = ICData target-name '==', arg-desc CP#0
+  [6] = ICData target-name '==', arg-desc CP#0
 }
 ]static method foo2(core::int x) → core::int {
   core::int y;
@@ -200,84 +181,72 @@
 Bytecode {
   Entry                2
   CheckStack
-  PushConstant         CP#0
+  PushNull
   PopLocal             r0
   Push                 FP[-5]
   PopLocal             r1
   Push                 r1
-  PushConstant         CP#2
+  PushInt              1
+  InstanceCall         2, CP#1
+  PushTrue
+  IfEqStrictTOS
+  Jump                 L1
+  Push                 r1
+  PushInt              2
+  InstanceCall         2, CP#2
+  PushTrue
+  IfEqStrictTOS
+  Jump                 L1
+  Push                 r1
+  PushInt              3
   InstanceCall         2, CP#3
-  PushConstant         CP#4
+  PushTrue
   IfEqStrictTOS
   Jump                 L1
   Push                 r1
-  PushConstant         CP#5
+  PushInt              4
+  InstanceCall         2, CP#4
+  PushTrue
+  IfEqStrictTOS
+  Jump                 L2
+  Push                 r1
+  PushInt              5
+  InstanceCall         2, CP#5
+  PushTrue
+  IfEqStrictTOS
+  Jump                 L2
+  Push                 r1
+  PushInt              6
   InstanceCall         2, CP#6
-  PushConstant         CP#4
-  IfEqStrictTOS
-  Jump                 L1
-  Push                 r1
-  PushConstant         CP#7
-  InstanceCall         2, CP#8
-  PushConstant         CP#4
-  IfEqStrictTOS
-  Jump                 L1
-  Push                 r1
-  PushConstant         CP#9
-  InstanceCall         2, CP#10
-  PushConstant         CP#4
-  IfEqStrictTOS
-  Jump                 L2
-  Push                 r1
-  PushConstant         CP#11
-  InstanceCall         2, CP#12
-  PushConstant         CP#4
-  IfEqStrictTOS
-  Jump                 L2
-  Push                 r1
-  PushConstant         CP#13
-  InstanceCall         2, CP#14
-  PushConstant         CP#4
+  PushTrue
   IfEqStrictTOS
   Jump                 L2
   Jump                 L3
 L1:
-  PushConstant         CP#15
+  PushInt              11
   PopLocal             r0
   Jump                 L2
 L2:
-  PushConstant         CP#16
+  PushInt              22
   PopLocal             r0
-  PushConstant         CP#17
+  PushInt              42
   ReturnTOS
 L3:
-  PushConstant         CP#18
+  PushInt              33
   PopLocal             r0
   Push                 r0
   ReturnTOS
-  PushConstant         CP#0
+  PushNull
   ReturnTOS
 }
 ConstantPool {
-  [0] = Null
-  [1] = ArgDesc num-args 2, num-type-args 0, names []
-  [2] = Int 1
-  [3] = ICData target-name '==', arg-desc CP#1
-  [4] = Bool true
-  [5] = Int 2
-  [6] = ICData target-name '==', arg-desc CP#1
-  [7] = Int 3
-  [8] = ICData target-name '==', arg-desc CP#1
-  [9] = Int 4
-  [10] = ICData target-name '==', arg-desc CP#1
-  [11] = Int 5
-  [12] = ICData target-name '==', arg-desc CP#1
-  [13] = Int 6
-  [14] = ICData target-name '==', arg-desc CP#1
-  [15] = Int 11
-  [16] = Int 22
-  [17] = Int 42
-  [18] = Int 33
+  [0] = ArgDesc num-args 2, num-type-args 0, names []
+  [1] = ICData target-name '==', arg-desc CP#0
+  [2] = ICData target-name '==', arg-desc CP#0
+  [3] = ICData target-name '==', arg-desc CP#0
+  [4] = ICData target-name '==', arg-desc CP#0
+  [5] = ICData target-name '==', arg-desc CP#0
+  [6] = ICData target-name '==', arg-desc CP#0
 }
 ]static method foo3(core::int x) → core::int {
   core::int y;
@@ -310,10 +279,9 @@
 Bytecode {
   Entry                0
   CheckStack
-  PushConstant         CP#0
+  PushNull
   ReturnTOS
 }
 ConstantPool {
-  [0] = Null
 }
 ]static method main() → dynamic {}
diff --git a/pkg/vm/testcases/bytecode/try_blocks.dart.expect b/pkg/vm/testcases/bytecode/try_blocks.dart.expect
index bd7e762..2158d27 100644
--- a/pkg/vm/testcases/bytecode/try_blocks.dart.expect
+++ b/pkg/vm/testcases/bytecode/try_blocks.dart.expect
@@ -19,26 +19,26 @@
   MoveSpecial          r1, stackTrace
   Push                 r0
   PopLocal             r2
-  PushConstant         CP#4
-  PushConstant         CP#5
+  PushNull
+  PushInt              2
   CreateArrayTOS
   StoreLocal           r3
   Push                 r3
-  PushConstant         CP#6
-  PushConstant         CP#7
+  PushInt              0
+  PushConstant         CP#4
   StoreIndexedTOS
   Push                 r3
-  PushConstant         CP#8
+  PushInt              1
   Push                 r2
   StoreIndexedTOS
-  PushConstant         CP#9
+  PushConstant         CP#5
   IndirectStaticCall   1, CP#1
-  PushConstant         CP#10
+  PushConstant         CP#6
   IndirectStaticCall   1, CP#1
   Drop1
   Jump                 L1
 L1:
-  PushConstant         CP#4
+  PushNull
   ReturnTOS
 }
 ExceptionsTable {
@@ -49,13 +49,9 @@
   [1] = ArgDesc num-args 1, num-type-args 0, names []
   [2] = StaticICData target 'dart.core::print', arg-desc CP#1
   [3] = Type dynamic
-  [4] = Null
-  [5] = Int 2
-  [6] = Int 0
-  [7] = String 'caught '
-  [8] = Int 1
-  [9] = StaticICData target 'dart.core::_StringBase::_interpolate', arg-desc CP#1
-  [10] = StaticICData target 'dart.core::print', arg-desc CP#1
+  [4] = String 'caught '
+  [5] = StaticICData target 'dart.core::_StringBase::_interpolate', arg-desc CP#1
+  [6] = StaticICData target 'dart.core::print', arg-desc CP#1
 }
 ]static method testTryCatch1() → dynamic {
   try {
@@ -81,83 +77,83 @@
   MoveSpecial          r0, exception
   MoveSpecial          r1, stackTrace
   Push                 r0
-  PushConstant         CP#4
-  PushConstant         CP#4
+  PushNull
+  PushNull
   PushConstant         CP#3
-  InstanceCall         4, CP#6
-  PushConstant         CP#7
+  InstanceCall         4, CP#5
+  PushTrue
   IfNeStrictTOS
   Jump                 L2
-  PushConstant         CP#8
-  PushConstant         CP#9
+  PushConstant         CP#6
+  PushConstant         CP#7
   IndirectStaticCall   1, CP#1
   Drop1
   Jump                 L1
 L2:
   Push                 r0
-  PushConstant         CP#4
-  PushConstant         CP#4
-  PushConstant         CP#10
-  InstanceCall         4, CP#11
-  PushConstant         CP#7
+  PushNull
+  PushNull
+  PushConstant         CP#8
+  InstanceCall         4, CP#9
+  PushTrue
   IfNeStrictTOS
   Jump                 L3
   Push                 r0
   PopLocal             r2
-  PushConstant         CP#4
-  PushConstant         CP#12
+  PushNull
+  PushInt              2
   CreateArrayTOS
   StoreLocal           r3
   Push                 r3
-  PushConstant         CP#13
-  PushConstant         CP#14
+  PushInt              0
+  PushConstant         CP#10
   StoreIndexedTOS
   Push                 r3
-  PushConstant         CP#15
+  PushInt              1
   Push                 r2
   StoreIndexedTOS
-  PushConstant         CP#16
+  PushConstant         CP#11
   IndirectStaticCall   1, CP#1
-  PushConstant         CP#17
+  PushConstant         CP#12
   IndirectStaticCall   1, CP#1
   Drop1
   Jump                 L1
 L3:
   Push                 r0
-  PushConstant         CP#4
-  PushConstant         CP#4
-  PushConstant         CP#18
-  InstanceCall         4, CP#19
-  PushConstant         CP#7
+  PushNull
+  PushNull
+  PushConstant         CP#13
+  InstanceCall         4, CP#14
+  PushTrue
   IfNeStrictTOS
   Jump                 L4
   Push                 r0
   PopLocal             r2
   Push                 r1
   PopLocal             r3
-  PushConstant         CP#4
-  PushConstant         CP#20
+  PushNull
+  PushInt              4
   CreateArrayTOS
   StoreLocal           r4
   Push                 r4
-  PushConstant         CP#13
-  PushConstant         CP#21
+  PushInt              0
+  PushConstant         CP#15
   StoreIndexedTOS
   Push                 r4
-  PushConstant         CP#15
+  PushInt              1
   Push                 r2
   StoreIndexedTOS
   Push                 r4
-  PushConstant         CP#12
-  PushConstant         CP#22
+  PushInt              2
+  PushConstant         CP#16
   StoreIndexedTOS
   Push                 r4
-  PushConstant         CP#23
+  PushInt              3
   Push                 r3
   StoreIndexedTOS
-  PushConstant         CP#24
+  PushConstant         CP#17
   IndirectStaticCall   1, CP#1
-  PushConstant         CP#25
+  PushConstant         CP#18
   IndirectStaticCall   1, CP#1
   Drop1
   Jump                 L1
@@ -166,70 +162,63 @@
   PopLocal             r2
   Push                 r1
   PopLocal             r3
-  PushConstant         CP#4
-  PushConstant         CP#20
+  PushNull
+  PushInt              4
   CreateArrayTOS
   StoreLocal           r4
   Push                 r4
-  PushConstant         CP#13
-  PushConstant         CP#27
+  PushInt              0
+  PushConstant         CP#20
   StoreIndexedTOS
   Push                 r4
-  PushConstant         CP#15
+  PushInt              1
   Push                 r2
   StoreIndexedTOS
   Push                 r4
-  PushConstant         CP#12
-  PushConstant         CP#22
+  PushInt              2
+  PushConstant         CP#16
   StoreIndexedTOS
   Push                 r4
-  PushConstant         CP#23
+  PushInt              3
   Push                 r3
   StoreIndexedTOS
-  PushConstant         CP#28
+  PushConstant         CP#21
   IndirectStaticCall   1, CP#1
-  PushConstant         CP#29
+  PushConstant         CP#22
   IndirectStaticCall   1, CP#1
   Drop1
   Jump                 L1
 L1:
-  PushConstant         CP#4
+  PushNull
   ReturnTOS
 }
 ExceptionsTable {
-  try-index 0, outer -1, start 2, end 7, handler 7, needs-stack-trace, types [CP#3, CP#10, CP#18, CP#26]
+  try-index 0, outer -1, start 2, end 7, handler 7, needs-stack-trace, types [CP#3, CP#8, CP#13, CP#19]
 }
 ConstantPool {
   [0] = String 'danger!'
   [1] = ArgDesc num-args 1, num-type-args 0, names []
   [2] = StaticICData target 'dart.core::print', arg-desc CP#1
   [3] = Type dart.core::TypeError
-  [4] = Null
-  [5] = ArgDesc num-args 4, num-type-args 0, names []
-  [6] = ICData target-name 'dart.core::_instanceOf', arg-desc CP#5
-  [7] = Bool true
-  [8] = String 'caught type error'
-  [9] = StaticICData target 'dart.core::print', arg-desc CP#1
-  [10] = Type dart.core::AssertionError
-  [11] = ICData target-name 'dart.core::_instanceOf', arg-desc CP#5
-  [12] = Int 2
-  [13] = Int 0
-  [14] = String 'caught assertion error '
-  [15] = Int 1
-  [16] = StaticICData target 'dart.core::_StringBase::_interpolate', arg-desc CP#1
-  [17] = StaticICData target 'dart.core::print', arg-desc CP#1
-  [18] = Type dart.core::Error
-  [19] = ICData target-name 'dart.core::_instanceOf', arg-desc CP#5
-  [20] = Int 4
-  [21] = String 'caught error '
-  [22] = String ' '
-  [23] = Int 3
-  [24] = StaticICData target 'dart.core::_StringBase::_interpolate', arg-desc CP#1
-  [25] = StaticICData target 'dart.core::print', arg-desc CP#1
-  [26] = Type dynamic
-  [27] = String 'caught something '
-  [28] = StaticICData target 'dart.core::_StringBase::_interpolate', arg-desc CP#1
-  [29] = StaticICData target 'dart.core::print', arg-desc CP#1
+  [4] = ArgDesc num-args 4, num-type-args 0, names []
+  [5] = ICData target-name 'dart.core::_instanceOf', arg-desc CP#4
+  [6] = String 'caught type error'
+  [7] = StaticICData target 'dart.core::print', arg-desc CP#1
+  [8] = Type dart.core::AssertionError
+  [9] = ICData target-name 'dart.core::_instanceOf', arg-desc CP#4
+  [10] = String 'caught assertion error '
+  [11] = StaticICData target 'dart.core::_StringBase::_interpolate', arg-desc CP#1
+  [12] = StaticICData target 'dart.core::print', arg-desc CP#1
+  [13] = Type dart.core::Error
+  [14] = ICData target-name 'dart.core::_instanceOf', arg-desc CP#4
+  [15] = String 'caught error '
+  [16] = String ' '
+  [17] = StaticICData target 'dart.core::_StringBase::_interpolate', arg-desc CP#1
+  [18] = StaticICData target 'dart.core::print', arg-desc CP#1
+  [19] = Type dynamic
+  [20] = String 'caught something '
+  [21] = StaticICData target 'dart.core::_StringBase::_interpolate', arg-desc CP#1
+  [22] = StaticICData target 'dart.core::print', arg-desc CP#1
 }
 ]static method testTryCatch2() → dynamic {
   try {
@@ -255,39 +244,39 @@
   AllocateContext      3
   PopLocal             r0
   Push                 r0
-  PushConstant         CP#0
+  PushInt              1
   StoreContextVar      0
   Push                 r0
   PopLocal             r2
 Try #0 start:
   Push                 r0
-  PushConstant         CP#1
+  PushInt              2
   StoreContextVar      1
-  Allocate             CP#13
+  Allocate             CP#9
   StoreLocal           r5
   Push                 r5
-  PushConstant         CP#11
-  StoreFieldTOS        CP#14
+  PushNull
+  StoreFieldTOS        CP#10
   Push                 r5
-  PushConstant         CP#11
-  StoreFieldTOS        CP#16
+  PushNull
+  StoreFieldTOS        CP#12
   Push                 r5
-  PushConstant         CP#18
-  StoreFieldTOS        CP#19
+  PushConstant         CP#14
+  StoreFieldTOS        CP#15
   Push                 r5
-  PushConstant         CP#2
-  StoreFieldTOS        CP#21
+  PushConstant         CP#0
+  StoreFieldTOS        CP#17
   Push                 r5
   Push                 r0
-  StoreFieldTOS        CP#3
+  StoreFieldTOS        CP#1
   PopLocal             r4
   Push                 r4
-  InstanceCall         1, CP#23
+  InstanceCall         1, CP#19
   Drop1
   Push                 r0
   LoadContextVar       1
-  PushConstant         CP#24
-  IndirectStaticCall   1, CP#6
+  PushConstant         CP#20
+  IndirectStaticCall   1, CP#4
   Drop1
   Jump                 L1
 Try #0 end:
@@ -302,49 +291,49 @@
   Push                 r0
   Push                 r3
   StoreContextVar      2
-  PushConstant         CP#11
-  PushConstant         CP#25
+  PushNull
+  PushInt              4
   CreateArrayTOS
   StoreLocal           r5
   Push                 r5
-  PushConstant         CP#26
-  PushConstant         CP#27
+  PushInt              0
+  PushConstant         CP#21
   StoreIndexedTOS
   Push                 r5
-  PushConstant         CP#0
+  PushInt              1
   Push                 r4
   StoreIndexedTOS
   Push                 r5
-  PushConstant         CP#1
-  PushConstant         CP#28
+  PushInt              2
+  PushConstant         CP#22
   StoreIndexedTOS
   Push                 r5
-  PushConstant         CP#10
+  PushInt              3
   Push                 r0
   LoadContextVar       2
   StoreIndexedTOS
-  PushConstant         CP#29
-  IndirectStaticCall   1, CP#6
-  PushConstant         CP#30
-  IndirectStaticCall   1, CP#6
+  PushConstant         CP#23
+  IndirectStaticCall   1, CP#4
+  PushConstant         CP#24
+  IndirectStaticCall   1, CP#4
   Drop1
-  Allocate             CP#13
+  Allocate             CP#9
   StoreLocal           r5
   Push                 r5
-  PushConstant         CP#11
-  StoreFieldTOS        CP#14
+  PushNull
+  StoreFieldTOS        CP#10
   Push                 r5
-  PushConstant         CP#11
-  StoreFieldTOS        CP#16
+  PushNull
+  StoreFieldTOS        CP#12
   Push                 r5
-  PushConstant         CP#18
-  StoreFieldTOS        CP#19
+  PushConstant         CP#14
+  StoreFieldTOS        CP#15
   Push                 r5
-  PushConstant         CP#31
-  StoreFieldTOS        CP#21
+  PushConstant         CP#25
+  StoreFieldTOS        CP#17
   Push                 r5
   Push                 r0
-  StoreFieldTOS        CP#3
+  StoreFieldTOS        CP#1
   PopLocal             r6
   Push                 r6
   ReturnTOS
@@ -353,69 +342,62 @@
   Push                 r0
   LoadContextParent
   PopLocal             r0
-  PushConstant         CP#11
+  PushNull
   ReturnTOS
 }
 ExceptionsTable {
-  try-index 0, outer -1, start 9, end 39, handler 39, needs-stack-trace, types [CP#8]
+  try-index 0, outer -1, start 9, end 39, handler 39, needs-stack-trace, types [CP#6]
 }
 ConstantPool {
-  [0] = Int 1
-  [1] = Int 2
-  [2] = ClosureFunction foo () → void;
-  [3] = InstanceField dart.core::_Closure::_context
-  [4] = Reserved
-  [5] = String 'danger foo'
-  [6] = ArgDesc num-args 1, num-type-args 0, names []
-  [7] = StaticICData target 'dart.core::print', arg-desc CP#6
-  [8] = Type dynamic
-  [9] = StaticICData target 'dart.core::print', arg-desc CP#6
-  [10] = Int 3
-  [11] = Null
-  [12] = EndClosureFunctionScope
-  [13] = Class dart.core::_Closure
-  [14] = InstanceField dart.core::_Closure::_instantiator_type_arguments
-  [15] = Reserved
-  [16] = InstanceField dart.core::_Closure::_function_type_arguments
-  [17] = Reserved
-  [18] = EmptyTypeArguments
-  [19] = InstanceField dart.core::_Closure::_delayed_type_arguments
-  [20] = Reserved
-  [21] = InstanceField dart.core::_Closure::_function
-  [22] = Reserved
-  [23] = ICData target-name 'call', arg-desc CP#6
-  [24] = StaticICData target 'dart.core::print', arg-desc CP#6
-  [25] = Int 4
-  [26] = Int 0
-  [27] = String 'caught '
-  [28] = String ' '
-  [29] = StaticICData target 'dart.core::_StringBase::_interpolate', arg-desc CP#6
-  [30] = StaticICData target 'dart.core::print', arg-desc CP#6
-  [31] = ClosureFunction bar () → void;
-  [32] = String 'danger bar'
-  [33] = StaticICData target 'dart.core::print', arg-desc CP#6
-  [34] = Type dart.core::Error
-  [35] = ArgDesc num-args 4, num-type-args 0, names []
-  [36] = ICData target-name 'dart.core::_instanceOf', arg-desc CP#35
-  [37] = Bool true
-  [38] = String 'error '
-  [39] = String ', captured stack trace: '
-  [40] = StaticICData target 'dart.core::_StringBase::_interpolate', arg-desc CP#6
-  [41] = StaticICData target 'dart.core::print', arg-desc CP#6
-  [42] = EndClosureFunctionScope
+  [0] = ClosureFunction foo () → void;
+  [1] = InstanceField dart.core::_Closure::_context
+  [2] = Reserved
+  [3] = String 'danger foo'
+  [4] = ArgDesc num-args 1, num-type-args 0, names []
+  [5] = StaticICData target 'dart.core::print', arg-desc CP#4
+  [6] = Type dynamic
+  [7] = StaticICData target 'dart.core::print', arg-desc CP#4
+  [8] = EndClosureFunctionScope
+  [9] = Class dart.core::_Closure
+  [10] = InstanceField dart.core::_Closure::_instantiator_type_arguments
+  [11] = Reserved
+  [12] = InstanceField dart.core::_Closure::_function_type_arguments
+  [13] = Reserved
+  [14] = EmptyTypeArguments
+  [15] = InstanceField dart.core::_Closure::_delayed_type_arguments
+  [16] = Reserved
+  [17] = InstanceField dart.core::_Closure::_function
+  [18] = Reserved
+  [19] = ICData dynamic target-name 'call', arg-desc CP#4
+  [20] = StaticICData target 'dart.core::print', arg-desc CP#4
+  [21] = String 'caught '
+  [22] = String ' '
+  [23] = StaticICData target 'dart.core::_StringBase::_interpolate', arg-desc CP#4
+  [24] = StaticICData target 'dart.core::print', arg-desc CP#4
+  [25] = ClosureFunction bar () → void;
+  [26] = String 'danger bar'
+  [27] = StaticICData target 'dart.core::print', arg-desc CP#4
+  [28] = Type dart.core::Error
+  [29] = ArgDesc num-args 4, num-type-args 0, names []
+  [30] = ICData target-name 'dart.core::_instanceOf', arg-desc CP#29
+  [31] = String 'error '
+  [32] = String ', captured stack trace: '
+  [33] = StaticICData target 'dart.core::_StringBase::_interpolate', arg-desc CP#4
+  [34] = StaticICData target 'dart.core::print', arg-desc CP#4
+  [35] = EndClosureFunctionScope
 }
-Closure CP#2 {
+Closure CP#0 {
   EntryFixed           1, 6
   CheckStack
   Push                 FP[-5]
-  LoadFieldTOS         CP#3
+  LoadFieldTOS         CP#1
   PopLocal             r0
   Push                 r0
   PopLocal             r2
 Try #0 start:
+  PushConstant         CP#3
   PushConstant         CP#5
-  PushConstant         CP#7
-  IndirectStaticCall   1, CP#6
+  IndirectStaticCall   1, CP#4
   Drop1
   Jump                 L1
 Try #0 end:
@@ -429,31 +411,31 @@
   PopLocal             r4
   Push                 r0
   LoadContextVar       0
-  PushConstant         CP#9
-  IndirectStaticCall   1, CP#6
+  PushConstant         CP#7
+  IndirectStaticCall   1, CP#4
   Drop1
   Push                 r0
-  PushConstant         CP#10
+  PushInt              3
   StoreContextVar      1
   Jump                 L1
 L1:
-  PushConstant         CP#11
+  PushNull
   ReturnTOS
 
 }
 
-Closure CP#31 {
+Closure CP#25 {
   EntryFixed           1, 6
   CheckStack
   Push                 FP[-5]
-  LoadFieldTOS         CP#3
+  LoadFieldTOS         CP#1
   PopLocal             r0
   Push                 r0
   PopLocal             r2
 Try #0 start:
-  PushConstant         CP#32
-  PushConstant         CP#33
-  IndirectStaticCall   1, CP#6
+  PushConstant         CP#26
+  PushConstant         CP#27
+  IndirectStaticCall   1, CP#4
   Drop1
   Jump                 L1
 Try #0 end:
@@ -464,40 +446,40 @@
   MoveSpecial          r2, exception
   MoveSpecial          r3, stackTrace
   Push                 r2
-  PushConstant         CP#11
-  PushConstant         CP#11
-  PushConstant         CP#34
-  InstanceCall         4, CP#36
-  PushConstant         CP#37
+  PushNull
+  PushNull
+  PushConstant         CP#28
+  InstanceCall         4, CP#30
+  PushTrue
   IfNeStrictTOS
   Jump                 L2
   Push                 r2
   PopLocal             r4
-  PushConstant         CP#11
-  PushConstant         CP#25
+  PushNull
+  PushInt              4
   CreateArrayTOS
   StoreLocal           r5
   Push                 r5
-  PushConstant         CP#26
-  PushConstant         CP#38
+  PushInt              0
+  PushConstant         CP#31
   StoreIndexedTOS
   Push                 r5
-  PushConstant         CP#0
+  PushInt              1
   Push                 r4
   StoreIndexedTOS
   Push                 r5
-  PushConstant         CP#1
-  PushConstant         CP#39
+  PushInt              2
+  PushConstant         CP#32
   StoreIndexedTOS
   Push                 r5
-  PushConstant         CP#10
+  PushInt              3
   Push                 r0
   LoadContextVar       2
   StoreIndexedTOS
-  PushConstant         CP#40
-  IndirectStaticCall   1, CP#6
-  PushConstant         CP#41
-  IndirectStaticCall   1, CP#6
+  PushConstant         CP#33
+  IndirectStaticCall   1, CP#4
+  PushConstant         CP#34
+  IndirectStaticCall   1, CP#4
   Drop1
   Jump                 L1
 L2:
@@ -505,7 +487,7 @@
   Push                 r3
   Throw                1
 L1:
-  PushConstant         CP#11
+  PushNull
   ReturnTOS
 
 }
@@ -563,7 +545,7 @@
   Drop1
   Push                 FP[-5]
   AssertBoolean        0
-  PushConstant         CP#6
+  PushTrue
   IfNeStrictTOS
   Jump                 L2
   Push                 r2
@@ -579,8 +561,8 @@
   MoveSpecial          r6, stackTrace
   Push                 r5
   PopLocal             r7
+  PushConstant         CP#6
   PushConstant         CP#7
-  PushConstant         CP#8
   IndirectStaticCall   1, CP#1
   Drop1
   Jump                 L3
@@ -597,17 +579,17 @@
   PopLocal             r2
   Push                 r1
   PopLocal             r3
+  PushConstant         CP#8
   PushConstant         CP#9
-  PushConstant         CP#10
   IndirectStaticCall   1, CP#1
   Drop1
   Push                 r3
-  PushConstant         CP#11
+  PushConstant         CP#10
   IndirectStaticCall   1, CP#1
   Drop1
   Jump                 L4
 L4:
-  PushConstant         CP#12
+  PushNull
   ReturnTOS
 }
 ExceptionsTable {
@@ -622,13 +604,11 @@
   [3] = Type dynamic
   [4] = String 'try 1 > catch 2 > try 3'
   [5] = StaticICData target 'dart.core::print', arg-desc CP#1
-  [6] = Bool true
-  [7] = String 'try 1 > catch 2 > catch 3'
-  [8] = StaticICData target 'dart.core::print', arg-desc CP#1
-  [9] = String 'catch 1'
+  [6] = String 'try 1 > catch 2 > catch 3'
+  [7] = StaticICData target 'dart.core::print', arg-desc CP#1
+  [8] = String 'catch 1'
+  [9] = StaticICData target 'dart.core::print', arg-desc CP#1
   [10] = StaticICData target 'dart.core::print', arg-desc CP#1
-  [11] = StaticICData target 'dart.core::print', arg-desc CP#1
-  [12] = Null
 }
 ]static method testRethrow(core::bool cond) → dynamic {
   try {
@@ -656,23 +636,23 @@
 Bytecode {
   Entry                3
   CheckStack
-  PushConstant         CP#0
+  PushInt              0
   PopLocal             r0
 L5:
   CheckStack
   Push                 r0
-  PushConstant         CP#1
-  InstanceCall         2, CP#3
+  PushInt              10
+  InstanceCall         2, CP#1
   AssertBoolean        0
-  PushConstant         CP#4
+  PushTrue
   IfNeStrictTOS
   Jump                 L1
 Try #0 start:
   Push                 r0
-  PushConstant         CP#5
-  InstanceCall         2, CP#6
+  PushInt              5
+  InstanceCall         2, CP#2
   AssertBoolean        0
-  PushConstant         CP#4
+  PushTrue
   IfNeStrictTOS
   Jump                 L2
   Jump                 L3
@@ -684,52 +664,46 @@
   MoveSpecial          r1, exception
   MoveSpecial          r2, stackTrace
   Push                 r0
-  PushConstant         CP#9
-  IndirectStaticCall   1, CP#8
+  PushConstant         CP#5
+  IndirectStaticCall   1, CP#4
   Drop1
   Push                 r1
   Push                 r2
   Throw                1
 L3:
   Push                 r0
-  PushConstant         CP#10
-  IndirectStaticCall   1, CP#8
+  PushConstant         CP#6
+  IndirectStaticCall   1, CP#4
   Drop1
   Jump                 L1
 L4:
   Push                 r0
-  PushConstant         CP#11
-  IndirectStaticCall   1, CP#8
+  PushConstant         CP#7
+  IndirectStaticCall   1, CP#4
   Drop1
   Push                 r0
-  PushConstant         CP#12
-  InstanceCall         2, CP#13
+  PushInt              1
+  InstanceCall         2, CP#8
   StoreLocal           r0
   Drop1
   Jump                 L5
 L1:
-  PushConstant         CP#14
+  PushNull
   ReturnTOS
 }
 ExceptionsTable {
-  try-index 0, outer -1, start 12, end 21, handler 21, needs-stack-trace, types [CP#7]
+  try-index 0, outer -1, start 12, end 21, handler 21, needs-stack-trace, types [CP#3]
 }
 ConstantPool {
-  [0] = Int 0
-  [1] = Int 10
-  [2] = ArgDesc num-args 2, num-type-args 0, names []
-  [3] = ICData target-name '<', arg-desc CP#2
-  [4] = Bool true
-  [5] = Int 5
-  [6] = ICData target-name '>', arg-desc CP#2
-  [7] = Type dynamic
-  [8] = ArgDesc num-args 1, num-type-args 0, names []
-  [9] = StaticICData target 'dart.core::print', arg-desc CP#8
-  [10] = StaticICData target 'dart.core::print', arg-desc CP#8
-  [11] = StaticICData target 'dart.core::print', arg-desc CP#8
-  [12] = Int 1
-  [13] = ICData target-name '+', arg-desc CP#2
-  [14] = Null
+  [0] = ArgDesc num-args 2, num-type-args 0, names []
+  [1] = ICData target-name '<', arg-desc CP#0
+  [2] = ICData target-name '>', arg-desc CP#0
+  [3] = Type dynamic
+  [4] = ArgDesc num-args 1, num-type-args 0, names []
+  [5] = StaticICData target 'dart.core::print', arg-desc CP#4
+  [6] = StaticICData target 'dart.core::print', arg-desc CP#4
+  [7] = StaticICData target 'dart.core::print', arg-desc CP#4
+  [8] = ICData target-name '+', arg-desc CP#0
 }
 ]static method testTryFinally1() → dynamic {
   #L1:
@@ -757,15 +731,15 @@
   LoadContextVar       0
   PopLocal             r2
   Push                 r2
-  PushConstant         CP#1
-  InstanceCall         2, CP#2
-  PushConstant         CP#3
+  PushInt              1
+  InstanceCall         2, CP#1
+  PushTrue
   IfEqStrictTOS
   Jump                 L1
   Push                 r2
-  PushConstant         CP#4
-  InstanceCall         2, CP#5
-  PushConstant         CP#3
+  PushInt              2
+  InstanceCall         2, CP#2
+  PushTrue
   IfEqStrictTOS
   Jump                 L2
   Jump                 L3
@@ -773,40 +747,40 @@
   Push                 r0
   PopLocal             r3
 Try #0 start:
-  PushConstant         CP#6
-  PushConstant         CP#8
-  IndirectStaticCall   1, CP#7
+  PushConstant         CP#3
+  PushConstant         CP#5
+  IndirectStaticCall   1, CP#4
   Drop1
   Push                 r0
-  PushConstant         CP#9
+  PushInt              3
   StoreContextVar      1
   Push                 r0
   PopLocal             r5
 Try #1 start:
-  PushConstant         CP#10
-  PushConstant         CP#11
-  IndirectStaticCall   1, CP#7
+  PushConstant         CP#6
+  PushConstant         CP#7
+  IndirectStaticCall   1, CP#4
   Drop1
-  Allocate             CP#19
+  Allocate             CP#14
   StoreLocal           r8
   Push                 r8
-  PushConstant         CP#17
+  PushNull
+  StoreFieldTOS        CP#15
+  Push                 r8
+  PushNull
+  StoreFieldTOS        CP#17
+  Push                 r8
+  PushConstant         CP#19
   StoreFieldTOS        CP#20
   Push                 r8
-  PushConstant         CP#17
+  PushConstant         CP#8
   StoreFieldTOS        CP#22
   Push                 r8
-  PushConstant         CP#24
-  StoreFieldTOS        CP#25
-  Push                 r8
-  PushConstant         CP#12
-  StoreFieldTOS        CP#27
-  Push                 r8
   Push                 r0
-  StoreFieldTOS        CP#13
+  StoreFieldTOS        CP#9
   PopLocal             r7
   Push                 r7
-  InstanceCall         1, CP#29
+  InstanceCall         1, CP#24
   Drop1
   Jump                 L4
   Jump                 L5
@@ -817,9 +791,9 @@
   PopLocal             r0
   MoveSpecial          r5, exception
   MoveSpecial          r6, stackTrace
-  PushConstant         CP#31
-  PushConstant         CP#32
-  IndirectStaticCall   1, CP#7
+  PushConstant         CP#26
+  PushConstant         CP#27
+  IndirectStaticCall   1, CP#4
   Drop1
   Push                 r5
   Push                 r6
@@ -827,21 +801,21 @@
 L4:
   Push                 r5
   PopLocal             r0
-  PushConstant         CP#31
-  PushConstant         CP#33
-  IndirectStaticCall   1, CP#7
+  PushConstant         CP#26
+  PushConstant         CP#28
+  IndirectStaticCall   1, CP#4
   Drop1
   Jump                 L6
 L5:
   Push                 r5
   PopLocal             r0
-  PushConstant         CP#31
-  PushConstant         CP#34
-  IndirectStaticCall   1, CP#7
+  PushConstant         CP#26
+  PushConstant         CP#29
+  IndirectStaticCall   1, CP#4
   Drop1
-  PushConstant         CP#35
-  PushConstant         CP#36
-  IndirectStaticCall   1, CP#7
+  PushConstant         CP#30
+  PushConstant         CP#31
+  IndirectStaticCall   1, CP#4
   Drop1
   Jump                 L7
 Try #0 end:
@@ -851,9 +825,9 @@
   PopLocal             r0
   MoveSpecial          r3, exception
   MoveSpecial          r4, stackTrace
-  PushConstant         CP#37
-  PushConstant         CP#38
-  IndirectStaticCall   1, CP#7
+  PushConstant         CP#32
+  PushConstant         CP#33
+  IndirectStaticCall   1, CP#4
   Drop1
   Push                 r3
   Push                 r4
@@ -861,95 +835,90 @@
 L6:
   Push                 r3
   PopLocal             r0
-  PushConstant         CP#37
-  PushConstant         CP#39
-  IndirectStaticCall   1, CP#7
+  PushConstant         CP#32
+  PushConstant         CP#34
+  IndirectStaticCall   1, CP#4
   Drop1
   Jump                 L2
 L7:
   Push                 r3
   PopLocal             r0
-  PushConstant         CP#37
-  PushConstant         CP#40
-  IndirectStaticCall   1, CP#7
+  PushConstant         CP#32
+  PushConstant         CP#35
+  IndirectStaticCall   1, CP#4
   Drop1
   Jump                 L3
 L2:
-  PushConstant         CP#41
-  PushConstant         CP#42
-  IndirectStaticCall   1, CP#7
+  PushConstant         CP#36
+  PushConstant         CP#37
+  IndirectStaticCall   1, CP#4
   Drop1
   Jump                 L3
 L3:
-  PushConstant         CP#17
+  PushNull
   ReturnTOS
 }
 ExceptionsTable {
-  try-index 0, outer -1, start 25, end 91, handler 91, needs-stack-trace, types [CP#30]
-  try-index 1, outer 0, start 34, end 61, handler 61, needs-stack-trace, types [CP#30]
+  try-index 0, outer -1, start 25, end 91, handler 91, needs-stack-trace, types [CP#25]
+  try-index 1, outer 0, start 34, end 61, handler 61, needs-stack-trace, types [CP#25]
 }
 ConstantPool {
   [0] = ArgDesc num-args 2, num-type-args 0, names []
-  [1] = Int 1
+  [1] = ICData target-name '==', arg-desc CP#0
   [2] = ICData target-name '==', arg-desc CP#0
-  [3] = Bool true
-  [4] = Int 2
-  [5] = ICData target-name '==', arg-desc CP#0
-  [6] = String 'before try 1'
-  [7] = ArgDesc num-args 1, num-type-args 0, names []
-  [8] = StaticICData target 'dart.core::print', arg-desc CP#7
-  [9] = Int 3
-  [10] = String 'try'
-  [11] = StaticICData target 'dart.core::print', arg-desc CP#7
-  [12] = ClosureFunction foo () → void;
-  [13] = InstanceField dart.core::_Closure::_context
-  [14] = Reserved
-  [15] = StaticICData target 'dart.core::print', arg-desc CP#7
-  [16] = StaticICData target 'dart.core::print', arg-desc CP#7
-  [17] = Null
-  [18] = EndClosureFunctionScope
-  [19] = Class dart.core::_Closure
-  [20] = InstanceField dart.core::_Closure::_instantiator_type_arguments
+  [3] = String 'before try 1'
+  [4] = ArgDesc num-args 1, num-type-args 0, names []
+  [5] = StaticICData target 'dart.core::print', arg-desc CP#4
+  [6] = String 'try'
+  [7] = StaticICData target 'dart.core::print', arg-desc CP#4
+  [8] = ClosureFunction foo () → void;
+  [9] = InstanceField dart.core::_Closure::_context
+  [10] = Reserved
+  [11] = StaticICData target 'dart.core::print', arg-desc CP#4
+  [12] = StaticICData target 'dart.core::print', arg-desc CP#4
+  [13] = EndClosureFunctionScope
+  [14] = Class dart.core::_Closure
+  [15] = InstanceField dart.core::_Closure::_instantiator_type_arguments
+  [16] = Reserved
+  [17] = InstanceField dart.core::_Closure::_function_type_arguments
+  [18] = Reserved
+  [19] = EmptyTypeArguments
+  [20] = InstanceField dart.core::_Closure::_delayed_type_arguments
   [21] = Reserved
-  [22] = InstanceField dart.core::_Closure::_function_type_arguments
+  [22] = InstanceField dart.core::_Closure::_function
   [23] = Reserved
-  [24] = EmptyTypeArguments
-  [25] = InstanceField dart.core::_Closure::_delayed_type_arguments
-  [26] = Reserved
-  [27] = InstanceField dart.core::_Closure::_function
-  [28] = Reserved
-  [29] = ICData target-name 'call', arg-desc CP#7
-  [30] = Type dynamic
-  [31] = String 'finally 1'
-  [32] = StaticICData target 'dart.core::print', arg-desc CP#7
-  [33] = StaticICData target 'dart.core::print', arg-desc CP#7
-  [34] = StaticICData target 'dart.core::print', arg-desc CP#7
-  [35] = String 'after try 1'
-  [36] = StaticICData target 'dart.core::print', arg-desc CP#7
-  [37] = String 'finally 2'
-  [38] = StaticICData target 'dart.core::print', arg-desc CP#7
-  [39] = StaticICData target 'dart.core::print', arg-desc CP#7
-  [40] = StaticICData target 'dart.core::print', arg-desc CP#7
-  [41] = String 'case 2'
-  [42] = StaticICData target 'dart.core::print', arg-desc CP#7
+  [24] = ICData dynamic target-name 'call', arg-desc CP#4
+  [25] = Type dynamic
+  [26] = String 'finally 1'
+  [27] = StaticICData target 'dart.core::print', arg-desc CP#4
+  [28] = StaticICData target 'dart.core::print', arg-desc CP#4
+  [29] = StaticICData target 'dart.core::print', arg-desc CP#4
+  [30] = String 'after try 1'
+  [31] = StaticICData target 'dart.core::print', arg-desc CP#4
+  [32] = String 'finally 2'
+  [33] = StaticICData target 'dart.core::print', arg-desc CP#4
+  [34] = StaticICData target 'dart.core::print', arg-desc CP#4
+  [35] = StaticICData target 'dart.core::print', arg-desc CP#4
+  [36] = String 'case 2'
+  [37] = StaticICData target 'dart.core::print', arg-desc CP#4
 }
-Closure CP#12 {
+Closure CP#8 {
   EntryFixed           1, 2
   CheckStack
   Push                 FP[-5]
-  LoadFieldTOS         CP#13
+  LoadFieldTOS         CP#9
   PopLocal             r0
   Push                 r0
   LoadContextVar       0
-  PushConstant         CP#15
-  IndirectStaticCall   1, CP#7
+  PushConstant         CP#11
+  IndirectStaticCall   1, CP#4
   Drop1
   Push                 r0
   LoadContextVar       1
-  PushConstant         CP#16
-  IndirectStaticCall   1, CP#7
+  PushConstant         CP#12
+  IndirectStaticCall   1, CP#4
   Drop1
-  PushConstant         CP#17
+  PushNull
   ReturnTOS
 
 }
@@ -996,30 +965,30 @@
   AllocateContext      1
   PopLocal             r0
   Push                 r0
-  PushConstant         CP#0
+  PushInt              11
   StoreContextVar      0
-  PushConstant         CP#1
+  PushNull
   PopLocal             r2
   Push                 r0
   PopLocal             r3
 Try #0 start:
-  Allocate             CP#26
+  Allocate             CP#22
   StoreLocal           r5
   Push                 r5
-  PushConstant         CP#1
-  StoreFieldTOS        CP#27
+  PushNull
+  StoreFieldTOS        CP#23
   Push                 r5
-  PushConstant         CP#1
-  StoreFieldTOS        CP#29
+  PushNull
+  StoreFieldTOS        CP#25
   Push                 r5
-  PushConstant         CP#31
-  StoreFieldTOS        CP#32
+  PushConstant         CP#27
+  StoreFieldTOS        CP#28
   Push                 r5
-  PushConstant         CP#2
-  StoreFieldTOS        CP#34
+  PushConstant         CP#0
+  StoreFieldTOS        CP#30
   Push                 r5
   Push                 r0
-  StoreFieldTOS        CP#3
+  StoreFieldTOS        CP#1
   PopLocal             r2
   Jump                 L1
 Try #0 end:
@@ -1031,11 +1000,11 @@
   MoveSpecial          r4, stackTrace
   Push                 r0
   LoadContextVar       0
-  PushConstant         CP#36
-  IndirectStaticCall   1, CP#5
+  PushConstant         CP#32
+  IndirectStaticCall   1, CP#3
   Drop1
   Push                 r2
-  InstanceCall         1, CP#37
+  InstanceCall         1, CP#33
   Drop1
   Push                 r3
   Push                 r4
@@ -1045,80 +1014,76 @@
   PopLocal             r0
   Push                 r0
   LoadContextVar       0
-  PushConstant         CP#38
-  IndirectStaticCall   1, CP#5
+  PushConstant         CP#34
+  IndirectStaticCall   1, CP#3
   Drop1
   Push                 r2
-  InstanceCall         1, CP#39
+  InstanceCall         1, CP#35
   Drop1
   Push                 r0
   LoadContextParent
   PopLocal             r0
-  PushConstant         CP#1
+  PushNull
   ReturnTOS
 }
 ExceptionsTable {
-  try-index 0, outer -1, start 11, end 30, handler 30, needs-stack-trace, types [CP#9]
+  try-index 0, outer -1, start 11, end 30, handler 30, needs-stack-trace, types [CP#7]
 }
 ConstantPool {
-  [0] = Int 11
-  [1] = Null
-  [2] = ClosureFunction <anonymous closure> () → dart.core::int;
-  [3] = InstanceField dart.core::_Closure::_context
-  [4] = Reserved
-  [5] = ArgDesc num-args 1, num-type-args 0, names []
-  [6] = StaticICData target 'dart.core::print', arg-desc CP#5
-  [7] = String 'try 1'
-  [8] = StaticICData target 'dart.core::print', arg-desc CP#5
-  [9] = Type dynamic
-  [10] = String 'try 2'
-  [11] = StaticICData target 'dart.core::print', arg-desc CP#5
-  [12] = StaticICData target 'dart.core::print', arg-desc CP#5
-  [13] = StaticICData target 'dart.core::print', arg-desc CP#5
-  [14] = Int 43
-  [15] = StaticICData target 'dart.core::print', arg-desc CP#5
-  [16] = StaticICData target 'dart.core::print', arg-desc CP#5
-  [17] = StaticICData target 'dart.core::print', arg-desc CP#5
-  [18] = StaticICData target 'dart.core::print', arg-desc CP#5
-  [19] = StaticICData target 'dart.core::print', arg-desc CP#5
-  [20] = Int 42
-  [21] = StaticICData target 'dart.core::print', arg-desc CP#5
-  [22] = StaticICData target 'dart.core::print', arg-desc CP#5
-  [23] = StaticICData target 'dart.core::print', arg-desc CP#5
-  [24] = StaticICData target 'dart.core::print', arg-desc CP#5
-  [25] = EndClosureFunctionScope
-  [26] = Class dart.core::_Closure
-  [27] = InstanceField dart.core::_Closure::_instantiator_type_arguments
-  [28] = Reserved
-  [29] = InstanceField dart.core::_Closure::_function_type_arguments
-  [30] = Reserved
-  [31] = EmptyTypeArguments
-  [32] = InstanceField dart.core::_Closure::_delayed_type_arguments
-  [33] = Reserved
-  [34] = InstanceField dart.core::_Closure::_function
-  [35] = Reserved
-  [36] = StaticICData target 'dart.core::print', arg-desc CP#5
-  [37] = ICData target-name 'call', arg-desc CP#5
-  [38] = StaticICData target 'dart.core::print', arg-desc CP#5
-  [39] = ICData target-name 'call', arg-desc CP#5
+  [0] = ClosureFunction <anonymous closure> () → dart.core::int;
+  [1] = InstanceField dart.core::_Closure::_context
+  [2] = Reserved
+  [3] = ArgDesc num-args 1, num-type-args 0, names []
+  [4] = StaticICData target 'dart.core::print', arg-desc CP#3
+  [5] = String 'try 1'
+  [6] = StaticICData target 'dart.core::print', arg-desc CP#3
+  [7] = Type dynamic
+  [8] = String 'try 2'
+  [9] = StaticICData target 'dart.core::print', arg-desc CP#3
+  [10] = StaticICData target 'dart.core::print', arg-desc CP#3
+  [11] = StaticICData target 'dart.core::print', arg-desc CP#3
+  [12] = StaticICData target 'dart.core::print', arg-desc CP#3
+  [13] = StaticICData target 'dart.core::print', arg-desc CP#3
+  [14] = StaticICData target 'dart.core::print', arg-desc CP#3
+  [15] = StaticICData target 'dart.core::print', arg-desc CP#3
+  [16] = StaticICData target 'dart.core::print', arg-desc CP#3
+  [17] = StaticICData target 'dart.core::print', arg-desc CP#3
+  [18] = StaticICData target 'dart.core::print', arg-desc CP#3
+  [19] = StaticICData target 'dart.core::print', arg-desc CP#3
+  [20] = StaticICData target 'dart.core::print', arg-desc CP#3
+  [21] = EndClosureFunctionScope
+  [22] = Class dart.core::_Closure
+  [23] = InstanceField dart.core::_Closure::_instantiator_type_arguments
+  [24] = Reserved
+  [25] = InstanceField dart.core::_Closure::_function_type_arguments
+  [26] = Reserved
+  [27] = EmptyTypeArguments
+  [28] = InstanceField dart.core::_Closure::_delayed_type_arguments
+  [29] = Reserved
+  [30] = InstanceField dart.core::_Closure::_function
+  [31] = Reserved
+  [32] = StaticICData target 'dart.core::print', arg-desc CP#3
+  [33] = ICData dynamic target-name 'call', arg-desc CP#3
+  [34] = StaticICData target 'dart.core::print', arg-desc CP#3
+  [35] = ICData dynamic target-name 'call', arg-desc CP#3
 }
-Closure CP#2 {
+Closure CP#0 {
   EntryFixed           1, 6
   CheckStack
   Push                 FP[-5]
-  LoadFieldTOS         CP#3
+  LoadFieldTOS         CP#1
   PopLocal             r0
   Push                 r0
   LoadContextVar       0
-  PushConstant         CP#6
-  IndirectStaticCall   1, CP#5
+  PushConstant         CP#4
+  IndirectStaticCall   1, CP#3
   Drop1
   Push                 r0
   PopLocal             r2
 Try #0 start:
-  PushConstant         CP#7
-  PushConstant         CP#8
-  IndirectStaticCall   1, CP#5
+  PushConstant         CP#5
+  PushConstant         CP#6
+  IndirectStaticCall   1, CP#3
   Drop1
   Jump                 L1
   Jump                 L2
@@ -1132,9 +1097,9 @@
   Push                 r0
   PopLocal             r4
 Try #1 start:
-  PushConstant         CP#10
-  PushConstant         CP#11
-  IndirectStaticCall   1, CP#5
+  PushConstant         CP#8
+  PushConstant         CP#9
+  IndirectStaticCall   1, CP#3
   Drop1
   Jump                 L3
   Jump                 L4
@@ -1147,8 +1112,8 @@
   MoveSpecial          r5, stackTrace
   Push                 r0
   LoadContextVar       0
-  PushConstant         CP#12
-  IndirectStaticCall   1, CP#5
+  PushConstant         CP#10
+  IndirectStaticCall   1, CP#3
   Drop1
   Push                 r4
   Push                 r5
@@ -1158,18 +1123,18 @@
   PopLocal             r0
   Push                 r0
   LoadContextVar       0
-  PushConstant         CP#13
-  IndirectStaticCall   1, CP#5
+  PushConstant         CP#11
+  IndirectStaticCall   1, CP#3
   Drop1
-  PushConstant         CP#14
+  PushInt              43
   ReturnTOS
 L4:
   Push                 r4
   PopLocal             r0
   Push                 r0
   LoadContextVar       0
-  PushConstant         CP#15
-  IndirectStaticCall   1, CP#5
+  PushConstant         CP#12
+  IndirectStaticCall   1, CP#3
   Drop1
   Push                 r2
   Push                 r3
@@ -1180,9 +1145,9 @@
   Push                 r0
   PopLocal             r4
 Try #2 start:
-  PushConstant         CP#10
-  PushConstant         CP#16
-  IndirectStaticCall   1, CP#5
+  PushConstant         CP#8
+  PushConstant         CP#13
+  IndirectStaticCall   1, CP#3
   Drop1
   Jump                 L5
   Jump                 L6
@@ -1195,8 +1160,8 @@
   MoveSpecial          r5, stackTrace
   Push                 r0
   LoadContextVar       0
-  PushConstant         CP#17
-  IndirectStaticCall   1, CP#5
+  PushConstant         CP#14
+  IndirectStaticCall   1, CP#3
   Drop1
   Push                 r4
   Push                 r5
@@ -1206,20 +1171,20 @@
   PopLocal             r0
   Push                 r0
   LoadContextVar       0
-  PushConstant         CP#18
-  IndirectStaticCall   1, CP#5
+  PushConstant         CP#15
+  IndirectStaticCall   1, CP#3
   Drop1
-  PushConstant         CP#14
+  PushInt              43
   ReturnTOS
 L6:
   Push                 r4
   PopLocal             r0
   Push                 r0
   LoadContextVar       0
-  PushConstant         CP#19
-  IndirectStaticCall   1, CP#5
+  PushConstant         CP#16
+  IndirectStaticCall   1, CP#3
   Drop1
-  PushConstant         CP#20
+  PushInt              42
   ReturnTOS
 L2:
   Push                 r2
@@ -1227,9 +1192,9 @@
   Push                 r0
   PopLocal             r4
 Try #3 start:
-  PushConstant         CP#10
-  PushConstant         CP#21
-  IndirectStaticCall   1, CP#5
+  PushConstant         CP#8
+  PushConstant         CP#17
+  IndirectStaticCall   1, CP#3
   Drop1
   Jump                 L7
   Jump                 L8
@@ -1242,8 +1207,8 @@
   MoveSpecial          r5, stackTrace
   Push                 r0
   LoadContextVar       0
-  PushConstant         CP#22
-  IndirectStaticCall   1, CP#5
+  PushConstant         CP#18
+  IndirectStaticCall   1, CP#3
   Drop1
   Push                 r4
   Push                 r5
@@ -1253,20 +1218,20 @@
   PopLocal             r0
   Push                 r0
   LoadContextVar       0
-  PushConstant         CP#23
-  IndirectStaticCall   1, CP#5
+  PushConstant         CP#19
+  IndirectStaticCall   1, CP#3
   Drop1
-  PushConstant         CP#14
+  PushInt              43
   ReturnTOS
 L8:
   Push                 r4
   PopLocal             r0
   Push                 r0
   LoadContextVar       0
-  PushConstant         CP#24
-  IndirectStaticCall   1, CP#5
+  PushConstant         CP#20
+  IndirectStaticCall   1, CP#3
   Drop1
-  PushConstant         CP#1
+  PushNull
   ReturnTOS
 
 }
@@ -1338,7 +1303,7 @@
   PushConstant         CP#8
   IndirectStaticCall   1, CP#1
   Drop1
-  PushConstant         CP#9
+  PushNull
   ReturnTOS
 }
 ExceptionsTable {
@@ -1355,7 +1320,6 @@
   [6] = String 'finally'
   [7] = StaticICData target 'dart.core::print', arg-desc CP#1
   [8] = StaticICData target 'dart.core::print', arg-desc CP#1
-  [9] = Null
 }
 ]static method testTryCatchFinally() → dynamic {
   try
@@ -1373,10 +1337,9 @@
 Bytecode {
   Entry                0
   CheckStack
-  PushConstant         CP#0
+  PushNull
   ReturnTOS
 }
 ConstantPool {
-  [0] = Null
 }
 ]static method main() → dynamic {}
diff --git a/pkg/vm/testcases/bytecode/type_ops.dart.expect b/pkg/vm/testcases/bytecode/type_ops.dart.expect
index 457d5bc..363540d 100644
--- a/pkg/vm/testcases/bytecode/type_ops.dart.expect
+++ b/pkg/vm/testcases/bytecode/type_ops.dart.expect
@@ -11,13 +11,12 @@
   PushConstant         CP#1
   IndirectStaticCall   1, CP#0
   Drop1
-  PushConstant         CP#2
+  PushNull
   ReturnTOS
 }
 ConstantPool {
   [0] = ArgDesc num-args 1, num-type-args 0, names []
   [1] = StaticICData target 'dart.core::Object::', arg-desc CP#0
-  [2] = Null
 }
 ]  synthetic constructor •() → void
     : super core::Object::•()
@@ -32,13 +31,12 @@
   PushConstant         CP#1
   IndirectStaticCall   1, CP#0
   Drop1
-  PushConstant         CP#2
+  PushNull
   ReturnTOS
 }
 ConstantPool {
   [0] = ArgDesc num-args 1, num-type-args 0, names []
   [1] = StaticICData target '#lib::A::', arg-desc CP#0
-  [2] = Null
 }
 ]  synthetic constructor •() → void
     : super self::A::•()
@@ -53,13 +51,12 @@
   PushConstant         CP#1
   IndirectStaticCall   1, CP#0
   Drop1
-  PushConstant         CP#2
+  PushNull
   ReturnTOS
 }
 ConstantPool {
   [0] = ArgDesc num-args 1, num-type-args 0, names []
   [1] = StaticICData target '#lib::B::', arg-desc CP#0
-  [2] = Null
 }
 ]  synthetic constructor •() → void
     : super self::B::•()
@@ -75,28 +72,27 @@
   Push                 FP[-5]
   Push                 FP[-6]
   LoadTypeArgumentsField CP#0
+  PushNull
   PushConstant         CP#1
   PushConstant         CP#2
-  PushConstant         CP#3
-  AssertAssignable     0, CP#4
-  StoreFieldTOS        CP#5
+  AssertAssignable     0, CP#3
+  StoreFieldTOS        CP#4
   Push                 FP[-6]
-  PushConstant         CP#8
-  IndirectStaticCall   1, CP#7
+  PushConstant         CP#7
+  IndirectStaticCall   1, CP#6
   Drop1
-  PushConstant         CP#1
+  PushNull
   ReturnTOS
 }
 ConstantPool {
   [0] = TypeArgumentsField #lib::D
-  [1] = Null
-  [2] = Type dart.core::Map<#lib::D::P, #lib::D::Q>
-  [3] = String ''
-  [4] = SubtypeTestCache
-  [5] = InstanceField #lib::D::foo
-  [6] = Reserved
-  [7] = ArgDesc num-args 1, num-type-args 0, names []
-  [8] = StaticICData target '#lib::C::', arg-desc CP#7
+  [1] = Type dart.core::Map<#lib::D::P, #lib::D::Q>
+  [2] = String ''
+  [3] = SubtypeTestCache
+  [4] = InstanceField #lib::D::foo
+  [5] = Reserved
+  [6] = ArgDesc num-args 1, num-type-args 0, names []
+  [7] = StaticICData target '#lib::C::', arg-desc CP#6
 }
 ]  constructor •(dynamic tt) → void
     : self::D::foo = tt as{TypeError} core::Map<self::D::P, self::D::Q>, super self::C::•()
@@ -108,65 +104,63 @@
   Push                 FP[-5]
   Push                 FP[-6]
   LoadTypeArgumentsField CP#0
+  PushNull
   PushConstant         CP#1
-  PushConstant         CP#2
-  InstanceCall         4, CP#4
+  InstanceCall         4, CP#3
   AssertBoolean        0
-  PushConstant         CP#5
+  PushTrue
   IfNeStrictTOS
   Jump                 L1
+  PushConstant         CP#4
   PushConstant         CP#6
-  PushConstant         CP#8
-  IndirectStaticCall   1, CP#7
+  IndirectStaticCall   1, CP#5
   Drop1
 L1:
   Push                 FP[-5]
   Push                 FP[-6]
   LoadTypeArgumentsField CP#0
-  PushConstant         CP#1
-  PushConstant         CP#9
-  InstanceCall         4, CP#10
+  PushNull
+  PushConstant         CP#7
+  InstanceCall         4, CP#8
   AssertBoolean        0
-  PushConstant         CP#5
+  PushTrue
   IfNeStrictTOS
   Jump                 L2
-  PushConstant         CP#11
-  PushConstant         CP#12
-  IndirectStaticCall   1, CP#7
+  PushConstant         CP#9
+  PushConstant         CP#10
+  IndirectStaticCall   1, CP#5
   Drop1
 L2:
   Push                 FP[-6]
   Push                 FP[-5]
   Push                 FP[-6]
   LoadTypeArgumentsField CP#0
-  PushConstant         CP#1
-  PushConstant         CP#13
-  PushConstant         CP#14
-  AssertAssignable     0, CP#15
-  InstanceCall         2, CP#17
+  PushNull
+  PushConstant         CP#11
+  PushConstant         CP#12
+  AssertAssignable     0, CP#13
+  InstanceCall         2, CP#15
   Drop1
-  PushConstant         CP#1
+  PushNull
   ReturnTOS
 }
 ConstantPool {
   [0] = TypeArgumentsField #lib::D
-  [1] = Null
-  [2] = Type #lib::A<#lib::D::P>
-  [3] = ArgDesc num-args 4, num-type-args 0, names []
-  [4] = ICData target-name 'dart.core::_instanceOf', arg-desc CP#3
-  [5] = Bool true
-  [6] = String '21'
-  [7] = ArgDesc num-args 1, num-type-args 0, names []
-  [8] = StaticICData target 'dart.core::print', arg-desc CP#7
-  [9] = Type #lib::C<dynamic, #lib::D::Q, dart.core::List<#lib::D::P>>
-  [10] = ICData target-name 'dart.core::_instanceOf', arg-desc CP#3
-  [11] = String '22'
-  [12] = StaticICData target 'dart.core::print', arg-desc CP#7
-  [13] = Type dart.core::Map<#lib::D::P, #lib::D::Q>
-  [14] = String ''
-  [15] = SubtypeTestCache
-  [16] = ArgDesc num-args 2, num-type-args 0, names []
-  [17] = ICData set target-name 'foo', arg-desc CP#16
+  [1] = Type #lib::A<#lib::D::P>
+  [2] = ArgDesc num-args 4, num-type-args 0, names []
+  [3] = ICData target-name 'dart.core::_instanceOf', arg-desc CP#2
+  [4] = String '21'
+  [5] = ArgDesc num-args 1, num-type-args 0, names []
+  [6] = StaticICData target 'dart.core::print', arg-desc CP#5
+  [7] = Type #lib::C<dynamic, #lib::D::Q, dart.core::List<#lib::D::P>>
+  [8] = ICData target-name 'dart.core::_instanceOf', arg-desc CP#2
+  [9] = String '22'
+  [10] = StaticICData target 'dart.core::print', arg-desc CP#5
+  [11] = Type dart.core::Map<#lib::D::P, #lib::D::Q>
+  [12] = String ''
+  [13] = SubtypeTestCache
+  [14] = ArgDesc num-args 2, num-type-args 0, names []
+  [15] = ICData set target-name 'foo', arg-desc CP#14
 }
 ]  method foo2(dynamic y) → dynamic {
     if(y is self::A<self::D::P>) {
@@ -183,62 +177,60 @@
   CheckStack
   CheckFunctionTypeArgs 2, 0
   Push                 FP[-5]
-  PushConstant         CP#0
+  PushNull
   Push                 r0
-  PushConstant         CP#1
-  InstanceCall         4, CP#3
+  PushConstant         CP#0
+  InstanceCall         4, CP#2
   AssertBoolean        0
-  PushConstant         CP#4
+  PushTrue
   IfNeStrictTOS
   Jump                 L1
+  PushConstant         CP#3
   PushConstant         CP#5
-  PushConstant         CP#7
-  IndirectStaticCall   1, CP#6
+  IndirectStaticCall   1, CP#4
   Drop1
 L1:
   Push                 FP[-5]
   Push                 FP[-6]
-  LoadTypeArgumentsField CP#8
+  LoadTypeArgumentsField CP#6
   Push                 r0
-  PushConstant         CP#9
-  InstanceCall         4, CP#10
+  PushConstant         CP#7
+  InstanceCall         4, CP#8
   AssertBoolean        0
-  PushConstant         CP#4
+  PushTrue
   IfNeStrictTOS
   Jump                 L2
-  PushConstant         CP#11
-  PushConstant         CP#12
-  IndirectStaticCall   1, CP#6
+  PushConstant         CP#9
+  PushConstant         CP#10
+  IndirectStaticCall   1, CP#4
   Drop1
 L2:
   Push                 FP[-5]
   Push                 FP[-6]
-  LoadTypeArgumentsField CP#8
+  LoadTypeArgumentsField CP#6
   Push                 r0
-  PushConstant         CP#13
-  InstanceCall         4, CP#14
-  InstanceCall         1, CP#15
+  PushConstant         CP#11
+  InstanceCall         4, CP#12
+  InstanceCall         1, CP#13
   ReturnTOS
-  PushConstant         CP#0
+  PushNull
   ReturnTOS
 }
 ConstantPool {
-  [0] = Null
-  [1] = Type #lib::A<#lib::D::foo3::T1>
-  [2] = ArgDesc num-args 4, num-type-args 0, names []
-  [3] = ICData target-name 'dart.core::_instanceOf', arg-desc CP#2
-  [4] = Bool true
-  [5] = String '31'
-  [6] = ArgDesc num-args 1, num-type-args 0, names []
-  [7] = StaticICData target 'dart.core::print', arg-desc CP#6
-  [8] = TypeArgumentsField #lib::D
-  [9] = Type #lib::C<dart.core::Map<#lib::D::foo3::T1, #lib::D::P>, dart.core::List<#lib::D::foo3::T2>, #lib::D::Q>
-  [10] = ICData target-name 'dart.core::_instanceOf', arg-desc CP#2
-  [11] = String '32'
-  [12] = StaticICData target 'dart.core::print', arg-desc CP#6
-  [13] = Type dart.core::Map<#lib::D::foo3::T2, #lib::D::Q>
-  [14] = ICData target-name 'dart.core::_as', arg-desc CP#2
-  [15] = ICData get target-name 'values', arg-desc CP#6
+  [0] = Type #lib::A<#lib::D::foo3::T1>
+  [1] = ArgDesc num-args 4, num-type-args 0, names []
+  [2] = ICData target-name 'dart.core::_instanceOf', arg-desc CP#1
+  [3] = String '31'
+  [4] = ArgDesc num-args 1, num-type-args 0, names []
+  [5] = StaticICData target 'dart.core::print', arg-desc CP#4
+  [6] = TypeArgumentsField #lib::D
+  [7] = Type #lib::C<dart.core::Map<#lib::D::foo3::T1, #lib::D::P>, dart.core::List<#lib::D::foo3::T2>, #lib::D::Q>
+  [8] = ICData target-name 'dart.core::_instanceOf', arg-desc CP#1
+  [9] = String '32'
+  [10] = StaticICData target 'dart.core::print', arg-desc CP#4
+  [11] = Type dart.core::Map<#lib::D::foo3::T2, #lib::D::Q>
+  [12] = ICData target-name 'dart.core::_as', arg-desc CP#1
+  [13] = ICData get target-name 'values', arg-desc CP#4
 }
 ]  method foo3<T1 extends core::Object = dynamic, T2 extends core::Object = dynamic>(dynamic z) → dynamic {
     if(z is self::A<self::D::foo3::T1>) {
@@ -255,49 +247,46 @@
   CheckStack
   Push                 FP[-6]
   LoadTypeArgumentsField CP#0
-  PushConstant         CP#1
-  InstantiateTypeArgumentsTOS 0, CP#2
+  PushNull
+  InstantiateTypeArgumentsTOS 0, CP#1
   StoreLocal           r1
   Push                 r1
-  PushConstant         CP#3
+  PushInt              1
   CreateArrayTOS
   StoreLocal           r1
   Push                 r1
-  PushConstant         CP#4
+  PushInt              0
   Push                 FP[-5]
   Push                 FP[-6]
   LoadTypeArgumentsField CP#0
-  PushConstant         CP#1
-  PushConstant         CP#5
-  PushConstant         CP#6
-  AssertAssignable     0, CP#7
+  PushNull
+  PushConstant         CP#2
+  PushConstant         CP#3
+  AssertAssignable     0, CP#4
   StoreIndexedTOS
-  PushConstant         CP#9
-  IndirectStaticCall   2, CP#8
+  PushConstant         CP#6
+  IndirectStaticCall   2, CP#5
   PopLocal             r0
   Push                 FP[-5]
   Push                 FP[-6]
   LoadTypeArgumentsField CP#0
-  PushConstant         CP#1
-  PushConstant         CP#5
-  PushConstant         CP#6
-  AssertAssignable     0, CP#10
+  PushNull
+  PushConstant         CP#2
+  PushConstant         CP#3
+  AssertAssignable     0, CP#7
   ReturnTOS
-  PushConstant         CP#1
+  PushNull
   ReturnTOS
 }
 ConstantPool {
   [0] = TypeArgumentsField #lib::D
-  [1] = Null
-  [2] = TypeArgs [dart.core::Map<#lib::D::P, #lib::D::Q>]
-  [3] = Int 1
-  [4] = Int 0
-  [5] = Type dart.core::Map<#lib::D::P, #lib::D::Q>
-  [6] = String ''
+  [1] = TypeArgs [dart.core::Map<#lib::D::P, #lib::D::Q>]
+  [2] = Type dart.core::Map<#lib::D::P, #lib::D::Q>
+  [3] = String ''
+  [4] = SubtypeTestCache
+  [5] = ArgDesc num-args 2, num-type-args 0, names []
+  [6] = StaticICData target 'dart.core::List::_fromLiteral', arg-desc CP#5
   [7] = SubtypeTestCache
-  [8] = ArgDesc num-args 2, num-type-args 0, names []
-  [9] = StaticICData target 'dart.core::List::_fromLiteral', arg-desc CP#8
-  [10] = SubtypeTestCache
 }
 ]  method foo4(dynamic w) → core::Map<self::D::P, self::D::Q> {
     core::List<core::Map<self::D::P, self::D::Q>> list = <core::Map<self::D::P, self::D::Q>>[w as{TypeError} core::Map<self::D::P, self::D::Q>];
@@ -309,13 +298,12 @@
 Bytecode {
   Entry                0
   CheckStack
-  PushConstant         CP#0
+  PushNull
   ReturnTOS
-  PushConstant         CP#0
+  PushNull
   ReturnTOS
 }
 ConstantPool {
-  [0] = Null
 }
 ]  static factory •<P extends core::String = dynamic>() → self::E<self::E::•::P>
     return null;
@@ -327,46 +315,26 @@
   JumpIfNotZeroTypeArgs L1
   Push                 FP[-6]
   LoadTypeArgumentsField CP#0
-  PushConstant         CP#1
-  InstantiateTypeArgumentsTOS 0, CP#2
+  PushNull
+  InstantiateTypeArgumentsTOS 0, CP#1
   PopLocal             r0
 L1:
   Push                 FP[-6]
   LoadTypeArgumentsField CP#0
   Push                 r0
+  PushConstant         CP#2
   PushConstant         CP#3
   PushConstant         CP#4
-  PushConstant         CP#5
   AssertSubtype
-  PushConstant         CP#1
-  Push                 r0
-  PushConstant         CP#6
-  PushConstant         CP#7
-  PushConstant         CP#8
-  AssertSubtype
-  Push                 FP[-5]
-  PushConstant         CP#1
-  Push                 r0
-  PushConstant         CP#9
-  PushConstant         CP#10
-  AssertAssignable     0, CP#11
-  Drop1
-  PushConstant         CP#1
+  PushNull
   ReturnTOS
 }
 ConstantPool {
   [0] = TypeArgumentsField #lib::E
-  [1] = Null
-  [2] = TypeArgs [#lib::E::P, dart.core::List<#lib::E::P>]
-  [3] = Type #lib::E::foo6::T
-  [4] = Type #lib::E::P
-  [5] = String 'T'
-  [6] = Type #lib::E::foo6::U
-  [7] = Type dart.core::List<#lib::E::foo6::T>
-  [8] = String 'U'
-  [9] = Type dart.core::Map<#lib::E::foo6::T, #lib::E::foo6::U>
-  [10] = String 'map'
-  [11] = SubtypeTestCache
+  [1] = TypeArgs [#lib::E::P, dart.core::List<#lib::E::P>]
+  [2] = Type #lib::E::foo6::T
+  [3] = Type #lib::E::P
+  [4] = String 'T'
 }
 ]  method foo6<generic-covariant-impl T extends self::E::P = self::E::P, U extends core::List<self::E::foo6::T> = core::List<self::E::P>>(core::Map<self::E::foo6::T, self::E::foo6::U> map) → void {}
 }
@@ -376,57 +344,55 @@
   Entry                0
   CheckStack
   Push                 FP[-5]
+  PushNull
+  PushNull
   PushConstant         CP#0
-  PushConstant         CP#0
-  PushConstant         CP#1
-  InstanceCall         4, CP#3
+  InstanceCall         4, CP#2
   AssertBoolean        0
-  PushConstant         CP#4
+  PushTrue
   IfNeStrictTOS
   Jump                 L1
+  PushConstant         CP#3
   PushConstant         CP#5
-  PushConstant         CP#7
-  IndirectStaticCall   1, CP#6
+  IndirectStaticCall   1, CP#4
   Drop1
 L1:
   Push                 FP[-5]
-  PushConstant         CP#0
-  PushConstant         CP#0
-  PushConstant         CP#8
-  InstanceCall         4, CP#9
+  PushNull
+  PushNull
+  PushConstant         CP#6
+  InstanceCall         4, CP#7
   AssertBoolean        0
-  PushConstant         CP#4
+  PushTrue
   IfNeStrictTOS
   Jump                 L2
-  PushConstant         CP#10
-  PushConstant         CP#11
-  IndirectStaticCall   1, CP#6
+  PushConstant         CP#8
+  PushConstant         CP#9
+  IndirectStaticCall   1, CP#4
   Drop1
 L2:
   Push                 FP[-5]
-  PushConstant         CP#0
-  PushConstant         CP#0
-  PushConstant         CP#12
-  InstanceCall         4, CP#13
+  PushNull
+  PushNull
+  PushConstant         CP#10
+  InstanceCall         4, CP#11
   ReturnTOS
-  PushConstant         CP#0
+  PushNull
   ReturnTOS
 }
 ConstantPool {
-  [0] = Null
-  [1] = Type #lib::B
-  [2] = ArgDesc num-args 4, num-type-args 0, names []
-  [3] = ICData target-name 'dart.core::_instanceOf', arg-desc CP#2
-  [4] = Bool true
-  [5] = String '11'
-  [6] = ArgDesc num-args 1, num-type-args 0, names []
-  [7] = StaticICData target 'dart.core::print', arg-desc CP#6
-  [8] = Type #lib::C<dart.core::int, dart.core::Object, dynamic>
-  [9] = ICData target-name 'dart.core::_instanceOf', arg-desc CP#2
-  [10] = String '12'
-  [11] = StaticICData target 'dart.core::print', arg-desc CP#6
-  [12] = Type #lib::A<dart.core::int>
-  [13] = ICData target-name 'dart.core::_as', arg-desc CP#2
+  [0] = Type #lib::B
+  [1] = ArgDesc num-args 4, num-type-args 0, names []
+  [2] = ICData target-name 'dart.core::_instanceOf', arg-desc CP#1
+  [3] = String '11'
+  [4] = ArgDesc num-args 1, num-type-args 0, names []
+  [5] = StaticICData target 'dart.core::print', arg-desc CP#4
+  [6] = Type #lib::C<dart.core::int, dart.core::Object, dynamic>
+  [7] = ICData target-name 'dart.core::_instanceOf', arg-desc CP#1
+  [8] = String '12'
+  [9] = StaticICData target 'dart.core::print', arg-desc CP#4
+  [10] = Type #lib::A<dart.core::int>
+  [11] = ICData target-name 'dart.core::_as', arg-desc CP#1
 }
 ]static method foo1(dynamic x) → dynamic {
   if(x is self::B) {
@@ -442,21 +408,20 @@
   Entry                1
   CheckStack
   Push                 FP[-5]
-  PushConstant         CP#0
+  PushNull
+  PushNull
   PushConstant         CP#0
   PushConstant         CP#1
-  PushConstant         CP#2
-  AssertAssignable     0, CP#3
-  StoreStaticTOS       CP#4
-  PushConstant         CP#0
+  AssertAssignable     0, CP#2
+  StoreStaticTOS       CP#3
+  PushNull
   ReturnTOS
 }
 ConstantPool {
-  [0] = Null
-  [1] = Type dart.core::List<dart.core::Iterable<dynamic>>
-  [2] = String ''
-  [3] = SubtypeTestCache
-  [4] = StaticField #lib::globalVar
+  [0] = Type dart.core::List<dart.core::Iterable<dynamic>>
+  [1] = String ''
+  [2] = SubtypeTestCache
+  [3] = StaticField #lib::globalVar
 }
 ]static method foo5(dynamic x) → void {
   self::globalVar = x as{TypeError} core::List<core::Iterable<dynamic>>;
@@ -465,10 +430,9 @@
 Bytecode {
   Entry                0
   CheckStack
-  PushConstant         CP#0
+  PushNull
   ReturnTOS
 }
 ConstantPool {
-  [0] = Null
 }
 ]static method main() → dynamic {}
diff --git a/pkg/vm/testcases/transformations/type_flow/summary_collector/calls.dart.expect b/pkg/vm/testcases/transformations/type_flow/summary_collector/calls.dart.expect
index 4deba6d..e5c30ed 100644
--- a/pkg/vm/testcases/transformations/type_flow/summary_collector/calls.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/summary_collector/calls.dart.expect
@@ -22,7 +22,7 @@
 %y = _Parameter #1 [_T (dart.core::int)+?]
 RESULT: _T {}?
 ------------ #lib::B::bar4 ------------
-
+%this = _Parameter #0 [_T (#lib::B)+]
 RESULT: _T {}?
 ------------ #lib::C:: ------------
 %this = _Parameter #0 [_T (#lib::C)+]
@@ -39,8 +39,9 @@
 t7* = _Call get [#lib::A::foo2] (%aa)
 t8 = _Narrow (t7 to _T (dart.core::int)+?)
 t9 = _Call set [#lib::A::foo3] (%aa, t8)
-t10* = _Call get [#lib::A::foo2] (%aa)
-t11 = _Call dynamic [call] (t10, %a2, %a3, _T ANY?)
+t10* = _Call get [#lib::A::foo1] (%aa)
+t11* = _Call get [#lib::A::foo2] (%aa)
+t12 = _Call dynamic [call] (t11, %a2, %a3, t10)
 a4 = _Join [dart.core::Object] (%a4, _T ANY?)
 RESULT: a4
 ------------ #lib::C::dynamicCalls ------------
@@ -71,8 +72,9 @@
 t6* = _Call direct get [#lib::B::bar4] (%this)
 t7 = _Call direct set [#lib::B::bar3] (%this, t6)
 t8* = _Call direct get [#lib::B::bar2] (%this)
-t9* = _Call dynamic [call] (t8, %a2, %a3, _T ANY?)
-a4 = _Join [dart.core::Object] (%a4, t9)
+t9* = _Call direct get [#lib::B::bar1] (%this)
+t10* = _Call dynamic [call] (t8, %a2, %a3, t9)
+a4 = _Join [dart.core::Object] (%a4, t10)
 RESULT: a4
 ------------ #lib::main ------------
 
diff --git a/pkg/vm/testcases/transformations/type_flow/summary_collector/setter_result.dart.expect b/pkg/vm/testcases/transformations/type_flow/summary_collector/setter_result.dart.expect
index 608ebfa..d2e41b1 100644
--- a/pkg/vm/testcases/transformations/type_flow/summary_collector/setter_result.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/summary_collector/setter_result.dart.expect
@@ -7,7 +7,7 @@
 t1 = _Call direct [dart.core::Object::] (%this)
 RESULT: _T {}?
 ------------ #lib::A::foo ------------
-
+%this = _Parameter #0 [_T (#lib::A)+]
 RESULT: _T {}?
 ------------ #lib::B:: ------------
 %this = _Parameter #0 [_T (#lib::B)+]
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_set_field2.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_set_field2.dart.expect
index ac18742..88d3aa8 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_set_field2.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_set_field2.dart.expect
@@ -28,8 +28,8 @@
     : self::Q::result = result, super core::Object::•()
     ;
 }
-static method foo1(core::List<self::T1> list) → dynamic {
-  [@vm.direct-call.metadata=#lib::T3::run] [@vm.direct-call.metadata=#lib::T1::go??] [@vm.inferred-type.metadata=#lib::T3] [@vm.direct-call.metadata=#lib::Q::result??] [@vm.inferred-type.metadata=!] list.{core::Iterable::map}<self::Q<self::T1>>((self::T1 t1) → self::Q<self::T1> => new self::Q::•<self::T1>(t1)).{core::Iterable::first}.{self::Q::result}.{self::T1::go}().{self::T3::run}();
+static method foo1([@vm.inferred-type.metadata=dart.core::_GrowableList] core::List<self::T1> list) → dynamic {
+  [@vm.direct-call.metadata=#lib::T3::run] [@vm.direct-call.metadata=#lib::T1::go??] [@vm.inferred-type.metadata=#lib::T3] [@vm.direct-call.metadata=#lib::Q::result??] [@vm.direct-call.metadata=dart._internal::ListIterable::first] [@vm.direct-call.metadata=dart.collection::_ListBase&Object&ListMixin::map] [@vm.inferred-type.metadata=dart._internal::MappedListIterable] list.{core::Iterable::map}<self::Q<self::T1>>((self::T1 t1) → self::Q<self::T1> => new self::Q::•<self::T1>(t1)).{core::Iterable::first}.{self::Q::result}.{self::T1::go}().{self::T3::run}();
 }
 static method foo2NewValue() → self::Q<dynamic>
   return new self::Q::•<self::T2>(new self::T2::•());
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/tear_off_interface_method.dart b/pkg/vm/testcases/transformations/type_flow/transformer/tear_off_interface_method.dart
index db52bf0..5ce46d8 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/tear_off_interface_method.dart
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/tear_off_interface_method.dart
@@ -11,11 +11,12 @@
 }
 
 class B extends A {
-  int foo() => 1 + knownResult().foo(); // Should have metadata.
+  int foo() => 1 + knownResult().bar(); // Should have metadata.
+  int bar() => 3;
 }
 
 class C implements A {
-  int foo() => 2 + knownResult().foo(); // Should be unreachable.
+  int foo() => 2 + knownResult().bar(); // Should be unreachable.
 }
 
 class TearOffInterfaceMethod {
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/tear_off_interface_method.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/tear_off_interface_method.dart.expect
index 18c3870..4cf2073 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/tear_off_interface_method.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/tear_off_interface_method.dart.expect
@@ -13,7 +13,9 @@
     : super self::A::•()
     ;
   method foo() → core::int
-    return [@vm.direct-call.metadata=dart.core::_IntegerImplementation::+] [@vm.inferred-type.metadata=int?] 1.{core::num::+}([@vm.direct-call.metadata=#lib::B::foo] [@vm.inferred-type.metadata=int?] [@vm.inferred-type.metadata=#lib::B] self::knownResult().foo() as{TypeError} core::num) as{TypeError} core::int;
+    return [@vm.direct-call.metadata=dart.core::_IntegerImplementation::+] [@vm.inferred-type.metadata=int?] 1.{core::num::+}([@vm.direct-call.metadata=#lib::B::bar] [@vm.inferred-type.metadata=int] [@vm.inferred-type.metadata=#lib::B] self::knownResult().bar() as{TypeError} core::num) as{TypeError} core::int;
+  method bar() → core::int
+    return 3;
 }
 class TearOffInterfaceMethod extends core::Object {
   field dynamic bazz;
diff --git a/runtime/BUILD.gn b/runtime/BUILD.gn
index ed7631b..865e716 100644
--- a/runtime/BUILD.gn
+++ b/runtime/BUILD.gn
@@ -124,17 +124,6 @@
   }
 }
 
-config("dart_interpreter_config") {
-  defines = [ "DART_USE_INTERPRETER" ]
-}
-
-config("dart_maybe_interpreter_config") {
-  defines = []
-  if (dart_use_interpreter) {
-    defines += [ "DART_USE_INTERPRETER" ]
-  }
-}
-
 config("dart_config") {
   defines = []
 
@@ -169,6 +158,7 @@
       "-Wvla",
       "-Wno-conversion-null",
       "-Woverloaded-virtual",
+      "-Wno-comments",  # Conflicts with clang-format.
       "-g3",
       "-ggdb3",
       "-fno-rtti",
diff --git a/runtime/bin/BUILD.gn b/runtime/bin/BUILD.gn
index 96351e9..242e976 100644
--- a/runtime/bin/BUILD.gn
+++ b/runtime/bin/BUILD.gn
@@ -247,7 +247,6 @@
   static_library(target_name) {
     configs += [
                  "..:dart_arch_config",
-                 "..:dart_maybe_interpreter_config",
                  "..:dart_config",
                ] + extra_configs
     if (is_fuchsia) {
@@ -408,7 +407,6 @@
 
 build_gen_snapshot("gen_snapshot") {
   extra_configs = [
-    "..:dart_maybe_interpreter_config",
     "..:dart_maybe_product_config",
     "..:dart_os_config",
   ]
@@ -421,7 +419,6 @@
 
 build_gen_snapshot("gen_snapshot_product") {
   extra_configs = [
-    "..:dart_maybe_interpreter_config",
     "..:dart_product_config",
     "..:dart_os_config",
   ]
@@ -434,7 +431,6 @@
 
 build_gen_snapshot("gen_snapshot_fuchsia") {
   extra_configs = [
-    "..:dart_maybe_interpreter_config",
     "..:dart_maybe_product_config",
     "..:dart_os_fuchsia_config",
   ]
@@ -447,7 +443,6 @@
 
 build_gen_snapshot("gen_snapshot_product_fuchsia") {
   extra_configs = [
-    "..:dart_maybe_interpreter_config",
     "..:dart_product_config",
     "..:dart_os_fuchsia_config",
   ]
@@ -458,60 +453,6 @@
   ]
 }
 
-if (!is_win) {
-  build_gen_snapshot("gen_snapshot_interpreter") {
-    extra_configs = [
-      "..:dart_interpreter_config",
-      "..:dart_maybe_product_config",
-      "..:dart_os_config",
-    ]
-    extra_deps = [
-      ":gen_snapshot_dart_io",
-      ":libdart_builtin",
-      "..:libdart_nosnapshot_with_precompiler_interpreter",
-    ]
-  }
-
-  build_gen_snapshot("gen_snapshot_product_interpreter") {
-    extra_configs = [
-      "..:dart_interpreter_config",
-      "..:dart_product_config",
-      "..:dart_os_config",
-    ]
-    extra_deps = [
-      ":gen_snapshot_dart_io",
-      ":libdart_builtin",
-      "..:libdart_nosnapshot_with_precompiler_interpreter",
-    ]
-  }
-
-  build_gen_snapshot("gen_snapshot_interpreter_fuchsia") {
-    extra_configs = [
-      "..:dart_interpreter_config",
-      "..:dart_maybe_product_config",
-      "..:dart_os_fuchsia_config",
-    ]
-    extra_deps = [
-      ":gen_snapshot_dart_io_fuchsia",
-      ":libdart_builtin_fuchsia",
-      "..:libdart_nosnapshot_with_precompiler_interpreter_fuchsia",
-    ]
-  }
-
-  build_gen_snapshot("gen_snapshot_product_interpreter_fuchsia") {
-    extra_configs = [
-      "..:dart_interpreter_config",
-      "..:dart_product_config",
-      "..:dart_os_fuchsia_config",
-    ]
-    extra_deps = [
-      ":gen_snapshot_dart_io_product_fuchsia",
-      ":libdart_builtin_product_fuchsia",
-      "..:libdart_nosnapshot_with_precompiler_product_interpreter_fuchsia",
-    ]
-  }
-}
-
 # A source set for the implementation of 'dart:io' library
 # (without secure sockets) suitable for linking with gen_snapshot.
 template("build_gen_snapshot_dart_io") {
@@ -523,7 +464,6 @@
     configs += [
                  "..:dart_arch_config",
                  "..:dart_config",
-                 "..:dart_maybe_interpreter_config",
                  "..:dart_precompiler_config",
                ] + extra_configs
     deps = []
@@ -611,7 +551,6 @@
     configs += [
                  "..:dart_arch_config",
                  "..:dart_config",
-                 "..:dart_maybe_interpreter_config",
                  "..:dart_os_config",
                ] + extra_configs
     if (is_fuchsia) {
@@ -722,6 +661,13 @@
   ]
   args = [
     "--deterministic",
+
+    # TODO(asiva) remove these flags once the core snapshot is switched to
+    # dart 2.
+    "--no-strong",
+    "--no-sync-async",
+    "--reify-generic-functions",
+
     "--snapshot_kind=" + dart_core_snapshot_kind,
     "--vm_snapshot_data=" + rebase_path(vm_snapshot_data, root_build_dir),
     "--vm_snapshot_instructions=" +
@@ -940,7 +886,6 @@
                  "..:dart_arch_config",
                  "..:dart_config",
                  "..:dart_os_config",
-                 "..:dart_maybe_interpreter_config",
                  "..:dart_maybe_product_config",
                ] + extra_configs
     if (is_fuchsia) {
@@ -1186,7 +1131,6 @@
     "..:dart_arch_config",
     "..:dart_config",
     "..:dart_os_config",
-    "..:dart_maybe_interpreter_config",
     "..:dart_maybe_product_config",
   ]
   if (is_fuchsia) {
diff --git a/runtime/bin/dart_io_entries.txt b/runtime/bin/dart_io_entries.txt
index b21ec2d..b0f5fe4 100644
--- a/runtime/bin/dart_io_entries.txt
+++ b/runtime/bin/dart_io_entries.txt
@@ -1,32 +1,3 @@
 # 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.
-
-# Entry points into Dart from dart:io's C++.
-
-dart:io,::,_makeUint8ListView
-dart:io,::,_makeDatagram
-dart:io,::,_setupHooks
-dart:io,::,_getWatchSignalInternal
-dart:io,CertificateException,CertificateException.
-dart:io,Directory,Directory.
-dart:io,Directory,Directory.fromRawPath
-dart:io,File,File.
-dart:io,File,File.fromRawPath
-dart:io,FileSystemException,FileSystemException.
-dart:io,HandshakeException,HandshakeException.
-dart:io,Link,Link.
-dart:io,OSError,OSError.
-dart:io,TlsException,TlsException.
-dart:io,X509Certificate,X509Certificate._
-dart:io,_ExternalBuffer,set:data
-dart:io,_ExternalBuffer,get:start
-dart:io,_ExternalBuffer,set:start
-dart:io,_ExternalBuffer,set:end
-dart:io,_ExternalBuffer,get:end
-dart:io,_Platform,set:_nativeScript
-dart:io,_ProcessStartStatus,set:_errorCode
-dart:io,_ProcessStartStatus,set:_errorMessage
-dart:io,_SecureFilterImpl,get:buffers
-dart:io,_SecureFilterImpl,get:ENCRYPTED_SIZE
-dart:io,_SecureFilterImpl,get:SIZE
diff --git a/runtime/bin/eventhandler_fuchsia.cc b/runtime/bin/eventhandler_fuchsia.cc
index 0f16c8e..79f067f 100644
--- a/runtime/bin/eventhandler_fuchsia.cc
+++ b/runtime/bin/eventhandler_fuchsia.cc
@@ -82,13 +82,23 @@
   const int err = errno;
   LOG_INFO("IOHandle::Read: fd = %ld. read %ld bytes\n", fd_, read_bytes);
 
-  // Resubscribe to read events. We resubscribe to events even if read() returns
+  // Track the number of bytes available to read.
+  if (read_bytes > 0) {
+    available_bytes_ -=
+        (available_bytes_ >= read_bytes) ? read_bytes : available_bytes_;
+  }
+
+  // If we have read all available bytes, or if there was an error, then
+  // re-enable read events. We re-enable read events even if read() returns
   // an error. The error might be, e.g. EWOULDBLOCK, in which case
-  // re-subscription is necessary. Logic in the caller decides which errors are
-  // real, and which are ignore-and-continue.
-  read_events_enabled_ = true;
-  if (!AsyncWaitLocked(ZX_HANDLE_INVALID, POLLIN, wait_key_)) {
-    LOG_ERR("IOHandle::AsyncWait failed for fd = %ld\n", fd_);
+  // resubscription is necessary. Logic in the caller decides which errors
+  // are real, and which are ignore-and-continue.
+  if ((available_bytes_ == 0) || (read_bytes < 0)) {
+    // Resubscribe to read events.
+    read_events_enabled_ = true;
+    if (!AsyncWaitLocked(ZX_HANDLE_INVALID, POLLIN, wait_key_)) {
+      LOG_ERR("IOHandle::AsyncWait failed for fd = %ld\n", fd_);
+    }
   }
 
   errno = err;
@@ -128,6 +138,21 @@
   return socket;
 }
 
+intptr_t IOHandle::AvailableBytes() {
+  MutexLocker ml(mutex_);
+  ASSERT(fd_ >= 0);
+  intptr_t available = FDUtils::AvailableBytes(fd_);
+  LOG_INFO("IOHandle::AvailableBytes(): fd = %ld, bytes = %ld\n", fd_,
+           available);
+  if (available < 0) {
+    // If there is an error, we set available to 1 to trigger a read event that
+    // then propagates the error.
+    available = 1;
+  }
+  available_bytes_ = available;
+  return available;
+}
+
 void IOHandle::Close() {
   MutexLocker ml(mutex_);
   VOID_NO_RETRY_EXPECTED(close(fd_));
diff --git a/runtime/bin/eventhandler_fuchsia.h b/runtime/bin/eventhandler_fuchsia.h
index 5a9f1ab..c0c1778 100644
--- a/runtime/bin/eventhandler_fuchsia.h
+++ b/runtime/bin/eventhandler_fuchsia.h
@@ -46,6 +46,7 @@
   intptr_t Read(void* buffer, intptr_t num_bytes);
   intptr_t Write(const void* buffer, intptr_t num_bytes);
   intptr_t Accept(struct sockaddr* addr, socklen_t* addrlen);
+  intptr_t AvailableBytes();
 
   // Called from the EventHandler thread.
   void Close();
@@ -73,6 +74,10 @@
   Mutex* mutex_;
   bool write_events_enabled_;
   bool read_events_enabled_;
+  // Bytes remaining to be read from the socket. Read events should only be
+  // re-enabled when this drops to zero.
+  intptr_t available_bytes_;
+
   // TODO(zra): Add flag to enable/disable peer closed signal?
   intptr_t fd_;
   zx_handle_t handle_;
diff --git a/runtime/bin/fdutils_fuchsia.cc b/runtime/bin/fdutils_fuchsia.cc
index 6cd03e6..eb40c73 100644
--- a/runtime/bin/fdutils_fuchsia.cc
+++ b/runtime/bin/fdutils_fuchsia.cc
@@ -69,7 +69,6 @@
   int available;  // ioctl for FIONREAD expects an 'int*' argument.
   int result = NO_RETRY_EXPECTED(ioctl(fd, FIONREAD, &available));
   if (result < 0) {
-    perror("ioctl(fd, FIONREAD, &available) failed");
     return result;
   }
   ASSERT(available >= 0);
diff --git a/runtime/bin/gen_snapshot.cc b/runtime/bin/gen_snapshot.cc
index e75b1fa..1a93dd0 100644
--- a/runtime/bin/gen_snapshot.cc
+++ b/runtime/bin/gen_snapshot.cc
@@ -1030,10 +1030,8 @@
     int64_t entries = ParseEntryPointsManifestLines(file, NULL);
     fclose(file);
 
-    if (entries <= 0) {
-      Log::PrintErr(
-          "Manifest file `%s` specified is invalid or contained no entries\n",
-          path);
+    if (entries < 0) {
+      Log::PrintErr("Manifest file `%s` specified is invalid\n", path);
       return NULL;
     }
 
diff --git a/runtime/bin/main.cc b/runtime/bin/main.cc
index 2c18c3b..992dd7f 100644
--- a/runtime/bin/main.cc
+++ b/runtime/bin/main.cc
@@ -448,7 +448,7 @@
     packages_config = Options::packages_file();
   }
 
-  Dart_Isolate isolate;
+  Dart_Isolate isolate = NULL;
   IsolateData* isolate_data = NULL;
   bool isolate_run_app_snapshot = false;
   AppSnapshot* app_snapshot = NULL;
@@ -470,7 +470,8 @@
         DART_KERNEL_ISOLATE_NAME, main, isolate_snapshot_data,
         isolate_snapshot_instructions, app_isolate_shared_data,
         app_isolate_shared_instructions, flags, isolate_data, error);
-  } else {
+  }
+  if (isolate == NULL) {
     const uint8_t* kernel_service_buffer = NULL;
     intptr_t kernel_service_buffer_size = 0;
     dfe.LoadKernelService(&kernel_service_buffer, &kernel_service_buffer_size);
@@ -890,7 +891,7 @@
   }
 
   Dart_Isolate isolate = NULL;
-  if (flags.strong && Options::gen_snapshot_kind() == kAppAOT) {
+  if (Options::preview_dart_2() && Options::gen_snapshot_kind() == kAppAOT) {
     isolate = IsolateSetupHelperAotCompilationDart2(
         script_name, "main", Options::package_root(), Options::packages_file(),
         &flags, &error, &exit_code);
@@ -1261,8 +1262,9 @@
   init_params.entropy_source = DartUtils::EntropySource;
   init_params.get_service_assets = GetVMServiceAssetsArchiveCallback;
 #if !defined(DART_PRECOMPILED_RUNTIME)
-  init_params.start_kernel_isolate =
-      dfe.UseDartFrontend() && dfe.CanUseDartFrontend();
+  init_params.start_kernel_isolate = Options::preview_dart_2() &&
+                                     dfe.UseDartFrontend() &&
+                                     dfe.CanUseDartFrontend();
 #else
   init_params.start_kernel_isolate = false;
 #endif
diff --git a/runtime/bin/main_options.cc b/runtime/bin/main_options.cc
index 9e7a323..faf5a26 100644
--- a/runtime/bin/main_options.cc
+++ b/runtime/bin/main_options.cc
@@ -63,12 +63,6 @@
 CB_OPTIONS_LIST(CB_OPTION_DEFINITION)
 #undef CB_OPTION_DEFINITION
 
-void Options::SetDart2Options(CommandLineOptions* vm_options) {
-  vm_options->AddArgument("--strong");
-  vm_options->AddArgument("--reify-generic-functions");
-  vm_options->AddArgument("--sync-async");
-}
-
 void Options::SetDart1Options(CommandLineOptions* vm_options) {
   vm_options->AddArgument("--no-strong");
   vm_options->AddArgument("--no-reify-generic-functions");
@@ -348,9 +342,6 @@
   const char* kPrefix = "--";
   const intptr_t kPrefixLen = strlen(kPrefix);
 
-  // Set Dart 2 as the default option.
-  Options::SetDart2Options(vm_options);
-
   // Store the executable name.
   Platform::SetExecutableName(argv[0]);
 
diff --git a/runtime/bin/main_options.h b/runtime/bin/main_options.h
index 53184a4..f5672eb 100644
--- a/runtime/bin/main_options.h
+++ b/runtime/bin/main_options.h
@@ -112,7 +112,6 @@
 #undef CB_OPTIONS_DECL
 
   static bool preview_dart_2() { return !no_preview_dart_2(); }
-  static void SetDart2Options(CommandLineOptions* vm_options);
   static void SetDart1Options(CommandLineOptions* vm_options);
 
   static dart::SimpleHashMap* environment() { return environment_; }
diff --git a/runtime/bin/options.h b/runtime/bin/options.h
index e4edbcf..336d934 100644
--- a/runtime/bin/options.h
+++ b/runtime/bin/options.h
@@ -119,7 +119,25 @@
   static OptionProcessor_##name option_##name;
 
 #define DEFINE_BOOL_OPTION(name, variable)                                     \
-  DEFINE_BOOL_OPTION_CB(name, { variable = true; })
+  class OptionProcessor_##name : public OptionProcessor {                      \
+   public:                                                                     \
+    virtual bool Process(const char* option, CommandLineOptions* vm_options) { \
+      const char* value = OptionProcessor::ProcessOption(option, "--" #name);  \
+      if (value == NULL) {                                                     \
+        return false;                                                          \
+      }                                                                        \
+      if (*value == '=') {                                                     \
+        Log::PrintErr("Non-empty value for option " #name "\n");               \
+        return false;                                                          \
+      }                                                                        \
+      if (*value != '\0') {                                                    \
+        return false;                                                          \
+      }                                                                        \
+      variable = true;                                                         \
+      return true;                                                             \
+    }                                                                          \
+  };                                                                           \
+  static OptionProcessor_##name option_##name;
 
 #define DEFINE_BOOL_OPTION_SHORT(short_name, long_name, variable)              \
   class OptionProcessor_##long_name : public OptionProcessor {                 \
diff --git a/runtime/bin/process.cc b/runtime/bin/process.cc
index 065b477..ee3e4e31 100644
--- a/runtime/bin/process.cc
+++ b/runtime/bin/process.cc
@@ -164,10 +164,16 @@
     result =
         DartUtils::SetIntegerField(status_handle, "_errorCode", error_code);
     ThrowIfError(result);
-    result = DartUtils::SetStringField(status_handle, "_errorMessage",
-                                       os_error_message != NULL
-                                           ? os_error_message
-                                           : "Cannot get error message");
+    Dart_Handle val = DartUtils::NewString(os_error_message != NULL
+                                               ? os_error_message
+                                               : "Cannot get error message");
+    if (Dart_IsError(val)) {
+      // If conversion of the OS error message to a Dart string fails, fall back
+      // on a stock message.
+      val = DartUtils::NewString("OS error message was a not a utf8 string.");
+    }
+    result = Dart_SetField(status_handle, DartUtils::NewString("_errorMessage"),
+                           val);
     ThrowIfError(result);
   }
   Dart_SetBooleanReturnValue(args, error_code == 0);
diff --git a/runtime/bin/run_vm_tests.cc b/runtime/bin/run_vm_tests.cc
index ebd050e..b7616aa 100644
--- a/runtime/bin/run_vm_tests.cc
+++ b/runtime/bin/run_vm_tests.cc
@@ -150,7 +150,8 @@
     isolate = Dart_CreateIsolate(
         DART_KERNEL_ISOLATE_NAME, main, isolate_snapshot_data,
         isolate_snapshot_instructions, NULL, NULL, flags, isolate_data, error);
-  } else {
+  }
+  if (isolate == NULL) {
     bin::dfe.Init();
     bin::dfe.LoadKernelService(&kernel_service_buffer,
                                &kernel_service_buffer_size);
@@ -267,8 +268,23 @@
   bin::TimerUtils::InitOnce();
   bin::EventHandler::Start();
 
-  const char* error = Flags::ProcessCommandLineFlags(dart_argc, dart_argv);
-  ASSERT(error == NULL);
+  const char* error;
+  if (!start_kernel_isolate) {
+    int extra_argc = dart_argc + 3;
+    const char** extra_argv = new const char*[extra_argc];
+    for (intptr_t i = 0; i < dart_argc; i++) {
+      extra_argv[i] = dart_argv[i];
+    }
+    extra_argv[dart_argc] = "--no-strong";
+    extra_argv[dart_argc + 1] = "--no-reify_generic_functions";
+    extra_argv[dart_argc + 2] = "--no-sync-async";
+    error = Flags::ProcessCommandLineFlags(extra_argc, extra_argv);
+    delete[] extra_argv;
+    ASSERT(error == NULL);
+  } else {
+    error = Flags::ProcessCommandLineFlags(dart_argc, dart_argv);
+    ASSERT(error == NULL);
+  }
 
   error = Dart::InitOnce(
       dart::bin::vm_snapshot_data, dart::bin::vm_snapshot_instructions,
diff --git a/runtime/bin/socket_base_fuchsia.cc b/runtime/bin/socket_base_fuchsia.cc
index a6a524d..b89abf2 100644
--- a/runtime/bin/socket_base_fuchsia.cc
+++ b/runtime/bin/socket_base_fuchsia.cc
@@ -86,10 +86,7 @@
 
 intptr_t SocketBase::Available(intptr_t fd) {
   IOHandle* handle = reinterpret_cast<IOHandle*>(fd);
-  ASSERT(handle->fd() >= 0);
-  intptr_t available = FDUtils::AvailableBytes(handle->fd());
-  LOG_INFO("SocketBase::Available(%ld) = %ld\n", handle->fd(), available);
-  return available;
+  return handle->AvailableBytes();
 }
 
 intptr_t SocketBase::Read(intptr_t fd,
diff --git a/runtime/configs.gni b/runtime/configs.gni
index fa5658f..b678f17 100644
--- a/runtime/configs.gni
+++ b/runtime/configs.gni
@@ -16,33 +16,13 @@
   "$_dart_runtime:dart_os_fuchsia_config",
 ]
 
-_maybe_interpreter_maybe_product = [
-  "$_dart_runtime:dart_maybe_interpreter_config",
-  "$_dart_runtime:dart_maybe_product_config",
-]
+_maybe_product = [ "$_dart_runtime:dart_maybe_product_config" ]
 
-_maybe_interpreter_product = [
-  "$_dart_runtime:dart_maybe_interpreter_config",
-  "$_dart_runtime:dart_product_config",
-]
+_product = [ "$_dart_runtime:dart_product_config" ]
 
-_interpreter_maybe_product = [
-  "$_dart_runtime:dart_interpreter_config",
-  "$_dart_runtime:dart_maybe_product_config",
-]
+_jit_config = _base_config + _maybe_product
 
-_interpreter_product = [
-  "$_dart_runtime:dart_interpreter_config",
-  "$_dart_runtime:dart_product_config",
-]
-
-_jit_config = _base_config + _maybe_interpreter_maybe_product
-
-_jit_product_config = _base_config + _maybe_interpreter_product
-
-_jit_interpreter_config = _base_config + _interpreter_maybe_product
-
-_jit_product_interpreter_config = _base_config + _interpreter_product
+_jit_product_config = _base_config + _product
 
 _precompiled_runtime_config =
     _base_config + [
@@ -72,28 +52,16 @@
 ]
 
 _nosnapshot_with_precompiler_config =
-    _base_config + _nosnapshot_precompiler_base + _maybe_interpreter_maybe_product
-
-_nosnapshot_with_precompiler_interpreter_config =
-    _base_config + _nosnapshot_precompiler_base + _interpreter_maybe_product
-
-_nosnapshot_with_precompiler_product_interpreter_config =
-    _base_config + _nosnapshot_precompiler_base + _interpreter_product
+    _base_config + _nosnapshot_precompiler_base + _maybe_product
 
 _nosnapshot_with_precompiler_product_config =
-    _base_config + _nosnapshot_precompiler_base + _maybe_interpreter_product
+    _base_config + _nosnapshot_precompiler_base + _product
 
 _nosnapshot_with_precompiler_fuchsia_config =
-    _base_fuchsia_config + _nosnapshot_precompiler_base + _maybe_interpreter_maybe_product
+    _base_fuchsia_config + _nosnapshot_precompiler_base + _maybe_product
 
 _nosnapshot_with_precompiler_product_fuchsia_config =
-    _base_fuchsia_config + _nosnapshot_precompiler_base + _maybe_interpreter_product
-
-_nosnapshot_with_precompiler_interpreter_fuchsia_config =
-    _base_fuchsia_config + _nosnapshot_precompiler_base + _interpreter_maybe_product
-
-_nosnapshot_with_precompiler_product_interpreter_fuchsia_config =
-    _base_fuchsia_config + _nosnapshot_precompiler_base + _interpreter_product
+    _base_fuchsia_config + _nosnapshot_precompiler_base + _product
 
 _all_configs = [
   {
@@ -148,42 +116,6 @@
   },
 ]
 
-# The interpreter is not currently needed on Windows.
-if (!is_win) {
-  _all_configs += [
-    {
-      suffix = "_jit_interpreter"
-      configs = _jit_interpreter_config
-      snapshot = true
-    },
-    {
-      suffix = "_jit_product_interpreter"
-      configs = _jit_product_interpreter_config
-      snapshot = true
-    },
-    {
-      suffix = "_nosnapshot_with_precompiler_interpreter"
-      configs = _nosnapshot_with_precompiler_interpreter_config
-      snapshot = false
-    },
-    {
-      suffix = "_nosnapshot_with_precompiler_product_interpreter"
-      configs = _nosnapshot_with_precompiler_product_interpreter_config
-      snapshot = false
-    },
-    {
-      suffix = "_nosnapshot_with_precompiler_interpreter_fuchsia"
-      configs = _nosnapshot_with_precompiler_interpreter_fuchsia_config
-      snapshot = false
-    },
-    {
-      suffix = "_nosnapshot_with_precompiler_product_interpreter_fuchsia"
-      configs = _nosnapshot_with_precompiler_product_interpreter_fuchsia_config
-      snapshot = false
-    },
-  ]
-}
-
 # This template creates a target for each of the configurations listed above.
 # For example:
 #
diff --git a/runtime/docs/compiler/exceptions.md b/runtime/docs/compiler/exceptions.md
new file mode 100644
index 0000000..222e5f8
--- /dev/null
+++ b/runtime/docs/compiler/exceptions.md
@@ -0,0 +1,92 @@
+# Exceptions Implementation
+
+This page describes how exceptions throwing and catching is implemented in the
+VM.
+
+## Intermediate Language
+
+Dart VM's IL **does not** explicitly represent exceptional control flow in its
+flow graph, there are **no** explicit exceptional edges connecting potentially
+throwing instructions (e.g. calls) with corresponding catch blocks. Instead this
+connection is defined at the block level: all exceptions that occur in any block
+with the given `try_index` will be caught by `CatchBlockEntry` with the equal
+`catch_try_index`.
+
+![Catch Block Entry](images/catch-block-entry-0.png)
+
+For optimized code this means that data flow associated with exceptional control
+flow is also represented implicitly: due to the absence of explicit exceptional
+edges the data flow can't be represented using explicit phi-functions. Instead
+in optimized code each `CatchBlockEntry` is treated almost as if it was an
+independent entry into the function: for each variable `v` `CatchBlockEntry`
+will contain a `Parameter(...)` instruction restoring variable state at catch
+entry from a fixed location on the stack. When an exception is thrown runtime
+system takes care of populating these stack slots with right values - current
+state of corresponding local variables. It's easy to see a parallel between
+these `Parameter(...)` instructions and `Phi(...)` instructions that would be
+used if exception control flow would be explicit.
+
+![Catch Block Entry](images/catch-block-entry-1.png)
+
+How does runtime system populate stack slots corresponding to these
+`Parameter(...)` instructions? During compilation necessary information is
+available in _deoptimization environment_ attached to the instruction. This
+environment encodes the state of local variables in terms of SSA values i.e. if
+we need to reconstruct unoptimized frame which SSA value should be stored into
+the given local variable (see [Optimized
+IL](compiler-pipeline-overview.md#optimized-il) for
+an overview). However the way we use these information for exception handling is
+slightly different in JIT and AOT modes.
+
+### AOT mode
+
+AOT mode does not support deoptimization and thus AOT compiler does not
+associate any deoptimization metadata with generated code. Instead
+deoptimization environments associated with instructions that can throw are
+converted into `CatchEntryMoves` metadata during code generation and resulting
+metadata is stored `RawCode::catch_entry_moves_maps_` in a compressed form.
+
+`CatchEntryMoves` is essentially a sequence of moves which runtime needs to
+perform to create the state that catch entry expects. There are three types of
+moves:
+
+* `*(FP + Dst) <- ObjectPool[PoolIndex]` - a move of a constant from an object
+pool;
+* `*(FP + Dst) <- *(FP + Src)` - a move of a tagged value;
+* `*(FP + Dst) <- Box<Rep>(*(FP + Src))` - a boxing operation for an untagged
+value;
+
+When an exception is caught runtime decompresses the metadata associated with the
+call site which has thrown an exception and uses it to prepare the state of the
+stack for the catch block entry. See
+`ExceptionHandlerFinder::{ReadCompressedCatchEntryMoves, ExecuteCatchEntryMoves}`.
+
+NOTE: See [this
+design/motivation](https://docs.google.com/a/google.com/document/d/1_vX8VkvHVA1Om7jjONiWLA325k_JmSZuvVClet-x-xM/edit?usp=sharing)
+document for `CatchEntryMoves` metadata
+
+### JIT mode
+
+JIT mode heavily relies on deoptimization and all call instructions have (lazy)
+deoptimization environments associated with them. These environments are
+converted to [deoptimization
+instructions](deoptimization.md#in-optimized-code)
+during code generation and stored on the `Code` object.
+
+When an exception is caught the runtime system converts deoptimization
+environment associated with the call site that threw an exception into
+`CatchEntryMoves` and then uses it to prepare the state of the stack for the
+catch block entry. See `ExceptionHandlerFinder::{GetCatchEntryMovesFromDeopt, ExecuteCatchEntryMoves}`.
+
+Constructing `CatchEntryMoves` dynamically from deoptimization instructions
+allows to avoid unnecessary duplication of the metadata and save memory: as
+deoptimization environments contain all information necessary for constructing
+correct stack state.
+
+IMPORTANT: There is a subtle difference between DBC and other architectures with
+respect to catch block entry state. On normal architectures `Parameter(i)` at
+catch entry would be associated with the same stack space that would be used to
+store variable with index `i`. On DBC however at catch entry `Parameter(i)`
+would be allocated to a separate scratch space at the very top of the register
+space. See `FlowGraphAllocator::ProcessInitialDefinition` and
+`FlowGraphCompiler::CatchEntryRegForVariable`.
diff --git a/runtime/docs/compiler/images/catch-block-entry-0.png b/runtime/docs/compiler/images/catch-block-entry-0.png
new file mode 100644
index 0000000..b6013de
--- /dev/null
+++ b/runtime/docs/compiler/images/catch-block-entry-0.png
Binary files differ
diff --git a/runtime/docs/compiler/images/catch-block-entry-1.png b/runtime/docs/compiler/images/catch-block-entry-1.png
new file mode 100644
index 0000000..c41adb4
--- /dev/null
+++ b/runtime/docs/compiler/images/catch-block-entry-1.png
Binary files differ
diff --git a/runtime/docs/gc.md b/runtime/docs/gc.md
new file mode 100644
index 0000000..22aebee
--- /dev/null
+++ b/runtime/docs/gc.md
@@ -0,0 +1,98 @@
+# Garbage Collection
+
+## Object representation
+
+## Scavenge
+
+## Mark-Sweep
+
+## Mark-Compact
+
+## Concurrent Marking
+
+To reduce the time the mutator is paused for old-space GCs, we allow the mutator to continue running during most of the marking work. 
+
+### Barrier
+
+With the mutator and marker running concurrently, the mutator could write a pointer to an object that has not been marked (TARGET) into an object that has already been marked and visited (SOURCE), leading to incorrect collection of TARGET. To prevent this, the write barrier checks if a store creates a pointer from an old-space object to an old-space object that is not marked, and marks the target object for such stores. We ignore pointers from new-space objects because we treat new-space objects as roots and will revisit them to finalize marking. We ignore the marking state of the source object to avoid expensive memory barriers required to ensure reordering of accesses to the header and slots can't lead skipped marking, and on the assumption that objects accessed during marking are likely to remain live when marking finishes.
+
+The barrier is equivalent to
+
+```
+StorePoint(RawObject* source, RawObject** slot, RawObject* target) {
+  *slot = target;
+  if (target->IsSmi()) return;
+  if (source->IsOldObject() && !source->IsRemembered() && target->IsNewObject()) {
+    source->SetRemembered();
+    AddToRememberedSet(source);
+  } else if (source->IsOldObject() && target->IsOldObject() && !target->IsMarked() && Thread::Current()->IsMarking()) {
+    if (target->TryAcquireMarkBit()) {
+      AddToMarkList(target);
+    }
+  }
+}
+```
+
+But we combine the generational and incremental checks with a shift-and-mask.
+
+```
+enum HeaderBits {
+  ...
+  kOldAndNotMarkedBit,      // Incremental barrier target.
+  kNewBit,                  // Generational barrier target.
+  kOldBit,                  // Incremental barrier source.
+  kOldAndNotRememberedBit,  // Generational barrier source.
+  ...
+};
+
+static const intptr_t kGenerationalBarrierMask = 1 << kNewBit;
+static const intptr_t kIncrementalBarrierMask = 1 << kOldAndNotMarkedBit;
+static const intptr_t kBarrierOverlapShift = 2;
+COMPILE_ASSERT(kOldAndNotMarkedBit + kBarrierOverlapShift == kOldBit);
+COMPILE_ASSERT(kNewBit + kBarrierOverlapShift == kOldAndNotRememberedBit);
+
+StorePointer(RawObject* source, RawObject** slot, RawObject* target) {
+  *slot = target;
+  if (target->IsSmi()) return;
+  if ((source->header() >> kBarrierOverlapShift) &&
+      (target->header()) &&
+      Thread::Current()->barrier_mask()) {
+    if (target->IsNewObject()) {
+      source->SetRemembered();
+      AddToRememberedSet(source);
+    } else {
+      if (target->TryAcquireMarkBit()) {
+        AddToMarkList(target);
+      }
+    }
+  }
+}
+
+StoreIntoObject(object, value, offset)
+  str   value, object#offset
+  tbnz  value, kSmiTagShift, done
+  lbu   tmp, value#headerOffset
+  lbu   tmp2, object#headerOffset
+  and   tmp, tmp2 LSR kBarrierOverlapShift
+  tst   tmp, BARRIER_MASK
+  bz    done
+  mov   tmp2, value
+  lw    tmp, THR#writeBarrierEntryPointOffset
+  blr   tmp
+done:
+
+```
+
+### Data races
+
+Operations on headers and slots use (relaxed ordering)[https://en.cppreference.com/w/cpp/atomic/memory_order] and do not provide synchronization.
+
+The concurrent marker starts with an acquire-release operation, so all writes by the mutator up to the time that marking starts are visible to the marker.
+
+For old-space objects created before marking started, in each slot the marker can see either its value at the time marking started or any subsequent value sorted in the slot. Any slot that contained a pointer continues to continue a valid pointer for the object's lifetime, so no matter which value the marker sees, it won't interpret a non-pointer as a pointer. (The one interesting case here is array truncation, where some slot in the array will become the header of a filler object. We ensure this is safe for concurrent marking by ensuring the header for the filler object looks like a Smi.) If the marker sees an old value, we may lose some precision and retain a dead object, but we remain correct because the new value has been marked by the mutator.
+
+For old-space objects created after marking started, the marker may see uninitialized values because operations on slots are not synchronized. To prevent this, during marking we allocate old-space objects black (marked) so the marker will not visit them.
+
+New-space objects and roots are only visited during a safepoint, and safepoints establish synchronization.
+
+When the mutator's mark block becomes full, it transfered to the marker by an acquire-release operation, so the marker will see the stores into the block.
diff --git a/runtime/docs/pragmas.md b/runtime/docs/pragmas.md
index 0cc036c..c739826 100644
--- a/runtime/docs/pragmas.md
+++ b/runtime/docs/pragmas.md
@@ -9,9 +9,21 @@
   [Defining entry-points into Dart code for an embedder or native methods]
   (file://../vm/compiler/aot/entry_points_pragma.md)
 
+## Pragmas for internal use
+
+These pragmas can cause unsound behavior if used incorrectly and therefore are only allowed within the core SDK libraries.
+
+- **vm:exact-result-type**
+
+  [Declaring an exact result type of a method]
+  (file://../vm/compiler/result_type_pragma.md)
+
 ## Pragmas for internal testing
 
-These pragmas are used for inspecting or modifying internal VM state and should be used exclusively by SDK tests. They must be enabled with the `--enable-testing-pragmas` flag. The names of these pragmas are prefixed with "testing". Additionally, they are categorized into "safe" and "unsafe" forms: "safe" pragmas should not affect the behavior of the program and can be safely added anywhere. "unsafe" pragmas may change the code's behavior or may cause the VM to crash if used improperly.
+These pragmas are used for inspecting or modifying internal VM state and should be used exclusively by SDK tests.
+They must be enabled with the `--enable-testing-pragmas` flag.
+The names of these pragmas are prefixed with "testing".
+Additionally, they are categorized into "safe" and "unsafe" forms: "safe" pragmas should not affect the behavior of the program and can be safely added anywhere, whereas "unsafe" pragmas may change the code's behavior or may cause the VM to crash if used improperly.
 
 - **vm:testing.unsafe.trace-entrypoints-fn**
 
diff --git a/runtime/include/dart_api.h b/runtime/include/dart_api.h
index eef2f9fb..c1c02df 100644
--- a/runtime/include/dart_api.h
+++ b/runtime/include/dart_api.h
@@ -553,7 +553,7 @@
  * for each part.
  */
 
-#define DART_FLAGS_CURRENT_VERSION (0x00000006)
+#define DART_FLAGS_CURRENT_VERSION (0x00000007)
 
 typedef struct {
   int32_t version;
@@ -566,10 +566,7 @@
   bool use_dart_frontend;
   bool obfuscate;
   Dart_QualifiedFunctionName* entry_points;
-  bool reify_generic_functions;
-  bool strong;
   bool load_vmservice_library;
-  bool sync_async;
   bool unsafe_trust_strong_mode_types;
 } Dart_IsolateFlags;
 
diff --git a/runtime/lib/array.dart b/runtime/lib/array.dart
index 93fcbe6..2e93901 100644
--- a/runtime/lib/array.dart
+++ b/runtime/lib/array.dart
@@ -6,6 +6,7 @@
 
 @pragma("vm:entry-point")
 class _List<E> extends FixedLengthListBase<E> {
+  @pragma("vm:exact-result-type", _List)
   factory _List(length) native "List_allocate";
 
   E operator [](int index) native "List_getIndexed";
@@ -16,6 +17,7 @@
 
   void _setIndexed(int index, E value) native "List_setIndexed";
 
+  @pragma("vm:exact-result-type", "dart:core#_Smi")
   int get length native "List_getLength";
 
   List _slice(int start, int count, bool needsTypeArgument) {
@@ -134,6 +136,7 @@
 
   E operator [](int index) native "List_getIndexed";
 
+  @pragma("vm:exact-result-type", "dart:core#_Smi")
   int get length native "List_getLength";
 
   List<E> sublist(int start, [int end]) {
diff --git a/runtime/lib/bigint_patch.dart b/runtime/lib/bigint_patch.dart
index 78b4298..aa33a6e 100644
--- a/runtime/lib/bigint_patch.dart
+++ b/runtime/lib/bigint_patch.dart
@@ -1091,6 +1091,7 @@
   ///
   /// Note: This function may be intrinsified. Intrinsics on 64-bit platforms
   /// process digit pairs at even indices and returns 2.
+  @pragma("vm:exact-result-type", "dart:core#_Smi")
   static int _mulAdd(
       Uint32List xDigits,
       int xIndex,
@@ -1141,6 +1142,7 @@
   ///
   /// Note: This function may be intrinsified. Intrinsics on 64-bit platforms
   /// process digit pairs at even indices and returns 2.
+  @pragma("vm:exact-result-type", "dart:core#_Smi")
   static int _sqrAdd(
       Uint32List xDigits, int i, Uint32List acculumatorDigits, int used) {
     int x = xDigits[i];
@@ -1261,6 +1263,7 @@
   /// Estimate `args[_quotientDigit.._quotientHighDigit] = digits[i-3..i] ~/
   /// args[_divisorLowTopDigit.._divisorTopDigit]`.
   /// Returns 2.
+  @pragma("vm:exact-result-type", "dart:core#_Smi")
   static int _estimateQuotientDigit(Uint32List args, Uint32List digits, int i) {
     // Verify that digit pairs are accessible for 64-bit processing.
     assert(digits.length >= 4);
@@ -2596,6 +2599,7 @@
   //   args[_muDigit.._muHighDigit] =
   //     args[_rhoDigit.._rhoHighDigit] * digits[i..i+1] mod _digitBase^2.
   //   Returns 2.
+  @pragma("vm:exact-result-type", "dart:core#_Smi")
   static int _mulMod(Uint32List args, Uint32List digits, int i) {
     var rhol = args[_rhoDigit] & _BigIntImpl._halfDigitMask;
     var rhoh = args[_rhoDigit] >> _BigIntImpl._halfDigitBits;
diff --git a/runtime/lib/class_id.dart b/runtime/lib/class_id.dart
index f50b848..2260a75 100644
--- a/runtime/lib/class_id.dart
+++ b/runtime/lib/class_id.dart
@@ -5,6 +5,7 @@
 // part of "internal_patch.dart";
 
 class ClassID {
+  @pragma("vm:exact-result-type", "dart:core#_Smi")
   static int getID(Object value) native "ClassID_getID";
 
   // VM injects class id constants into this class.
diff --git a/runtime/lib/class_id_fasta.dart b/runtime/lib/class_id_fasta.dart
index 150488e..0a89db4 100644
--- a/runtime/lib/class_id_fasta.dart
+++ b/runtime/lib/class_id_fasta.dart
@@ -5,6 +5,7 @@
 // part of "internal_patch.dart";
 
 class ClassID {
+  @pragma("vm:exact-result-type", "dart:core#_Smi")
   static int getID(Object value) native "ClassID_getID";
 
   static final int cidArray = 0;
diff --git a/runtime/lib/compact_hash.dart b/runtime/lib/compact_hash.dart
index f05df0d..c374ec6 100644
--- a/runtime/lib/compact_hash.dart
+++ b/runtime/lib/compact_hash.dart
@@ -46,18 +46,23 @@
 
 // Base class for VM-internal classes; keep in sync with _HashFieldBase.
 abstract class _HashVMBase {
+  @pragma("vm:exact-result-type", "dart:typed_data#_Uint32List")
   Uint32List get _index native "LinkedHashMap_getIndex";
   void set _index(Uint32List value) native "LinkedHashMap_setIndex";
 
+  @pragma("vm:exact-result-type", "dart:core#_Smi")
   int get _hashMask native "LinkedHashMap_getHashMask";
   void set _hashMask(int value) native "LinkedHashMap_setHashMask";
 
+  @pragma("vm:exact-result-type", "dart:core#_List")
   List get _data native "LinkedHashMap_getData";
   void set _data(List value) native "LinkedHashMap_setData";
 
+  @pragma("vm:exact-result-type", "dart:core#_Smi")
   int get _usedData native "LinkedHashMap_getUsedData";
   void set _usedData(int value) native "LinkedHashMap_setUsedData";
 
+  @pragma("vm:exact-result-type", "dart:core#_Smi")
   int get _deletedKeys native "LinkedHashMap_getDeletedKeys";
   void set _deletedKeys(int value) native "LinkedHashMap_setDeletedKeys";
 }
diff --git a/runtime/lib/double.dart b/runtime/lib/double.dart
index 1a69396..f2de9c0 100644
--- a/runtime/lib/double.dart
+++ b/runtime/lib/double.dart
@@ -6,27 +6,34 @@
 
 @pragma("vm:entry-point")
 class _Double implements double {
+  @pragma("vm:exact-result-type", _Double)
   factory _Double.fromInteger(int value) native "Double_doubleFromInteger";
 
   int get hashCode native "Double_hashCode";
   int get _identityHashCode native "Double_hashCode";
 
+  @pragma("vm:exact-result-type", _Double)
   double operator +(num other) {
     return _add(other.toDouble());
   }
 
+  @pragma("vm:exact-result-type", _Double)
   double _add(double other) native "Double_add";
 
+  @pragma("vm:exact-result-type", _Double)
   double operator -(num other) {
     return _sub(other.toDouble());
   }
 
+  @pragma("vm:exact-result-type", _Double)
   double _sub(double other) native "Double_sub";
 
+  @pragma("vm:exact-result-type", _Double)
   double operator *(num other) {
     return _mul(other.toDouble());
   }
 
+  @pragma("vm:exact-result-type", _Double)
   double _mul(double other) native "Double_mul";
 
   int operator ~/(num other) {
@@ -35,16 +42,19 @@
 
   int _trunc_div(double other) native "Double_trunc_div";
 
+  @pragma("vm:exact-result-type", _Double)
   double operator /(num other) {
     return _div(other.toDouble());
   }
 
+  @pragma("vm:exact-result-type", _Double)
   double _div(double other) native "Double_div";
 
   double operator %(num other) {
     return _modulo(other.toDouble());
   }
 
+  @pragma("vm:exact-result-type", _Double)
   double _modulo(double other) native "Double_modulo";
 
   double remainder(num other) {
@@ -53,27 +63,35 @@
 
   double _remainder(double other) native "Double_remainder";
 
+  @pragma("vm:exact-result-type", _Double)
   double operator -() native "Double_flipSignBit";
 
+  @pragma("vm:exact-result-type", bool)
   bool operator ==(Object other) {
     return (other is num) && _equal(other.toDouble());
   }
 
   bool _equal(double other) native "Double_equal";
   bool _equalToInteger(int other) native "Double_equalToInteger";
+
+  @pragma("vm:exact-result-type", bool)
   bool operator <(num other) {
     return other > this;
   }
 
+  @pragma("vm:exact-result-type", bool)
   bool operator >(num other) {
     return _greaterThan(other.toDouble());
   }
 
   bool _greaterThan(double other) native "Double_greaterThan";
+
+  @pragma("vm:exact-result-type", bool)
   bool operator >=(num other) {
     return (this == other) || (this > other);
   }
 
+  @pragma("vm:exact-result-type", bool)
   bool operator <=(num other) {
     return (this == other) || (this < other);
   }
@@ -86,6 +104,7 @@
     return new _Double.fromInteger(other)._sub(this);
   }
 
+  @pragma("vm:exact-result-type", "dart:core#_Double")
   double _mulFromInteger(int other) {
     return new _Double.fromInteger(other)._mul(this);
   }
@@ -105,8 +124,11 @@
   bool _greaterThanFromInteger(int other)
       native "Double_greaterThanFromInteger";
 
+  @pragma("vm:exact-result-type", bool)
   bool get isNegative native "Double_getIsNegative";
+  @pragma("vm:exact-result-type", bool)
   bool get isInfinite native "Double_getIsInfinite";
+  @pragma("vm:exact-result-type", bool)
   bool get isNaN native "Double_getIsNaN";
   bool get isFinite => !isInfinite && !isNaN; // Can be optimized.
 
@@ -127,9 +149,13 @@
   int ceil() => ceilToDouble().toInt();
   int truncate() => truncateToDouble().toInt();
 
+  @pragma("vm:exact-result-type", _Double)
   double roundToDouble() native "Double_round";
+  @pragma("vm:exact-result-type", _Double)
   double floorToDouble() native "Double_floor";
+  @pragma("vm:exact-result-type", _Double)
   double ceilToDouble() native "Double_ceil";
+  @pragma("vm:exact-result-type", _Double)
   double truncateToDouble() native "Double_truncate";
 
   num clamp(num lowerLimit, num upperLimit) {
diff --git a/runtime/lib/growable_array.dart b/runtime/lib/growable_array.dart
index 68dac2c..d23632f 100644
--- a/runtime/lib/growable_array.dart
+++ b/runtime/lib/growable_array.dart
@@ -104,10 +104,13 @@
     return new _GrowableList<T>.withData(data);
   }
 
+  @pragma("vm:exact-result-type", _GrowableList)
   factory _GrowableList.withData(_List data) native "GrowableList_allocate";
 
+  @pragma("vm:exact-result-type", "dart:core#_Smi")
   int get _capacity native "GrowableList_getCapacity";
 
+  @pragma("vm:exact-result-type", "dart:core#_Smi")
   int get length native "GrowableList_getLength";
 
   void set length(int new_length) {
diff --git a/runtime/lib/identical_patch.dart b/runtime/lib/identical_patch.dart
index b229c20..36607fb 100644
--- a/runtime/lib/identical_patch.dart
+++ b/runtime/lib/identical_patch.dart
@@ -5,6 +5,7 @@
 // part of "core_patch.dart";
 
 @patch
+@pragma("vm:exact-result-type", bool)
 bool identical(Object a, Object b) native "Identical_comparison";
 
 @patch
diff --git a/runtime/lib/integers.dart b/runtime/lib/integers.dart
index fb20195..3e427c4 100644
--- a/runtime/lib/integers.dart
+++ b/runtime/lib/integers.dart
@@ -61,25 +61,31 @@
   int operator >>(int other) => other._shrFromInteger(this);
   int operator <<(int other) => other._shlFromInteger(this);
 
+  @pragma("vm:exact-result-type", bool)
   bool operator <(num other) {
     return other > this;
   }
 
+  @pragma("vm:exact-result-type", bool)
   bool operator >(num other) {
     return other._greaterThanFromInteger(this);
   }
 
+  @pragma("vm:exact-result-type", bool)
   bool operator >=(num other) {
     return (this == other) || (this > other);
   }
 
+  @pragma("vm:exact-result-type", bool)
   bool operator <=(num other) {
     return (this == other) || (this < other);
   }
 
+  @pragma("vm:exact-result-type", bool)
   bool _greaterThanFromInteger(int other)
       native "Integer_greaterThanFromInteger";
 
+  @pragma("vm:exact-result-type", bool)
   bool operator ==(Object other) {
     if (other is num) {
       return other._equalToInteger(this);
@@ -87,6 +93,7 @@
     return false;
   }
 
+  @pragma("vm:exact-result-type", bool)
   bool _equalToInteger(int other) native "Integer_equalToInteger";
   int abs() {
     return this < 0 ? -this : this;
@@ -224,6 +231,7 @@
     return this;
   }
 
+  @pragma("vm:exact-result-type", _Double)
   double toDouble() {
     return new _Double.fromInteger(this);
   }
@@ -458,11 +466,14 @@
   }
   int get hashCode => this;
   int get _identityHashCode => this;
+  @pragma("vm:exact-result-type", "dart:core#_Smi")
   int operator ~() native "Smi_bitNegate";
+  @pragma("vm:exact-result-type", "dart:core#_Smi")
   int get bitLength native "Smi_bitLength";
 
   int operator &(int other) => other._bitAndFromSmi(this);
 
+  @pragma("vm:exact-result-type", "dart:core#_Smi")
   int _bitAndFromSmi(_Smi other) native "Smi_bitAndFromSmi";
 
   /**
diff --git a/runtime/lib/internal_patch.dart b/runtime/lib/internal_patch.dart
index 8446926..83359ac 100644
--- a/runtime/lib/internal_patch.dart
+++ b/runtime/lib/internal_patch.dart
@@ -69,6 +69,7 @@
 bool _inquireIs64Bit() native "Internal_inquireIs64Bit";
 
 @pragma("vm:entry-point")
+@pragma("vm:exact-result-type", bool)
 bool _classRangeCheck(int cid, int lowerLimit, int upperLimit) {
   return cid >= lowerLimit && cid <= upperLimit;
 }
diff --git a/runtime/lib/isolate.cc b/runtime/lib/isolate.cc
index 289c4aa..261ed5d 100644
--- a/runtime/lib/isolate.cc
+++ b/runtime/lib/isolate.cc
@@ -361,7 +361,7 @@
     Dart_IsolateFlags* flags = state->isolate_flags();
     flags->enable_asserts = is_checked;
     // Do not enable type checks in strong mode.
-    flags->enable_type_checks = is_checked && !flags->strong;
+    flags->enable_type_checks = is_checked && !FLAG_strong;
   }
 
   ThreadPool::Task* spawn_task = new SpawnIsolateTask(state);
diff --git a/runtime/lib/math_patch.dart b/runtime/lib/math_patch.dart
index ff9b2fa..73eb844 100644
--- a/runtime/lib/math_patch.dart
+++ b/runtime/lib/math_patch.dart
@@ -83,6 +83,7 @@
   return _doublePow(x.toDouble(), exponent.toDouble());
 }
 
+@pragma("vm:exact-result-type", "dart:core#_Double")
 double _doublePow(double base, double exponent) {
   if (exponent == 0.0) {
     return 1.0; // ECMA-262 15.8.2.13
@@ -125,20 +126,28 @@
 }
 
 @patch
+@pragma("vm:exact-result-type", "dart:core#_Double")
 double atan2(num a, num b) => _atan2(a.toDouble(), b.toDouble());
 @patch
+@pragma("vm:exact-result-type", "dart:core#_Double")
 double sin(num radians) => _sin(radians.toDouble());
 @patch
+@pragma("vm:exact-result-type", "dart:core#_Double")
 double cos(num radians) => _cos(radians.toDouble());
 @patch
+@pragma("vm:exact-result-type", "dart:core#_Double")
 double tan(num radians) => _tan(radians.toDouble());
 @patch
+@pragma("vm:exact-result-type", "dart:core#_Double")
 double acos(num x) => _acos(x.toDouble());
 @patch
+@pragma("vm:exact-result-type", "dart:core#_Double")
 double asin(num x) => _asin(x.toDouble());
 @patch
+@pragma("vm:exact-result-type", "dart:core#_Double")
 double atan(num x) => _atan(x.toDouble());
 @patch
+@pragma("vm:exact-result-type", "dart:core#_Double")
 double sqrt(num x) => _sqrt(x.toDouble());
 @patch
 double exp(num x) => _exp(x.toDouble());
diff --git a/runtime/lib/object.cc b/runtime/lib/object.cc
index 7b0537f..58da284 100644
--- a/runtime/lib/object.cc
+++ b/runtime/lib/object.cc
@@ -380,7 +380,7 @@
   Class& interface_cls = Class::Handle(zone);
   intptr_t num_type_args = 0;  // Remains 0 when executing Dart 1.0 code.
   // TODO(regis): Check for strong mode too?
-  if (Isolate::Current()->reify_generic_functions()) {
+  if (FLAG_reify_generic_functions) {
     const TypeArguments& function_type_args =
         TypeArguments::Handle(zone, arguments->NativeTypeArgs());
     if (function_type_args.Length() == 1) {
diff --git a/runtime/lib/object_patch.dart b/runtime/lib/object_patch.dart
index c63d3e4..77f359a 100644
--- a/runtime/lib/object_patch.dart
+++ b/runtime/lib/object_patch.dart
@@ -4,6 +4,7 @@
 
 // part of "core_patch.dart";
 
+@pragma("vm:exact-result-type", "dart:core#_Smi")
 int _getHash(obj) native "Object_getHash";
 void _setHash(obj, hash) native "Object_setHash";
 
@@ -12,6 +13,7 @@
 class Object {
   // The VM has its own implementation of equals.
   @patch
+  @pragma("vm:exact-result-type", bool)
   bool operator ==(other) native "Object_equals";
 
   // Helpers used to implement hashCode. If a hashCode is used, we remember it
@@ -49,9 +51,11 @@
   }
 
   @patch
+  @pragma("vm:exact-result-type", "dart:core#_Type")
   Type get runtimeType native "Object_runtimeType";
 
   @pragma("vm:entry-point")
+  @pragma("vm:exact-result-type", bool)
   static bool _haveSameRuntimeType(a, b) native "Object_haveSameRuntimeType";
 
   // Call this function instead of inlining instanceof, thus collecting
diff --git a/runtime/lib/string_patch.dart b/runtime/lib/string_patch.dart
index d7dfc1c..fe749e4 100644
--- a/runtime/lib/string_patch.dart
+++ b/runtime/lib/string_patch.dart
@@ -95,7 +95,10 @@
     throw new UnsupportedError("_StringBase can't be instaniated");
   }
 
+  @pragma("vm:exact-result-type", "dart:core#_Smi")
   int get hashCode native "String_getHashCode";
+
+  @pragma("vm:exact-result-type", "dart:core#_Smi")
   int get _identityHashCode native "String_getHashCode";
 
   bool get _isOneByte {
@@ -235,8 +238,10 @@
 
   int codeUnitAt(int index); // Implemented in the subclasses.
 
+  @pragma("vm:exact-result-type", "dart:core#_Smi")
   int get length native "String_getLength";
 
+  @pragma("vm:exact-result-type", bool)
   bool get isEmpty {
     return this.length == 0;
   }
@@ -249,6 +254,7 @@
     return this;
   }
 
+  @pragma("vm:exact-result-type", bool)
   bool operator ==(Object other) {
     if (identical(this, other)) {
       return true;
@@ -284,6 +290,7 @@
     return 0;
   }
 
+  @pragma("vm:exact-result-type", bool)
   bool _substringMatches(int start, String other) {
     if (other.isEmpty) return true;
     final len = other.length;
@@ -930,18 +937,22 @@
         "_OneByteString can only be allocated by the VM");
   }
 
+  @pragma("vm:exact-result-type", "dart:core#_Smi")
   int get hashCode native "String_getHashCode";
 
+  @pragma("vm:exact-result-type", "dart:core#_Smi")
   int codeUnitAt(int index) native "String_codeUnitAt";
 
   bool _isWhitespace(int codeUnit) {
     return _StringBase._isOneByteWhitespace(codeUnit);
   }
 
+  @pragma("vm:exact-result-type", bool)
   bool operator ==(Object other) {
     return super == other;
   }
 
+  @pragma("vm:exact-result-type", _OneByteString)
   String _substringUncheckedNative(int startIndex, int endIndex)
       native "OneByteString_substringUnchecked";
 
@@ -1200,6 +1211,7 @@
 
   // Allocates a string of given length, expecting its content to be
   // set using _setAt.
+  @pragma("vm:exact-result-type", _OneByteString)
   static _OneByteString _allocate(int length) native "OneByteString_allocate";
 
   static _OneByteString _allocateFromOneByteList(List<int> list, int start,
@@ -1241,8 +1253,10 @@
     return _StringBase._isTwoByteWhitespace(codeUnit);
   }
 
+  @pragma("vm:exact-result-type", "dart:core#_Smi")
   int codeUnitAt(int index) native "String_codeUnitAt";
 
+  @pragma("vm:exact-result-type", bool)
   bool operator ==(Object other) {
     return super == other;
   }
@@ -1259,6 +1273,7 @@
     return _StringBase._isOneByteWhitespace(codeUnit);
   }
 
+  @pragma("vm:exact-result-type", "dart:core#_Smi")
   int codeUnitAt(int index) native "String_codeUnitAt";
 
   bool operator ==(Object other) {
@@ -1277,6 +1292,7 @@
     return _StringBase._isTwoByteWhitespace(codeUnit);
   }
 
+  @pragma("vm:exact-result-type", "dart:core#_Smi")
   int codeUnitAt(int index) native "String_codeUnitAt";
 
   bool operator ==(Object other) {
diff --git a/runtime/lib/type_patch.dart b/runtime/lib/type_patch.dart
index 82aa34e..40eff3c 100644
--- a/runtime/lib/type_patch.dart
+++ b/runtime/lib/type_patch.dart
@@ -14,6 +14,7 @@
 // Equivalent of RawType.
 @pragma("vm:entry-point")
 class _Type extends _AbstractType {
+  @pragma("vm:exact-result-type", "dart:core#_Smi")
   int get hashCode native "Type_getHashCode";
 }
 
diff --git a/runtime/lib/typed_data_patch.dart b/runtime/lib/typed_data_patch.dart
index 4dbf16b..9c9393f 100644
--- a/runtime/lib/typed_data_patch.dart
+++ b/runtime/lib/typed_data_patch.dart
@@ -2045,19 +2045,24 @@
 
   // Methods implementing the collection interface.
 
+  @pragma("vm:exact-result-type", "dart:core#_Smi")
   int get length native "TypedData_length";
 
   // Internal utility methods.
 
+  @pragma("vm:exact-result-type", "dart:core#_Smi")
   int _getInt8(int offsetInBytes) native "TypedData_GetInt8";
   void _setInt8(int offsetInBytes, int value) native "TypedData_SetInt8";
 
+  @pragma("vm:exact-result-type", "dart:core#_Smi")
   int _getUint8(int offsetInBytes) native "TypedData_GetUint8";
   void _setUint8(int offsetInBytes, int value) native "TypedData_SetUint8";
 
+  @pragma("vm:exact-result-type", "dart:core#_Smi")
   int _getInt16(int offsetInBytes) native "TypedData_GetInt16";
   void _setInt16(int offsetInBytes, int value) native "TypedData_SetInt16";
 
+  @pragma("vm:exact-result-type", "dart:core#_Smi")
   int _getUint16(int offsetInBytes) native "TypedData_GetUint16";
   void _setUint16(int offsetInBytes, int value) native "TypedData_SetUint16";
 
@@ -2073,18 +2078,22 @@
   int _getUint64(int offsetInBytes) native "TypedData_GetUint64";
   void _setUint64(int offsetInBytes, int value) native "TypedData_SetUint64";
 
+  @pragma("vm:exact-result-type", "dart:core#_Double")
   double _getFloat32(int offsetInBytes) native "TypedData_GetFloat32";
   void _setFloat32(int offsetInBytes, double value)
       native "TypedData_SetFloat32";
 
+  @pragma("vm:exact-result-type", "dart:core#_Double")
   double _getFloat64(int offsetInBytes) native "TypedData_GetFloat64";
   void _setFloat64(int offsetInBytes, double value)
       native "TypedData_SetFloat64";
 
+  @pragma("vm:exact-result-type", _Float32x4)
   Float32x4 _getFloat32x4(int offsetInBytes) native "TypedData_GetFloat32x4";
   void _setFloat32x4(int offsetInBytes, Float32x4 value)
       native "TypedData_SetFloat32x4";
 
+  @pragma("vm:exact-result-type", _Int32x4)
   Int32x4 _getInt32x4(int offsetInBytes) native "TypedData_GetInt32x4";
   void _setInt32x4(int offsetInBytes, Int32x4 value)
       native "TypedData_SetInt32x4";
@@ -2114,6 +2123,7 @@
 @patch
 class Int8List {
   @patch
+  @pragma("vm:exact-result-type", _Int8List)
   factory Int8List(int length) native "TypedData_Int8Array_new";
 
   @patch
@@ -2126,6 +2136,7 @@
 @pragma("vm:entry-point")
 class _Int8List extends _TypedList with _IntListMixin implements Int8List {
   // Method(s) implementing List interface.
+  @pragma("vm:exact-result-type", "dart:core#_Smi")
   int operator [](int index) {
     if (index < 0 || index >= length) {
       throw new RangeError.index(index, this, "index");
@@ -2154,6 +2165,7 @@
 @patch
 class Uint8List {
   @patch
+  @pragma("vm:exact-result-type", _Uint8List)
   factory Uint8List(int length) native "TypedData_Uint8Array_new";
 
   @patch
@@ -2166,6 +2178,7 @@
 @pragma("vm:entry-point")
 class _Uint8List extends _TypedList with _IntListMixin implements Uint8List {
   // Methods implementing List interface.
+  @pragma("vm:exact-result-type", "dart:core#_Smi")
   int operator [](int index) {
     if (index < 0 || index >= length) {
       throw new RangeError.index(index, this, "index");
@@ -2194,6 +2207,7 @@
 @patch
 class Uint8ClampedList {
   @patch
+  @pragma("vm:exact-result-type", _Uint8ClampedList)
   factory Uint8ClampedList(int length) native "TypedData_Uint8ClampedArray_new";
 
   @patch
@@ -2208,6 +2222,7 @@
     with _IntListMixin
     implements Uint8ClampedList {
   // Methods implementing List interface.
+  @pragma("vm:exact-result-type", "dart:core#_Smi")
   int operator [](int index) {
     if (index < 0 || index >= length) {
       throw new RangeError.index(index, this, "index");
@@ -2236,6 +2251,7 @@
 @patch
 class Int16List {
   @patch
+  @pragma("vm:exact-result-type", _Int16List)
   factory Int16List(int length) native "TypedData_Int16Array_new";
 
   @patch
@@ -2248,6 +2264,7 @@
 @pragma("vm:entry-point")
 class _Int16List extends _TypedList with _IntListMixin implements Int16List {
   // Method(s) implementing List interface.
+  @pragma("vm:exact-result-type", "dart:core#_Smi")
   int operator [](int index) {
     if (index < 0 || index >= length) {
       throw new RangeError.index(index, this, "index");
@@ -2295,6 +2312,7 @@
 @patch
 class Uint16List {
   @patch
+  @pragma("vm:exact-result-type", _Uint16List)
   factory Uint16List(int length) native "TypedData_Uint16Array_new";
 
   @patch
@@ -2307,6 +2325,7 @@
 @pragma("vm:entry-point")
 class _Uint16List extends _TypedList with _IntListMixin implements Uint16List {
   // Method(s) implementing the List interface.
+  @pragma("vm:exact-result-type", "dart:core#_Smi")
   int operator [](int index) {
     if (index < 0 || index >= length) {
       throw new RangeError.index(index, this, "index");
@@ -2354,6 +2373,7 @@
 @patch
 class Int32List {
   @patch
+  @pragma("vm:exact-result-type", _Int32List)
   factory Int32List(int length) native "TypedData_Int32Array_new";
 
   @patch
@@ -2402,6 +2422,7 @@
 @patch
 class Uint32List {
   @patch
+  @pragma("vm:exact-result-type", _Uint32List)
   factory Uint32List(int length) native "TypedData_Uint32Array_new";
 
   @patch
@@ -2450,6 +2471,7 @@
 @patch
 class Int64List {
   @patch
+  @pragma("vm:exact-result-type", _Int64List)
   factory Int64List(int length) native "TypedData_Int64Array_new";
 
   @patch
@@ -2498,6 +2520,7 @@
 @patch
 class Uint64List {
   @patch
+  @pragma("vm:exact-result-type", _Uint64List)
   factory Uint64List(int length) native "TypedData_Uint64Array_new";
 
   @patch
@@ -2546,6 +2569,7 @@
 @patch
 class Float32List {
   @patch
+  @pragma("vm:exact-result-type", _Float32List)
   factory Float32List(int length) native "TypedData_Float32Array_new";
 
   @patch
@@ -2560,6 +2584,7 @@
     with _DoubleListMixin
     implements Float32List {
   // Method(s) implementing the List interface.
+  @pragma("vm:exact-result-type", "dart:core#_Double")
   double operator [](int index) {
     if (index < 0 || index >= length) {
       throw new RangeError.index(index, this, "index");
@@ -2596,6 +2621,7 @@
 @patch
 class Float64List {
   @patch
+  @pragma("vm:exact-result-type", _Float64List)
   factory Float64List(int length) native "TypedData_Float64Array_new";
 
   @patch
@@ -2610,6 +2636,7 @@
     with _DoubleListMixin
     implements Float64List {
   // Method(s) implementing the List interface.
+  @pragma("vm:exact-result-type", "dart:core#_Double")
   double operator [](int index) {
     if (index < 0 || index >= length) {
       throw new RangeError.index(index, this, "index");
@@ -2646,6 +2673,7 @@
 @patch
 class Float32x4List {
   @patch
+  @pragma("vm:exact-result-type", _Float32x4List)
   factory Float32x4List(int length) native "TypedData_Float32x4Array_new";
 
   @patch
@@ -2659,6 +2687,7 @@
 class _Float32x4List extends _TypedList
     with _Float32x4ListMixin
     implements Float32x4List {
+  @pragma("vm:exact-result-type", _Float32x4)
   Float32x4 operator [](int index) {
     if (index < 0 || index >= length) {
       throw new RangeError.index(index, this, "index");
@@ -2695,6 +2724,7 @@
 @patch
 class Int32x4List {
   @patch
+  @pragma("vm:exact-result-type", _Int32x4List)
   factory Int32x4List(int length) native "TypedData_Int32x4Array_new";
 
   @patch
@@ -2708,6 +2738,7 @@
 class _Int32x4List extends _TypedList
     with _Int32x4ListMixin
     implements Int32x4List {
+  @pragma("vm:exact-result-type", _Int32x4)
   Int32x4 operator [](int index) {
     if (index < 0 || index >= length) {
       throw new RangeError.index(index, this, "index");
@@ -2744,6 +2775,7 @@
 @patch
 class Float64x2List {
   @patch
+  @pragma("vm:exact-result-type", _Float64x2List)
   factory Float64x2List(int length) native "TypedData_Float64x2Array_new";
 
   @patch
@@ -2757,6 +2789,7 @@
 class _Float64x2List extends _TypedList
     with _Float64x2ListMixin
     implements Float64x2List {
+  @pragma("vm:exact-result-type", _Float64x2)
   Float64x2 operator [](int index) {
     if (index < 0 || index >= length) {
       throw new RangeError.index(index, this, "index");
@@ -2825,6 +2858,7 @@
     with _IntListMixin
     implements Uint8List {
   // Method(s) implementing the List interface.
+  @pragma("vm:exact-result-type", "dart:core#_Smi")
   int operator [](int index) {
     if (index < 0 || index >= length) {
       throw new RangeError.index(index, this, "index");
@@ -3310,70 +3344,106 @@
 @patch
 class Float32x4 {
   @patch
+  @pragma("vm:exact-result-type", _Float32x4)
   factory Float32x4(double x, double y, double z, double w)
       native "Float32x4_fromDoubles";
 
   @patch
+  @pragma("vm:exact-result-type", _Float32x4)
   factory Float32x4.splat(double v) native "Float32x4_splat";
 
   @patch
+  @pragma("vm:exact-result-type", _Float32x4)
   factory Float32x4.zero() native "Float32x4_zero";
 
   @patch
+  @pragma("vm:exact-result-type", _Float32x4)
   factory Float32x4.fromInt32x4Bits(Int32x4 x)
       native "Float32x4_fromInt32x4Bits";
 
   @patch
+  @pragma("vm:exact-result-type", _Float32x4)
   factory Float32x4.fromFloat64x2(Float64x2 v) native "Float32x4_fromFloat64x2";
 }
 
 @pragma("vm:entry-point")
 class _Float32x4 implements Float32x4 {
+  @pragma("vm:exact-result-type", _Float32x4)
   Float32x4 operator +(Float32x4 other) native "Float32x4_add";
+  @pragma("vm:exact-result-type", _Float32x4)
   Float32x4 operator -() native "Float32x4_negate";
+  @pragma("vm:exact-result-type", _Float32x4)
   Float32x4 operator -(Float32x4 other) native "Float32x4_sub";
+  @pragma("vm:exact-result-type", _Float32x4)
   Float32x4 operator *(Float32x4 other) native "Float32x4_mul";
   Float32x4 operator /(Float32x4 other) native "Float32x4_div";
+  @pragma("vm:exact-result-type", _Int32x4)
   Int32x4 lessThan(Float32x4 other) native "Float32x4_cmplt";
+  @pragma("vm:exact-result-type", _Int32x4)
   Int32x4 lessThanOrEqual(Float32x4 other) native "Float32x4_cmplte";
+  @pragma("vm:exact-result-type", _Int32x4)
   Int32x4 greaterThan(Float32x4 other) native "Float32x4_cmpgt";
+  @pragma("vm:exact-result-type", _Int32x4)
   Int32x4 greaterThanOrEqual(Float32x4 other) native "Float32x4_cmpgte";
+  @pragma("vm:exact-result-type", _Int32x4)
   Int32x4 equal(Float32x4 other) native "Float32x4_cmpequal";
+  @pragma("vm:exact-result-type", _Int32x4)
   Int32x4 notEqual(Float32x4 other) native "Float32x4_cmpnequal";
+  @pragma("vm:exact-result-type", _Float32x4)
   Float32x4 scale(double s) native "Float32x4_scale";
+  @pragma("vm:exact-result-type", _Float32x4)
   Float32x4 abs() native "Float32x4_abs";
+  @pragma("vm:exact-result-type", _Float32x4)
   Float32x4 clamp(Float32x4 lowerLimit, Float32x4 upperLimit)
       native "Float32x4_clamp";
+  @pragma("vm:exact-result-type", "dart:core#_Double")
   double get x native "Float32x4_getX";
+  @pragma("vm:exact-result-type", "dart:core#_Double")
   double get y native "Float32x4_getY";
+  @pragma("vm:exact-result-type", "dart:core#_Double")
   double get z native "Float32x4_getZ";
+  @pragma("vm:exact-result-type", "dart:core#_Double")
   double get w native "Float32x4_getW";
   int get signMask native "Float32x4_getSignMask";
 
+  @pragma("vm:exact-result-type", _Float32x4)
   Float32x4 shuffle(int mask) native "Float32x4_shuffle";
+  @pragma("vm:exact-result-type", _Float32x4)
   Float32x4 shuffleMix(Float32x4 zw, int mask) native "Float32x4_shuffleMix";
 
+  @pragma("vm:exact-result-type", _Float32x4)
   Float32x4 withX(double x) native "Float32x4_setX";
+  @pragma("vm:exact-result-type", _Float32x4)
   Float32x4 withY(double y) native "Float32x4_setY";
+  @pragma("vm:exact-result-type", _Float32x4)
   Float32x4 withZ(double z) native "Float32x4_setZ";
+  @pragma("vm:exact-result-type", _Float32x4)
   Float32x4 withW(double w) native "Float32x4_setW";
+  @pragma("vm:exact-result-type", _Float32x4)
   Float32x4 min(Float32x4 other) native "Float32x4_min";
+  @pragma("vm:exact-result-type", _Float32x4)
   Float32x4 max(Float32x4 other) native "Float32x4_max";
+  @pragma("vm:exact-result-type", _Float32x4)
   Float32x4 sqrt() native "Float32x4_sqrt";
+  @pragma("vm:exact-result-type", _Float32x4)
   Float32x4 reciprocal() native "Float32x4_reciprocal";
+  @pragma("vm:exact-result-type", _Float32x4)
   Float32x4 reciprocalSqrt() native "Float32x4_reciprocalSqrt";
 }
 
 @patch
 class Int32x4 {
   @patch
+  @pragma("vm:exact-result-type", _Int32x4)
   factory Int32x4(int x, int y, int z, int w) native "Int32x4_fromInts";
 
   @patch
+  @pragma("vm:exact-result-type", _Int32x4)
   factory Int32x4.bool(bool x, bool y, bool z, bool w)
       native "Int32x4_fromBools";
 
   @patch
+  @pragma("vm:exact-result-type", _Int32x4)
   factory Int32x4.fromFloat32x4Bits(Float32x4 x)
       native "Int32x4_fromFloat32x4Bits";
 }
@@ -3390,20 +3460,31 @@
   int get z native "Int32x4_getZ";
   int get w native "Int32x4_getW";
   int get signMask native "Int32x4_getSignMask";
+  @pragma("vm:exact-result-type", _Int32x4)
   Int32x4 shuffle(int mask) native "Int32x4_shuffle";
+  @pragma("vm:exact-result-type", _Int32x4)
   Int32x4 shuffleMix(Int32x4 zw, int mask) native "Int32x4_shuffleMix";
   Int32x4 withX(int x) native "Int32x4_setX";
   Int32x4 withY(int y) native "Int32x4_setY";
   Int32x4 withZ(int z) native "Int32x4_setZ";
   Int32x4 withW(int w) native "Int32x4_setW";
+  @pragma("vm:exact-result-type", bool)
   bool get flagX native "Int32x4_getFlagX";
+  @pragma("vm:exact-result-type", bool)
   bool get flagY native "Int32x4_getFlagY";
+  @pragma("vm:exact-result-type", bool)
   bool get flagZ native "Int32x4_getFlagZ";
+  @pragma("vm:exact-result-type", bool)
   bool get flagW native "Int32x4_getFlagW";
+  @pragma("vm:exact-result-type", _Int32x4)
   Int32x4 withFlagX(bool x) native "Int32x4_setFlagX";
+  @pragma("vm:exact-result-type", _Int32x4)
   Int32x4 withFlagY(bool y) native "Int32x4_setFlagY";
+  @pragma("vm:exact-result-type", _Int32x4)
   Int32x4 withFlagZ(bool z) native "Int32x4_setFlagZ";
+  @pragma("vm:exact-result-type", _Int32x4)
   Int32x4 withFlagW(bool w) native "Int32x4_setFlagW";
+  @pragma("vm:exact-result-type", _Float32x4)
   Float32x4 select(Float32x4 trueValue, Float32x4 falseValue)
       native "Int32x4_select";
 }
@@ -3411,36 +3492,50 @@
 @patch
 class Float64x2 {
   @patch
+  @pragma("vm:exact-result-type", _Float64x2)
   factory Float64x2(double x, double y) native "Float64x2_fromDoubles";
 
   @patch
+  @pragma("vm:exact-result-type", _Float64x2)
   factory Float64x2.splat(double v) native "Float64x2_splat";
 
   @patch
+  @pragma("vm:exact-result-type", _Float64x2)
   factory Float64x2.zero() native "Float64x2_zero";
 
   @patch
+  @pragma("vm:exact-result-type", _Float64x2)
   factory Float64x2.fromFloat32x4(Float32x4 v) native "Float64x2_fromFloat32x4";
 }
 
 @pragma("vm:entry-point")
 class _Float64x2 implements Float64x2 {
   Float64x2 operator +(Float64x2 other) native "Float64x2_add";
+  @pragma("vm:exact-result-type", _Float64x2)
   Float64x2 operator -() native "Float64x2_negate";
   Float64x2 operator -(Float64x2 other) native "Float64x2_sub";
   Float64x2 operator *(Float64x2 other) native "Float64x2_mul";
   Float64x2 operator /(Float64x2 other) native "Float64x2_div";
+  @pragma("vm:exact-result-type", _Float64x2)
   Float64x2 scale(double s) native "Float64x2_scale";
+  @pragma("vm:exact-result-type", _Float64x2)
   Float64x2 abs() native "Float64x2_abs";
   Float64x2 clamp(Float64x2 lowerLimit, Float64x2 upperLimit)
       native "Float64x2_clamp";
+  @pragma("vm:exact-result-type", "dart:core#_Double")
   double get x native "Float64x2_getX";
+  @pragma("vm:exact-result-type", "dart:core#_Double")
   double get y native "Float64x2_getY";
   int get signMask native "Float64x2_getSignMask";
+  @pragma("vm:exact-result-type", _Float64x2)
   Float64x2 withX(double x) native "Float64x2_setX";
+  @pragma("vm:exact-result-type", _Float64x2)
   Float64x2 withY(double y) native "Float64x2_setY";
+  @pragma("vm:exact-result-type", _Float64x2)
   Float64x2 min(Float64x2 other) native "Float64x2_min";
+  @pragma("vm:exact-result-type", _Float64x2)
   Float64x2 max(Float64x2 other) native "Float64x2_max";
+  @pragma("vm:exact-result-type", _Float64x2)
   Float64x2 sqrt() native "Float64x2_sqrt";
 }
 
@@ -4432,6 +4527,7 @@
   return value & 0xFF;
 }
 
+@pragma("vm:exact-result-type", "dart:core#_Smi")
 int _toClampedUint8(int value) {
   if (value < 0) return 0;
   if (value > 0xFF) return 0xFF;
diff --git a/runtime/observatory/tests/service/break_on_default_constructor_test.dart b/runtime/observatory/tests/service/break_on_default_constructor_test.dart
index 93901a8..ab5755c 100644
--- a/runtime/observatory/tests/service/break_on_default_constructor_test.dart
+++ b/runtime/observatory/tests/service/break_on_default_constructor_test.dart
@@ -3,6 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'dart:async';
+import 'dart:io';
 
 import 'package:observatory/debugger.dart';
 import 'package:observatory/service_io.dart';
@@ -67,7 +68,7 @@
     }
 
     isolate.resume();
-  },
+  }
 ];
 
 main(args) {
diff --git a/runtime/observatory/tests/service/get_vm_timeline_rpc_test.dart b/runtime/observatory/tests/service/get_vm_timeline_rpc_test.dart
index 40daf1e..2b7dffe 100644
--- a/runtime/observatory/tests/service/get_vm_timeline_rpc_test.dart
+++ b/runtime/observatory/tests/service/get_vm_timeline_rpc_test.dart
@@ -76,10 +76,6 @@
       // Skip meta-data events.
       continue;
     }
-    if (event['ph'] == 'C') {
-      // Skip counter events, where an isolate id makes Catapult hard to read.
-      continue;
-    }
     if (event['name'] == 'Runnable' && event['ph'] == 'i') {
       // Skip Runnable events which don't have an isolate.
       continue;
diff --git a/runtime/observatory/tests/service/service.status b/runtime/observatory/tests/service/service.status
index 7fbaf49..0370264 100644
--- a/runtime/observatory/tests/service/service.status
+++ b/runtime/observatory/tests/service/service.status
@@ -107,7 +107,7 @@
 *: SkipByDesign
 
 [ $compiler == dartk || $compiler == dartkp ]
-rewind_test: Pass, RuntimeError # Issue 34287
+rewind_test: Pass, RuntimeError, Slow # Issue 34287
 
 # Skip all service tests because random reloads interfere.
 [ $hot_reload || $hot_reload_rollback ]
diff --git a/runtime/observatory/tests/service/service_kernel.status b/runtime/observatory/tests/service/service_kernel.status
index e90e5a5..35be1d2 100644
--- a/runtime/observatory/tests/service/service_kernel.status
+++ b/runtime/observatory/tests/service/service_kernel.status
@@ -14,22 +14,15 @@
 async_star_single_step_into_test: RuntimeError
 async_star_step_out_test: RuntimeError
 async_step_out_test: RuntimeError
-awaiter_async_stack_contents_2_test: RuntimeError
-awaiter_async_stack_contents_test: RuntimeError
 bad_reload_test: RuntimeError
 break_on_activation_test: Skip # No incremental compiler available.
 break_on_function_test: RuntimeError
 breakpoint_in_parts_class_test: RuntimeError
 breakpoint_two_args_checked_test: RuntimeError
-causal_async_stack_contents_test: RuntimeError
-causal_async_stack_presence_test: RuntimeError
-causal_async_star_stack_contents_test: RuntimeError
-causal_async_star_stack_presence_test: RuntimeError
 code_test: RuntimeError # Issue 34143
 complex_reload_test: RuntimeError
 debugger_inspect_test: Skip # No incremental compiler available.
 debugger_location_second_test: RuntimeError
-debugger_location_test: RuntimeError
 debugging_inlined_finally_test: RuntimeError
 debugging_test: RuntimeError
 developer_service_get_isolate_id_test: Skip #  No incremental compiler available.
@@ -51,14 +44,12 @@
 get_retained_size_rpc_test: Skip # No incremental compiler available.
 get_retaining_path_rpc_test: Skip # No incremental compiler available.
 get_source_report_test: RuntimeError
-get_stack_rpc_test: RuntimeError
 get_user_level_retaining_path_rpc_test: Skip # No incremental compiler available.
 get_vm_rpc_test: RuntimeError
 get_vm_timeline_rpc_test: RuntimeError
 instance_field_order_rpc_test: Skip # No incremental compiler available.
 issue_25465_test: RuntimeError
 issue_27238_test: RuntimeError
-issue_27287_test: RuntimeError
 local_variable_declaration_test: RuntimeError
 mixin_break_test: RuntimeError
 next_through_assign_call_test: RuntimeError
@@ -83,16 +74,12 @@
 next_through_simple_async_with_returns_test: RuntimeError
 next_through_simple_linear_2_test: RuntimeError
 next_through_simple_linear_test: RuntimeError
-parameters_in_scope_at_entry_test: RuntimeError
 pause_on_exceptions_test: Skip # No incremental compiler available.
-pause_on_unhandled_async_exceptions2_test: RuntimeError
-pause_on_unhandled_async_exceptions_test: RuntimeError
 positive_token_pos_test: RuntimeError
 regress_28443_test: RuntimeError
 regress_28980_test: RuntimeError
 rewind_optimized_out_test: RuntimeError
 rewind_test: RuntimeError
-set_library_debuggable_test: RuntimeError
 set_name_rpc_test: RuntimeError
 set_vm_name_rpc_test: RuntimeError
 simple_reload_test: RuntimeError
@@ -121,6 +108,7 @@
 # These are the non-kernel specific versions so skip tests and allow errors.
 [ $compiler == dartk ]
 add_breakpoint_rpc_test: SkipByDesign # non-kernel specific version of add_breakpoint_rpc_kernel_test.
+bad_reload_test: RuntimeError # Issue 34025
 evaluate_activation_in_method_class_test: RuntimeError
 evaluate_activation_test/instance: RuntimeError # http://dartbug.com/20047
 evaluate_activation_test/scope: RuntimeError # http://dartbug.com/20047
@@ -146,6 +134,9 @@
 [ $arch == simdbc64 && $compiler == dartk && $mode == debug ]
 eval_test: Pass, Slow
 
+[ $arch == x64 && $compiler == dartk && $mode == release && $system == windows ]
+regexp_function_test: Pass, Crash # Issue http://dartbug.com/34422
+
 [ $compiler == app_jitk && $mode == debug ]
 code_test: RuntimeError
 step_test: RuntimeError
diff --git a/runtime/runtime_args.gni b/runtime/runtime_args.gni
index ba24461..3f5fbeb 100644
--- a/runtime/runtime_args.gni
+++ b/runtime/runtime_args.gni
@@ -78,9 +78,8 @@
     dart_component_kind = "static_library"
   }
 
-  # Whether the runtime should interpret called functions for which bytecode
-  # is provided by kernel, rather than compile them before execution.
-  dart_use_interpreter = false
+  # Whether the VM's platform dill file contains bytecode.
+  dart_platform_bytecode = false
 
   # Whether the VM includes the kernel service in all modes (debug, release,
   # product).
@@ -91,7 +90,7 @@
   # We create a kernel service app-jit snapshot only for when the target
   # architecture is x64 for other cases we will use the '.dill' file
   # which is already linked in the VM.
-  if (dart_target_arch == "x64" && !dart_use_interpreter) {
+  if (dart_target_arch == "x64" && !dart_platform_bytecode) {
     create_kernel_service_snapshot = true
   } else {
     create_kernel_service_snapshot = false
diff --git a/runtime/tests/vm/dart/catch_entry_state_test.dart b/runtime/tests/vm/dart/catch_entry_state_test.dart
new file mode 100644
index 0000000..ed33f17
--- /dev/null
+++ b/runtime/tests/vm/dart/catch_entry_state_test.dart
@@ -0,0 +1,53 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// VMOptions=--no-background-compilation --enable-inlining-annotations --optimization-counter-threshold=100
+
+// Verify that runtime correctly materializes unboxed variables on the catch
+// entry in optimized code.
+
+import 'dart:typed_data';
+
+import 'package:expect/expect.dart';
+
+const NeverInline = "NeverInline";
+
+@NeverInline
+void testThrow(bool shouldThrow) {
+  var dbl = 0.0;
+  var i32 = 0;
+  var i64 = 0;
+  var f32x4 = new Float32x4.zero();
+  var f64x2 = new Float64x2.zero();
+  var i32x4 = new Int32x4(0, 0, 0, 0);
+  try {
+    for (var i = 0; i < 100; i++) {
+      dbl += i;
+      i32 = i | 0x70000000;
+      i64 = i | 0x80000000;
+      final d = i.toDouble();
+      f32x4 += new Float32x4(d, -d, d, -d);
+      f64x2 += new Float64x2(d, -d);
+      i32x4 += new Int32x4(-i, i, -i, i);
+      if (shouldThrow && i == 50) {
+        throw "";
+      }
+    }
+  } catch (e) {}
+
+  if (shouldThrow) {
+    Expect.equals(1275.0, dbl);
+    Expect.equals(0x70000000 | 50, i32);
+    Expect.equals(0x80000000 | 50, i64);
+    Expect.listEquals([1275.0, -1275.0, 1275.0, -1275.0],
+        [f32x4.x, f32x4.y, f32x4.z, f32x4.w]);
+    Expect.listEquals([1275.0, -1275.0], [f64x2.x, f64x2.y]);
+    Expect.listEquals(
+        [-1275, 1275, -1275, 1275], [i32x4.x, i32x4.y, i32x4.z, i32x4.w]);
+  }
+}
+
+void main() {
+  for (var i = 0; i < 100; i++) testThrow(false);
+  testThrow(true);
+}
diff --git a/runtime/tests/vm/vm.status b/runtime/tests/vm/vm.status
index 960e7903..400420b 100644
--- a/runtime/tests/vm/vm.status
+++ b/runtime/tests/vm/vm.status
@@ -19,6 +19,7 @@
 cc/Profiler_InliningIntervalBoundry: Skip # Differences in ia32, debug, release
 cc/SNPrint_BadArgs: Crash, Fail # These tests are expected to crash on all platforms.
 dart/data_uri_import_test/none: SkipByDesign
+dart/entrypoints/*: Skip  # Only supported in Dart 2 JIT (hot-reload -> issue 34199).
 
 [ $builder_tag == asan ]
 cc/CodeImmutability: Fail, OK # Address Sanitizer turns a crash into a failure.
@@ -54,14 +55,14 @@
 dart/truncating_ints_test: SkipByDesign # The test requires int64.
 dart/wrap_around_in_range_analysis_test: SkipByDesign # The test requires int64.
 
-[ $compiler != dartk || ($arch != x64 && $arch != simarm && $arch != arm) || $hot_reload || $hot_reload_rollback ]
-dart/entrypoints/*: Skip  # Only supported in Dart 2 JIT (hot-reload -> issue 34199).
-
 [ ($compiler == dartk || $compiler == dartkb) ]
 cc/DartAPI_New: Fail # Issue #33041
 dart/redirection_type_shuffling_test/00: RuntimeError, Pass
 dart/redirection_type_shuffling_test/none: RuntimeError
 
+[ $runtime != vm && $runtime != dart_precompiled ]
+dart/catch_entry_state: SkipByDesign
+
 [ $compiler != dartk && $compiler != dartkb ]
 cc/IsolateReload_KernelIncrementalCompile: SkipByDesign
 cc/IsolateReload_KernelIncrementalCompileAppAndLib: SkipByDesign
@@ -111,26 +112,26 @@
 
 # Following tests are failing in a weird way on macos/ia32/debug builds
 # need to investigate.
-[ $arch == ia32 && $mode == debug && $runtime == vm && $system == macos ]
-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_IntrinsicAllocation: 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
+[ $runtime == vm && $system == macos ]
+cc/Profiler_ArrayAllocation: Skip # Issue 34493
+cc/Profiler_BasicSourcePosition: Skip # Issue 34493
+cc/Profiler_BasicSourcePositionOptimized: Skip # Issue 34493
+cc/Profiler_BinaryOperatorSourcePosition: Skip # Issue 34493
+cc/Profiler_BinaryOperatorSourcePositionOptimized: Skip # Issue 34493
+cc/Profiler_ChainedSamples: Skip # Issue 34493
+cc/Profiler_ClosureAllocation: Skip # Issue 34493
+cc/Profiler_CodeTicks: Skip # Issue 34493
+cc/Profiler_ContextAllocation: Skip # Issue 34493
+cc/Profiler_FunctionInline: Skip # Issue 34493
+cc/Profiler_FunctionTicks: Skip # Issue 34493
+cc/Profiler_IntrinsicAllocation: Skip # Issue 34493
+cc/Profiler_SourcePosition: Skip # Issue 34493
+cc/Profiler_SourcePositionOptimized: Skip # Issue 34493
+cc/Profiler_StringAllocation: Skip # Issue 34493
+cc/Profiler_StringInterpolation: Skip # Issue 34493
+cc/Profiler_ToggleRecordAllocation: Skip # Issue 34493
+cc/Profiler_TrivialRecordAllocation: Skip # Issue 34493
+cc/Profiler_TypedArrayAllocation: Skip # Issue 34493
 
 [ $arch != simarm && $arch != simarm64 && $arch != simdbc64 && ($compiler == dartk || $compiler == dartkb) && $hot_reload ]
 dart/data_uri_import_test/base64: Crash
@@ -363,3 +364,6 @@
 dart/spawn_infinite_loop_test: Skip # We can shutdown an isolate before it reloads.
 dart/spawn_shutdown_test: Skip # We can shutdown an isolate before it reloads.
 dart/stack_overflow_shared_test: SkipSlow # Too slow with --slow-path-triggers-gc flag and not relevant outside precompiled.
+
+[ $arch == simdbc64 && $mode == debug && $no_preview_dart_2 ]
+cc/CustomIsolates: Crash  # http://dartbug.com/34424
diff --git a/runtime/tools/dartfuzz/README.md b/runtime/tools/dartfuzz/README.md
index 6367411..9ee5e38 100644
--- a/runtime/tools/dartfuzz/README.md
+++ b/runtime/tools/dartfuzz/README.md
@@ -11,17 +11,18 @@
 How to run DartFuzz
 ===================
 
-    dartfuzz.py [--help] [--seed SEED]
+    dart dartfuzz.dart [--help] [--seed SEED] [FILENAME]
 
 where
 
     --help : prints help and exits
     --seed : defines random seed (system-set by default)
 
-DartFuzz sends all output to stdout, and provides
-a runnable main isolate. A typical test run looks as:
+If no FILENAME is given, DartFuzz sends all output to stdout.
+The tool provides a runnable main isolate. A typical single
+test run looks as:
 
-    dartfuzz.py > fuzz.dart
+    dart dartfuzz.dart fuzz.dart
     dart fuzz.dart
 
 How to start DartFuzz testing
diff --git a/runtime/tools/dartfuzz/dartfuzz.dart b/runtime/tools/dartfuzz/dartfuzz.dart
new file mode 100644
index 0000000..d32766f
--- /dev/null
+++ b/runtime/tools/dartfuzz/dartfuzz.dart
@@ -0,0 +1,917 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:io';
+import 'dart:math';
+
+import 'package:args/args.dart';
+
+// Version of DartFuzz. Increase this each time changes are made
+// to preserve the property that a given version of DartFuzz yields
+// the same fuzzed program for a deterministic random seed.
+const String version = '1.0';
+
+// Restriction on statement and expression depths.
+const int stmtDepth = 5;
+const int exprDepth = 2;
+
+// Interesting integer values.
+const List<int> interestingIntegers = [
+  0x0000000000000000,
+  0x0000000000000001,
+  0x000000007fffffff,
+  0x0000000080000000,
+  0x0000000080000001,
+  0x00000000ffffffff,
+  0x0000000100000000,
+  0x0000000100000001,
+  0x000000017fffffff,
+  0x0000000180000000,
+  0x0000000180000001,
+  0x00000001ffffffff,
+  0x7fffffff00000000,
+  0x7fffffff00000001,
+  0x7fffffff7fffffff,
+  0x7fffffff80000000,
+  0x7fffffff80000001,
+  0x7fffffffffffffff,
+  0x8000000000000000,
+  0x8000000000000001,
+  0x800000007fffffff,
+  0x8000000080000000,
+  0x8000000080000001,
+  0x80000000ffffffff,
+  0x8000000100000000,
+  0x8000000100000001,
+  0x800000017fffffff,
+  0x8000000180000000,
+  0x8000000180000001,
+  0x80000001ffffffff,
+  0xffffffff00000000,
+  0xffffffff00000001,
+  0xffffffff7fffffff,
+  0xffffffff80000000,
+  0xffffffff80000001,
+  0xffffffffffffffff
+];
+
+// Interesting characters.
+const interestingChars =
+    'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#&()+-';
+
+// Class that represents Dart types.
+class DartType {
+  final String name;
+
+  const DartType._withName(this.name);
+
+  static const VOID = const DartType._withName('void');
+  static const BOOL = const DartType._withName('bool');
+  static const INT = const DartType._withName('int');
+  static const DOUBLE = const DartType._withName('double');
+  static const STRING = const DartType._withName('String');
+  static const INT_LIST = const DartType._withName('List<int>');
+  static const INT_STRING_MAP = const DartType._withName('Map<int, String>');
+}
+
+// All value types.
+const allTypes = [
+  DartType.BOOL,
+  DartType.INT,
+  DartType.DOUBLE,
+  DartType.STRING,
+  DartType.INT_LIST,
+  DartType.INT_STRING_MAP
+];
+
+// Naming conventions.
+const varName = 'var';
+const paramName = 'par';
+const localName = 'loc';
+const fieldName = 'fld';
+const methodName = 'foo';
+
+// Class that generates a random, but runnable Dart program for fuzz testing.
+class DartFuzz {
+  DartFuzz(this.seed, this.sink);
+
+  void run() {
+    // Initialize program variables.
+    rand = new Random(seed);
+    indent = 0;
+    currentClass = null;
+    currentMethod = null;
+    // Setup the types.
+    localVars = new List<DartType>();
+    globalVars = fillTypes1();
+    globalVars.addAll(allTypes); // always one each
+    globalMethods = fillTypes2();
+    classFields = fillTypes2();
+    classMethods = fillTypes3(classFields.length);
+    // Generate.
+    emitHeader();
+    emitVarDecls(varName, globalVars);
+    emitMethods(methodName, globalMethods);
+    emitClasses();
+    emitMain();
+    // Sanity.
+    assert(currentClass == null);
+    assert(currentMethod == null);
+    assert(indent == 0);
+    assert(localVars.length == 0);
+  }
+
+  //
+  // Program components.
+  //
+
+  void emitHeader() {
+    emitLn('// The Dart Project Fuzz Tester ($version).');
+    emitLn('// Program generated as:');
+    emitLn('//   dart dartfuzz.dart --seed $seed');
+  }
+
+  void emitMethods(String name, List<List<DartType>> methods) {
+    for (int i = 0; i < methods.length; i++) {
+      List<DartType> method = methods[i];
+      currentMethod = i;
+      emitLn('${method[0].name} $name$i(', newline: false);
+      emitParDecls(method);
+      emit(') {', newline: true);
+      indent += 2;
+      assert(localVars.length == 0);
+      if (emitStatements(0)) {
+        emitReturn();
+      }
+      assert(localVars.length == 0);
+      indent -= 2;
+      emitLn('}');
+      emit('', newline: true);
+      currentMethod = null;
+    }
+  }
+
+  void emitClasses() {
+    assert(classFields.length == classMethods.length);
+    for (int i = 0; i < classFields.length; i++) {
+      currentClass = i;
+      emitLn('class X$i ${i == 0 ? "" : "extends X${i - 1}"} {');
+      indent += 2;
+      emitVarDecls('$fieldName${i}_', classFields[i]);
+      emitMethods('$methodName${i}_', classMethods[i]);
+      emitLn('void run() {');
+      indent += 2;
+      if (i > 0) {
+        emitLn('super.run();');
+      }
+      assert(localVars.length == 0);
+      emitStatements(0);
+      assert(localVars.length == 0);
+      indent -= 2;
+      emitLn('}');
+      indent -= 2;
+      emitLn('}');
+      emit('', newline: true);
+      currentClass = null;
+    }
+  }
+
+  void emitMain() {
+    emitLn('main() {');
+    indent += 2;
+    emitLn('try {');
+    indent += 2;
+    emitLn('new X${classFields.length - 1}().run();');
+    indent -= 2;
+    emitLn('} catch (e) {');
+    indent += 2;
+    emitLn("print('throws');");
+    indent -= 2;
+    emitLn('} finally {');
+    indent += 2;
+    emitLn("print('", newline: false);
+    for (int i = 0; i < globalVars.length; i++) {
+      emit('\$$varName$i\\n');
+    }
+    emit("');", newline: true);
+    indent -= 2;
+    emitLn('}');
+    indent -= 2;
+    emitLn('}');
+  }
+
+  //
+  // Declarations.
+  //
+
+  void emitVarDecls(String name, List<DartType> vars) {
+    emit('', newline: true);
+    for (int i = 0; i < vars.length; i++) {
+      DartType tp = vars[i];
+      emitLn('${tp.name} $name$i = ', newline: false);
+      emitLiteral(tp);
+      emit(';', newline: true);
+    }
+    emit('', newline: true);
+  }
+
+  void emitParDecls(List<DartType> pars) {
+    for (int i = 1; i < pars.length; i++) {
+      DartType tp = pars[i];
+      emit('${tp.name} $paramName$i');
+      if (i != (pars.length - 1)) {
+        emit(', ');
+      }
+    }
+  }
+
+  //
+  // Statements.
+  //
+
+  // Emit an assignment statement.
+  bool emitAssign() {
+    DartType tp = getType();
+    emitLn('', newline: false);
+    emitVar(tp);
+    emitAssignOp(tp);
+    emitExpr(0, tp);
+    emit(';', newline: true);
+    return true;
+  }
+
+  // Emit a print statement.
+  bool emitPrint() {
+    DartType tp = getType();
+    emitLn('print(', newline: false);
+    emitExpr(0, tp);
+    emit(');', newline: true);
+    return true;
+  }
+
+  // Emit a return statement.
+  bool emitReturn() {
+    List<DartType> proto = getCurrentProto();
+    if (proto == null) {
+      emitLn('return;');
+    } else {
+      emitLn('return ', newline: false);
+      emitExpr(0, proto[0]);
+      emit(';', newline: true);
+    }
+    return false;
+  }
+
+  // Emit a one-way if statement.
+  bool emitIf1(int depth) {
+    emitLn('if (', newline: false);
+    emitExpr(0, DartType.BOOL);
+    emit(') {', newline: true);
+    indent += 2;
+    bool b = emitStatements(depth + 1);
+    indent -= 2;
+    emitLn('}');
+    return b;
+  }
+
+  // Emit a two-way if statement.
+  bool emitIf2(int depth) {
+    emitLn('if (', newline: false);
+    emitExpr(0, DartType.BOOL);
+    emit(') {', newline: true);
+    indent += 2;
+    bool b1 = emitStatements(depth + 1);
+    indent -= 2;
+    emitLn('} else {');
+    indent += 2;
+    bool b2 = emitStatements(depth + 1);
+    indent -= 2;
+    emitLn('}');
+    return b1 || b2;
+  }
+
+  // Emit a simple increasing for-loop.
+  bool emitFor(int depth) {
+    int i = localVars.length;
+    emitLn('for (int $localName$i = 0; $localName$i < ', newline: false);
+    emitSmallPositiveInt();
+    emit('; $localName$i++) {', newline: true);
+    indent += 2;
+    localVars.add(DartType.INT);
+    bool b = emitStatements(depth + 1);
+    localVars.removeLast();
+    indent -= 2;
+    emitLn('}');
+    return b;
+  }
+
+  // Emit a new program scope that introduces a new local variable.
+  bool emitScope(int depth) {
+    DartType tp = getType();
+    emitLn('{ ${tp.name} $localName${localVars.length} = ', newline: false);
+    emitExpr(0, tp);
+    emit(';', newline: true);
+    indent += 2;
+    localVars.add(tp);
+    bool b = emitStatements(depth + 1);
+    localVars.removeLast();
+    indent -= 2;
+    emitLn('}');
+    return b;
+  }
+
+  // Emit a statement. Returns true if code may fall-through.
+  // TODO: add many more constructs
+  bool emitStatement(int depth) {
+    // Continuing nested statements becomes less likely as the depth grows.
+    if (rand.nextInt(depth + 1) > stmtDepth) {
+      return emitAssign();
+    }
+    // Possibly nested statement.
+    switch (rand.nextInt(8)) {
+      // favors assignment
+      case 0:
+        return emitIf1(depth);
+      case 1:
+        return emitIf2(depth);
+      case 2:
+        return emitFor(depth);
+      case 3:
+        return emitScope(depth);
+      case 4:
+        return emitPrint();
+      case 5:
+        return emitReturn();
+      default:
+        return emitAssign();
+    }
+  }
+
+  // Emit statements. Returns true if code may fall-through.
+  bool emitStatements(int depth) {
+    int s = 1 + rand.nextInt(4);
+    for (int i = 0; i < s; i++) {
+      if (!emitStatement(depth)) {
+        return false; // rest would be dead code
+      }
+    }
+    return true;
+  }
+
+  //
+  // Expressions.
+  //
+
+  void emitBool() {
+    emit(rand.nextInt(2) == 0 ? 'true' : 'false');
+  }
+
+  void emitSmallPositiveInt() {
+    emit('${rand.nextInt(100)}');
+  }
+
+  void emitSmallNegativeInt() {
+    emit('-${rand.nextInt(100)}');
+  }
+
+  void emitInterestingInt() {
+    int i = rand.nextInt(interestingIntegers.length);
+    emit('${interestingIntegers[i]}');
+  }
+
+  void emitInt() {
+    switch (rand.nextInt(4)) {
+      // favors small positive int
+      case 0:
+        emitInterestingInt();
+        break;
+      case 1:
+        emitSmallNegativeInt();
+        break;
+      default:
+        emitSmallPositiveInt();
+        break;
+    }
+  }
+
+  void emitDouble() {
+    switch (rand.nextInt(7)) {
+      // favors small double
+      case 0:
+        emit('double.infinity');
+        break;
+      case 1:
+        emit('double.maxFinite');
+        break;
+      case 2:
+        emit('double.minPositive');
+        break;
+      case 3:
+        emit('double.nan');
+        break;
+      case 4:
+        emit('double.negativeInfinity');
+        break;
+      default:
+        emit('${rand.nextDouble()}');
+        break;
+    }
+  }
+
+  void emitChar() {
+    emit(interestingChars[rand.nextInt(interestingChars.length)]);
+  }
+
+  void emitString() {
+    switch (rand.nextInt(4)) {
+      // favors non-null
+      case 0:
+        emit('null');
+        break;
+      default:
+        {
+          emit("'");
+          int l = rand.nextInt(8);
+          for (int i = 0; i < l; i++) {
+            emitChar();
+          }
+          emit("'");
+          break;
+        }
+    }
+  }
+
+  void emitIntList() {
+    switch (rand.nextInt(4)) {
+      // favors non-null
+      case 0:
+        emit('null');
+        break;
+      default:
+        {
+          emit('[ ');
+          int l = 1 + rand.nextInt(4);
+          for (int i = 0; i < l; i++) {
+            emitInt();
+            if (i != (l - 1)) {
+              emit(', ');
+            }
+          }
+          emit(' ]');
+          break;
+        }
+    }
+  }
+
+  void emitIntStringMap() {
+    switch (rand.nextInt(4)) {
+      // favors non-null
+      case 0:
+        emit('null');
+        break;
+      default:
+        {
+          emit('{ ');
+          int l = 1 + rand.nextInt(4);
+          for (int i = 0; i < l; i++) {
+            emit('$i : ');
+            emitString();
+            if (i != (l - 1)) {
+              emit(', ');
+            }
+          }
+          emit(' }');
+          break;
+        }
+    }
+  }
+
+  void emitLiteral(DartType tp) {
+    if (tp == DartType.BOOL) {
+      emitBool();
+    } else if (tp == DartType.INT) {
+      emitInt();
+    } else if (tp == DartType.DOUBLE) {
+      emitDouble();
+    } else if (tp == DartType.STRING) {
+      emitString();
+    } else if (tp == DartType.INT_LIST) {
+      emitIntList();
+    } else if (tp == DartType.INT_STRING_MAP) {
+      emitIntStringMap();
+    } else {
+      assert(false);
+    }
+  }
+
+  void emitScalarVar(DartType tp) {
+    // Collect all choices from globals, fields, locals, and parameters.
+    List<String> choices = new List<String>();
+    for (int i = 0; i < globalVars.length; i++) {
+      if (tp == globalVars[i]) choices.add('$varName$i');
+    }
+    for (int i = 0; i < localVars.length; i++) {
+      if (tp == localVars[i]) choices.add('$localName$i');
+    }
+    List<DartType> fields = getCurrentFields();
+    if (fields != null) {
+      for (int i = 0; i < fields.length; i++) {
+        if (tp == fields[i]) choices.add('$fieldName${currentClass}_$i');
+      }
+    }
+    List<DartType> proto = getCurrentProto();
+    if (proto != null) {
+      for (int i = 1; i < proto.length; i++) {
+        if (tp == proto[i]) choices.add('$paramName$i');
+      }
+    }
+    // Then pick one.
+    assert(choices.length > 0);
+    emit('${choices[rand.nextInt(choices.length)]}');
+  }
+
+  void emitVar(DartType tp) {
+    // TODO: add subscripted var
+    emitScalarVar(tp);
+  }
+
+  void emitTerminal(DartType tp) {
+    switch (rand.nextInt(2)) {
+      case 0:
+        emitLiteral(tp);
+        break;
+      default:
+        emitVar(tp);
+        break;
+    }
+  }
+
+  void emitExprList(int depth, List<DartType> proto) {
+    for (int i = 1; i < proto.length; i++) {
+      emitExpr(depth, proto[i]);
+      if (i != (proto.length - 1)) {
+        emit(', ');
+      }
+    }
+  }
+
+  bool pickedCall(
+      int depth, DartType tp, String name, List<List<DartType>> protos, int m) {
+    for (int i = m - 1; i >= 0; i--) {
+      if (tp == protos[i][0]) {
+        emit('$name$i(');
+        emitExprList(depth + 1, protos[i]);
+        emit(')');
+        return true;
+      }
+    }
+    return false;
+  }
+
+  void emitCall(int depth, DartType tp) {
+    // Only call backward to avoid infinite recursion.
+    if (currentClass == null) {
+      // Outside a class: call backward in global methods.
+      if (pickedCall(depth, tp, methodName, globalMethods, currentMethod)) {
+        return;
+      }
+    } else {
+      // Inside a class: try to call backwards in class methods first.
+      int m1 = currentMethod == null
+          ? classMethods[currentClass].length
+          : currentMethod;
+      int m2 = globalMethods.length;
+      if (pickedCall(depth, tp, '$methodName${currentClass}_',
+              classMethods[currentClass], m1) ||
+          pickedCall(depth, tp, methodName, globalMethods, m2)) {
+        return;
+      }
+    }
+    emitTerminal(tp); // resort to terminal.
+  }
+
+  // Emit expression with unary operator: (~(x))
+  void emitUnaryExpr(int depth, DartType tp) {
+    if (tp == DartType.BOOL || tp == DartType.INT || tp == DartType.DOUBLE) {
+      emit('(');
+      emitUnaryOp(tp);
+      emit('(');
+      emitExpr(depth + 1, tp);
+      emit('))');
+    } else {
+      emitTerminal(tp); // resort to terminal
+    }
+  }
+
+  // Emit expression with binary operator: (x + y)
+  void emitBinaryExpr(int depth, DartType tp) {
+    if (tp == DartType.BOOL || tp == DartType.INT || tp == DartType.DOUBLE) {
+      emit('(');
+      emitExpr(depth + 1, tp);
+      emitBinaryOp(tp);
+      emitExpr(depth + 1, tp);
+      emit(')');
+    } else {
+      emitTerminal(tp); // resort to terminal
+    }
+  }
+
+  // Emit expression with pre/post-increment/decrement operator: (x++)
+  void emitPreOrPostExpr(int depth, DartType tp) {
+    if (tp == DartType.INT) {
+      int r = rand.nextInt(2);
+      emit('(');
+      if (r == 0) emitPreOrPostOp(tp);
+      emitScalarVar(tp);
+      if (r == 1) emitPreOrPostOp(tp);
+      emit(')');
+    } else {
+      emitTerminal(tp); // resort to terminal
+    }
+  }
+
+  // Emit type converting expression.
+  void emitTypeConv(int depth, DartType tp) {
+    if (tp == DartType.BOOL) {
+      DartType deeper_tp = getType();
+      emit('(');
+      emitExpr(depth + 1, deeper_tp);
+      emitRelOp(deeper_tp);
+      emitExpr(depth + 1, deeper_tp);
+      emit(')');
+    } else if (tp == DartType.INT) {
+      emit('(');
+      emitExpr(depth + 1, DartType.DOUBLE);
+      emit(').toInt()');
+    } else if (tp == DartType.DOUBLE) {
+      emit('(');
+      emitExpr(depth + 1, DartType.INT);
+      emit(').toDouble()');
+    } else {
+      emitTerminal(tp); // resort to terminal
+    }
+  }
+
+  // Emit expression.
+  // TODO: add many more constructs
+  void emitExpr(int depth, DartType tp) {
+    // Continuing nested expressions becomes less likely as the depth grows.
+    if (rand.nextInt(depth + 1) > exprDepth) {
+      emitTerminal(tp);
+      return;
+    }
+    // Possibly nested expression.
+    switch (rand.nextInt(6)) {
+      case 0:
+        emitUnaryExpr(depth, tp);
+        break;
+      case 1:
+        emitBinaryExpr(depth, tp);
+        break;
+      case 2:
+        emitPreOrPostExpr(depth, tp);
+        break;
+      case 3:
+        emitTypeConv(depth, tp);
+        break;
+      case 4:
+        emitCall(depth, tp);
+        break;
+      default:
+        emitTerminal(tp);
+        break;
+    }
+  }
+
+  //
+  // Operators.
+  //
+
+  // Emit one of the given choices.
+  T oneOf<T>(List<T> choices) {
+    return choices[rand.nextInt(choices.length)];
+  }
+
+  // Emit same type in-out assignment operator.
+  void emitAssignOp(DartType tp) {
+    if (tp == DartType.INT) {
+      emit(oneOf(const <String>[
+        ' += ',
+        ' -= ',
+        ' *= ',
+        ' ~/= ',
+        ' %= ',
+        ' &= ',
+        ' |= ',
+        ' ^= ',
+        ' >>= ',
+        ' <<= ',
+        ' = '
+      ]));
+    } else if (tp == DartType.DOUBLE) {
+      emit(oneOf(const <String>[' += ', ' -= ', ' *= ', ' /= ', ' = ']));
+    } else {
+      emit(' = ');
+    }
+  }
+
+  // Emit same type in-out unary operator.
+  void emitUnaryOp(DartType tp) {
+    if (tp == DartType.BOOL) {
+      emit('!');
+    } else if (tp == DartType.INT) {
+      emit(oneOf(const <String>['-', '~']));
+    } else if (tp == DartType.DOUBLE) {
+      emit('-');
+    } else {
+      assert(false);
+    }
+  }
+
+  // Emit same type in-out binary operator.
+  void emitBinaryOp(DartType tp) {
+    if (tp == DartType.BOOL) {
+      emit(oneOf(const <String>[' && ', ' || ']));
+    } else if (tp == DartType.INT) {
+      emit(oneOf(const <String>[
+        ' + ',
+        ' - ',
+        ' * ',
+        ' ~/ ',
+        ' % ',
+        ' & ',
+        ' | ',
+        ' ^ ',
+        ' >> ',
+        ' << '
+      ]));
+    } else if (tp == DartType.DOUBLE) {
+      emit(oneOf(const <String>[' + ', ' - ', ' * ', ' / ']));
+    } else {
+      assert(false);
+    }
+  }
+
+  // Emit increment operator.
+  void emitPreOrPostOp(DartType tp) {
+    if (tp == DartType.INT) {
+      emit(oneOf(const <String>['++', '--']));
+    } else {
+      assert(false);
+    }
+  }
+
+  // Emit one type in, boolean out operator.
+  void emitRelOp(DartType tp) {
+    if (tp == DartType.INT || tp == DartType.DOUBLE) {
+      emit(oneOf(const <String>[' > ', ' >= ', ' < ', ' <= ', ' != ', ' == ']));
+    } else {
+      emit(oneOf(const <String>[' != ', ' == ']));
+    }
+  }
+
+  //
+  // Types.
+  //
+
+  DartType getType() {
+    switch (rand.nextInt(6)) {
+      case 0:
+        return DartType.BOOL;
+      case 1:
+        return DartType.INT;
+      case 2:
+        return DartType.DOUBLE;
+      case 3:
+        return DartType.STRING;
+      case 4:
+        return DartType.INT_LIST;
+      case 5:
+        return DartType.INT_STRING_MAP;
+    }
+  }
+
+  List<DartType> fillTypes1() {
+    List<DartType> list = new List<DartType>();
+    int n = 1 + rand.nextInt(4);
+    for (int i = 0; i < n; i++) {
+      list.add(getType());
+    }
+    return list;
+  }
+
+  List<List<DartType>> fillTypes2() {
+    List<List<DartType>> list = new List<List<DartType>>();
+    int n = 1 + rand.nextInt(4);
+    for (int i = 0; i < n; i++) {
+      list.add(fillTypes1());
+    }
+    return list;
+  }
+
+  List<List<List<DartType>>> fillTypes3(int n) {
+    List<List<List<DartType>>> list = new List<List<List<DartType>>>();
+    for (int i = 0; i < n; i++) {
+      list.add(fillTypes2());
+    }
+    return list;
+  }
+
+  List<DartType> getCurrentProto() {
+    if (currentClass != null) {
+      if (currentMethod != null) {
+        return classMethods[currentClass][currentMethod];
+      }
+    } else if (currentMethod != null) {
+      return globalMethods[currentMethod];
+    }
+    return null;
+  }
+
+  List<DartType> getCurrentFields() {
+    if (currentClass != null) {
+      return classFields[currentClass];
+    }
+    return null;
+  }
+
+  //
+  // Output.
+  //
+
+  // Emits indented line to append to program.
+  void emitLn(String line, {bool newline = true}) {
+    sink.write(' ' * indent);
+    emit(line, newline: newline);
+  }
+
+  // Emits text to append to program.
+  void emit(String txt, {bool newline = false}) {
+    sink.write(txt);
+    if (newline) {
+      sink.write('\n');
+    }
+  }
+
+  // Random seed used to generate program.
+  final int seed;
+
+  // Sink used for output.
+  final IOSink sink;
+
+  // Program variables.
+  Random rand;
+  int indent;
+  int currentClass;
+  int currentMethod;
+
+  // Types of local variables currently in scope.
+  List<DartType> localVars;
+
+  // Types of global variables.
+  List<DartType> globalVars;
+
+  // Prototypes of all global functions (first element is return type).
+  List<List<DartType>> globalMethods;
+
+  // Types of fields over all classes.
+  List<List<DartType>> classFields;
+
+  // Prototypes of all methods over all classes (first element is return type).
+  List<List<List<DartType>>> classMethods;
+}
+
+// Generate seed. By default (no user-defined nonzero seed given),
+// pick the system's best way of seeding randomness and then pick
+// a user-visible nonzero seed.
+int getSeed(String userSeed) {
+  int seed = int.parse(userSeed);
+  if (seed == 0) {
+    Random rand = new Random();
+    while (seed == 0) {
+      seed = rand.nextInt(1 << 32);
+    }
+  }
+  return seed;
+}
+
+// Main driver when dartfuzz.dart is run stand-alone.
+main(List<String> arguments) {
+  final parser = new ArgParser()
+    ..addOption('seed',
+        abbr: 's',
+        help: 'random seed (0 forces time-based seed)',
+        defaultsTo: '0');
+  try {
+    final results = parser.parse(arguments);
+    final seed = getSeed(results['seed']);
+    final sink = results.rest.isEmpty
+        ? stdout
+        : new File(results.rest.single).openWrite();
+    new DartFuzz(seed, sink).run();
+  } catch (e) {
+    print('Usage: dart dartfuzz.dart [OPTIONS] [FILENAME]');
+    print(parser.usage);
+  }
+}
diff --git a/runtime/tools/dartfuzz/dartfuzz.py b/runtime/tools/dartfuzz/dartfuzz.py
deleted file mode 100755
index fb96a11..0000000
--- a/runtime/tools/dartfuzz/dartfuzz.py
+++ /dev/null
@@ -1,411 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
-# for 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 argparse
-import random
-import time
-
-from enum import IntEnum
-from enum import unique
-
-# Version of DartFuzz. Increase this each time changes are made
-# to preserve the property that a given version of DartFuzz yields
-# the same fuzzed program for a deterministic random seed.
-
-VERSION='1.0'
-
-#
-# Dart operators and types.
-#
-
-NUM_UNARY_OPS  = [ '-' ]
-INT_UNARY_OPS  = NUM_UNARY_OPS + [ '~' ]
-
-BOOL_BIN_OPS   = [ ' && ', ' || ' ]
-NUM_BIN_OPS    = [ ' + ', ' - ', ' * ' ]
-INT_BIN_OPS    = NUM_BIN_OPS + [ ' & ', ' | ', ' ^ ', ' % ', ' ~/ ', ' >> ', ' << ' ]
-FP_BIN_OPS     = NUM_BIN_OPS + [ ' / ' ]
-
-NUM_ASSIGN_OPS = [ ' = ', ' += ', ' -= ', ' *= ' ]
-INT_ASSIGN_OPS = NUM_ASSIGN_OPS + [ ' &= ', ' |= ', ' ^= ', ' %= ', ' ~/= ', ' >>= ', ' <<= ' ]
-FP_ASSIGN_OPS  = NUM_ASSIGN_OPS + [ ' /= ' ]
-
-NUM_INC_OPS    = [ '++', '--' ]
-
-REL_OPS        = [ ' == ', ' != ' ]
-NUM_REL_OPS    = REL_OPS + [ ' > ', ' >= ', ' < ', ' <= ' ]
-
-@unique
-class Type(IntEnum):
-  """Enum representing Dart types."""
-  BOOL = 0,
-  INT = 1,
-  DOUBLE = 2,
-  STRING = 3,
-  INT_LIST = 4,
-  INT_STRING_MAP = 5
-
-Types = {
-  Type.BOOL           : 'bool',
-  Type.INT            : 'int',
-  Type.DOUBLE         : 'double',
-  Type.STRING         : 'String',
-  Type.INT_LIST       : 'List<int>',
-  Type.INT_STRING_MAP : 'Map<int, String>'
-}
-
-TypeList = list(Types.keys())
-
-#
-# DartFuzz generator class.
-#
-
-class DartFuzz(object):
-  """Generates a random, but runnable Dart program for fuzz testing."""
-
-  def  __init__(self, seed):
-    """Constructor.
-
-    Args:
-      seed: int, random seed from which randomness is obtained.
-    """
-    self._seed = seed
-
-  def Run(self):
-    # Setup
-    self._rand = random.Random()
-    self._rand.seed(self._seed)
-    self._indent = 0
-    self._num_classes = self._rand.randint(1, 4)
-    # Header.
-    self.EmitHeader()
-    # Top level.
-    for v in range(0, len(TypeList)):
-      self.EmitTopVarDecl(v)
-    self.EmitTopLevelMethod()
-    # Classes.
-    for c in range(0, self._num_classes):
-      self.EmitClass(c)
-    # Main.
-    self.EmitMain()
-
-  #
-  # Program components.
-  #
-
-  def EmitHeader(self):
-    self.EmitLn('')
-    self.EmitLn('// The Dart Project Fuzz Tester (' + VERSION + ').')
-    self.EmitLn('// Program generated as:')
-    self.EmitLn('//   dartfuzz.py --seed ' + str(self._seed))
-    self.EmitLn('')
-
-  def EmitTopLevelMethod(self):
-    self.EmitLn('')
-    self.EmitLn('void top() {')
-    self._indent += 2
-    self.EmitStmtList(0)
-    self._indent -= 2
-    self.EmitLn('}')
-
-  def EmitTopVarDecl(self, v):
-    tp = v  # int as type
-    self.EmitType(tp)
-    self.Emit(' var' + str(v) + ' = ')
-    self.EmitLiteral(tp)
-    self.Emit(';', end='\n')
-
-  def EmitClass(self, class_id):
-    self.EmitLn('')
-    self.EmitLn('class X' + str(class_id), end='')
-    if class_id > 0:
-      self.Emit(' extends X' + str(class_id - 1))
-    self.Emit(' {', end='\n')
-    self._indent += 2
-    self.EmitFieldDecls()
-    self.EmitMethod(class_id)
-    self._indent -= 2
-    self.EmitLn('}')
-
-  def EmitFieldDecls(self):
-    pass
-
-  def EmitMethod(self, class_id):
-    self.EmitLn('void run() {')
-    self._indent += 2
-    if class_id > 0:
-      self.EmitLn('super.run();')
-    else:
-      self.EmitLn('top();')
-    self.EmitStmtList(0)
-    self._indent -= 2
-    self.EmitLn('}')
-
-  def EmitMain(self):
-    self.EmitLn('')
-    self.EmitLn('main() {')
-    self._indent += 2
-    self.EmitLn('try {')
-    self._indent += 2
-    self.EmitLn('new X' + str(self._num_classes - 1) + '().run();')
-    self._indent -= 2
-    self.EmitLn('} catch (e) {')
-    self._indent += 2
-    self.EmitLn('print("exception");')
-    self._indent -= 2
-    self.EmitLn('} finally {')
-    self._indent += 2
-    for v in range(0, len(TypeList)):
-      self.EmitLn("print(var" + str(v) + ");");
-    self.EmitLn('print("done");')
-    self._indent -= 2
-    self.EmitLn('}')
-    self._indent -= 2
-    self.EmitLn('}')
-
-  #
-  # Statements.
-  #
-
-  def EmitStmtList(self, depth):
-    num_stmts = self._rand.randint(1, 4)
-    for s in range(0, num_stmts):
-      if not self.EmitStmt(depth):
-        return False  # rest would be dead code
-    return True
-
-  def EmitStmt(self, depth):
-    self.EmitLn('', end='')
-    r = self._rand.randint(1, 8)  # favors assignment
-    if r == 1 and depth <= 2:
-      return self.EmitIf(depth)
-    elif r == 2:
-      return self.EmitPrint(depth)
-    else:
-      return self.EmitAssign(depth)
-
-  def EmitIf(self, depth):
-    self.Emit('if (')
-    self.EmitExpr(Type.BOOL, 0)
-    self.Emit(') {', end='\n')
-    self._indent += 2
-    self.EmitStmtList(depth + 1)
-    self._indent -= 2
-    self.EmitLn('} else {')
-    self._indent += 2
-    self.EmitStmtList(depth + 1)
-    self._indent -= 2
-    self.EmitLn('}')
-    return True
-
-  def EmitPrint(self, depth):
-    self.Emit('print(')
-    tp = self.RandomType()
-    self.EmitExpr(tp, 0)
-    self.Emit(');', end='\n')
-    return True
-
-  def EmitAssign(self, depth):
-    tp = self.RandomType()
-    self.EmitVar(tp)
-    self.EmitAssignOp(tp)
-    self.EmitExpr(tp, 0)
-    self.Emit(';', end='\n')
-    return True
-
-  #
-  # Expressions.
-  #
-
-  def RandLen(self, x):
-    return self._rand.randint(0, len(x) - 1)
-
-  def EmitAssignOp(self, tp):
-    if tp == Type.INT:
-      self.Emit(INT_ASSIGN_OPS[self.RandLen(INT_ASSIGN_OPS)])
-    elif tp == Type.DOUBLE:
-      self.Emit(FP_ASSIGN_OPS[self.RandLen(FP_ASSIGN_OPS)])
-    else:
-      self.Emit(' = ')
-
-  def EmitUnaryOp(self, tp):
-    """Emit same type in-out binary operator."""
-    if tp == Type.INT:
-      self.Emit(INT_UNARY_OPS[self.RandLen(INT_UNARY_OPS)])
-    elif tp == Type.DOUBLE:
-      self.Emit(NUM_UNARY_OPS[self.RandLen(NUM_UNARY_OPS)])
-    else:
-      self.Emit(' !')
-
-  def EmitBinOp(self, tp):
-    """Emit same type in-out binary operator."""
-    if tp == Type.BOOL:
-      self.Emit(BOOL_BIN_OPS[self.RandLen(BOOL_BIN_OPS)])
-    elif tp == Type.INT:
-      self.Emit(INT_BIN_OPS[self.RandLen(INT_BIN_OPS)])
-    elif tp == Type.DOUBLE:
-      self.Emit(FP_BIN_OPS[self.RandLen(FP_BIN_OPS)])
-    else:
-      self.Emit(' + ')
-
-  def EmitRelOp(self, tp):
-    """Emit one type in, boolean out operator."""
-    if tp == Type.INT or tp == Type.DOUBLE:
-      self.Emit(NUM_REL_OPS[self.RandLen(NUM_REL_OPS)])
-    else:
-      self.Emit(REL_OPS[self.RandLen(REL_OPS)])
-
-  def EmitExpr(self, tp, depth):
-    if (depth > 2):
-      self.EmitTerm(tp)
-      return
-    r = self._rand.randint(1, 5)
-    if r == 1 and tp <= Type.DOUBLE:
-      # Unary operator: (~(x))
-      self.Emit('(')
-      self.EmitUnaryOp(tp)
-      self.Emit('(')
-      self.EmitExpr(tp, depth + 1)
-      self.Emit('))')
-    elif r == 2 and tp <= Type.STRING:
-      # Binary operator: (x + y)
-      self.Emit('(')
-      self.EmitExpr(tp, depth + 1)
-      self.EmitBinOp(tp)
-      self.EmitExpr(tp, depth + 1)
-      self.Emit(')')
-    elif r == 3 and Type.INT <= tp and tp <= Type.DOUBLE:
-      # Pre- or post-increment/decrement: (++x) or (x++)
-      self.Emit('(')
-      pre = self._rand.randint(1, 1)
-      if pre == 1:
-        self.Emit(NUM_INC_OPS[self.RandLen(NUM_INC_OPS)])
-      self.EmitVar(tp);
-      if pre == 2:
-        self.Emit(NUM_INC_OPS[self.RandLen(NUM_INC_OPS)])
-      self.Emit(')')
-    elif r == 4:
-      # Type conversion: x.toInt()
-      self.EmitTypeConv(tp, depth)
-    else:
-      # Terminal expression: x or 1
-      self.EmitTerm(tp)
-
-  def EmitTypeConv(self, tp, depth):
-    if tp == Type.BOOL:
-      new_tp = self.RandomType()
-      self.Emit('(')
-      self.EmitExpr(new_tp, depth + 1)
-      self.EmitRelOp(new_tp)
-      self.EmitExpr(new_tp, depth + 1)
-      self.Emit(')')
-    elif tp == Type.INT:
-      self.Emit('(')
-      self.EmitExpr(Type.DOUBLE, depth + 1)
-      self.Emit(').toInt()')
-    elif tp == Type.DOUBLE:
-      self.Emit('(')
-      self.EmitExpr(Type.INT, depth + 1)
-      self.Emit(').toDouble()')
-    else:
-      self.EmitTerm(tp)
-
-  def EmitTerm(self, tp):
-    r = self._rand.randint(1, 2)
-    if r == 1:
-      self.EmitVar(tp)
-    else:
-      self.EmitLiteral(tp)
-
-  def EmitVar(self, tp):
-    v = int(tp)  # type as int
-    self.Emit('var' + str(v))
-
-  def EmitLiteral(self, tp):
-    if tp == Type.BOOL:
-      self.Emit('true' if self._rand.randint(0, 1) == 0 else 'false')
-    elif tp == Type.INT:
-      self.Emit(str(self._rand.randint(-1000, 1000)))
-    elif tp == Type.DOUBLE:
-      self.Emit(str(self._rand.uniform(-1000.0, +1000.0)))
-    elif tp == Type.STRING:
-      len = self._rand.randint(1, 5)
-      self.Emit('"' + ''.join(self._rand.choice('AaBbCcDdEeFfGgHh')
-                              for _ in range(len)) + '"')
-    elif tp == Type.INT_LIST:
-      len = self._rand.randint(1, 5)
-      self.Emit('[')
-      self.EmitLiteral(Type.INT)
-      for i in range(1, len):
-        self.Emit(', ')
-        self.EmitLiteral(Type.INT)
-      self.Emit(']')
-    elif tp == Type.INT_STRING_MAP:
-      len = self._rand.randint(1, 5)
-      self.Emit('{ 0 : ')
-      self.EmitLiteral(Type.STRING)
-      for i in range(1, len):
-        self.Emit(', ' + str(i) + ' : ')
-        self.EmitLiteral(Type.STRING)
-      self.Emit('}')
-
-  #
-  # Types.
-  #
-
-  def RandomType(self):
-    return TypeList[self._rand.randint(0, len(TypeList) - 1)]
-
-  def EmitType(self, tp):
-    self.Emit(Types[tp])
-
-  #
-  # Output.
-  #
-
-  def EmitLn(self, line, end='\n'):
-    """Emits indented line to append to program (stdout).
-
-    Args:
-      line: string, line to append to program.
-    """
-    print(self._indent * ' ', end='')
-    print(line, end=end)
-
-  def Emit(self, txt, end=''):
-    """Emits string to append to program (stdout).
-
-    Args:
-      txt: string, text to append to program.
-    """
-    print(txt, end=end)
-
-#
-# Main driver.
-#
-
-def main():
-  # Handle arguments.
-  parser = argparse.ArgumentParser()
-  parser.add_argument('--seed', default=0, type=int,
-                      help='random seed (0 forces time-based seed)')
-  args = parser.parse_args()
-
-  # By default (zero seed), select a random seed.
-  seed = args.seed
-  if seed == 0:
-    # Pick system's best way of seeding randomness.
-    # Then pick a user visible nonzero seed.
-    random.seed()
-    while seed == 0:
-      seed = random.getrandbits(64)
-
-  # Run DartFuzz.
-  fuzzer = DartFuzz(seed)
-  fuzzer.Run()
-
-if __name__ == '__main__':
-  main()
diff --git a/runtime/tools/dartfuzz/run_dartfuzz_test.py b/runtime/tools/dartfuzz/run_dartfuzz_test.py
index 38b5496..8d33b49 100755
--- a/runtime/tools/dartfuzz/run_dartfuzz_test.py
+++ b/runtime/tools/dartfuzz/run_dartfuzz_test.py
@@ -8,6 +8,7 @@
 import argparse
 import os
 import shutil
+import signal
 import subprocess
 import sys
 
@@ -269,6 +270,8 @@
     print('Exec-Mode 1 :', self._runner1.description)
     print('Exec-Mode 2 :', self._runner2.description)
     print('Dart Dev    :', os.environ.get('DART_TOP'))
+    print('Orig Dir    :', self._save_dir)
+    print('Temp Dir    :', self._tmp_dir)
     print()
     self.ShowStats()  # show all zeros on start
     for self._test in range(1, self._repeat + 1):
@@ -278,7 +281,7 @@
   def Setup(self):
     """Initial setup of the testing environment."""
     # Fuzzer command.
-    self._dartfuzz = self._save_dir + '/dartfuzz.py'
+    self._dartfuzz = self._save_dir + '/dartfuzz.dart'
     # Statistics.
     self._test = 0
     self._num_success = 0
@@ -311,7 +314,7 @@
       FatalError: error when DartFuzz fails.
     """
     # Invoke dartfuzz script on command line rather than calling py code.
-    if (RunCommand([self._dartfuzz], out='fuzz.dart') != RetCode.SUCCESS):
+    if (RunCommand(['dart', self._dartfuzz], out='fuzz.dart') != RetCode.SUCCESS):
       raise FatalError('Unexpected error while running DartFuzz')
 
   def CheckForDivergence(self, out1, retcode1, out2, retcode2):
diff --git a/runtime/vm/BUILD.gn b/runtime/vm/BUILD.gn
index b47ed54..ebb800a 100644
--- a/runtime/vm/BUILD.gn
+++ b/runtime/vm/BUILD.gn
@@ -328,13 +328,14 @@
     "$root_out_dir/vm_outline_strong.dill",
   ]
 
-  args = [ "--strong-mode" ]
+  args = [
+    "--strong-mode",
+    "dart:core",
+  ]
 
-  if (dart_use_interpreter) {
+  if (dart_platform_bytecode) {
     args += [ "--bytecode" ]
   }
-
-  args += [ "dart:core" ]
 }
 
 group("kernel_platform_files") {
diff --git a/runtime/vm/class_finalizer.cc b/runtime/vm/class_finalizer.cc
index a8e852a..c2cceac 100644
--- a/runtime/vm/class_finalizer.cc
+++ b/runtime/vm/class_finalizer.cc
@@ -449,8 +449,7 @@
     return;
   }
 
-  Isolate* isolate = Isolate::Current();
-  if (isolate->error_on_bad_override() && !isolate->strong()) {
+  if (!FLAG_strong && Isolate::Current()->error_on_bad_override()) {
     // Verify that the target is compatible with the redirecting factory.
     Error& error = Error::Handle();
     if (!target.HasCompatibleParametersWith(factory, &error)) {
@@ -564,7 +563,7 @@
          (type.signature() != Function::null()));
 
   // In non-strong mode, replace FutureOr<T> type of async library with dynamic.
-  if (type_class.IsFutureOrClass() && !Isolate::Current()->strong()) {
+  if (type_class.IsFutureOrClass() && !FLAG_strong) {
     Type::Cast(type).set_type_class(Class::Handle(Object::dynamic_class()));
     type.set_arguments(Object::null_type_arguments());
   }
@@ -1226,7 +1225,7 @@
     // malformed.
     if ((finalization >= kCanonicalize) && !type.IsMalformed() &&
         !type.IsCanonical() && type.IsType()) {
-      if (!Isolate::Current()->strong()) {
+      if (!FLAG_strong) {
         CheckTypeBounds(cls, type);
       }
       return type.Canonicalize();
@@ -1370,7 +1369,7 @@
 
   // If we are done finalizing a graph of mutually recursive types, check their
   // bounds.
-  if (is_root_type && !Isolate::Current()->strong()) {
+  if (is_root_type && !FLAG_strong) {
     for (intptr_t i = pending_types->length() - 1; i >= 0; i--) {
       const AbstractType& type = pending_types->At(i);
       if (!type.IsMalformed() && !type.IsCanonical()) {
@@ -1634,7 +1633,7 @@
   String& other_name = String::Handle(zone);
   Class& super_class = Class::Handle(zone);
   const intptr_t num_fields = array.Length();
-  const bool track_exactness = isolate->strong() && isolate->use_field_guards();
+  const bool track_exactness = FLAG_strong && isolate->use_field_guards();
   for (intptr_t i = 0; i < num_fields; i++) {
     field ^= array.At(i);
     type = field.type();
@@ -1743,7 +1742,7 @@
   // If we check for bad overrides, collect interfaces, super interfaces, and
   // super classes of this class.
   GrowableArray<const Class*> interfaces(zone, 4);
-  if (isolate->error_on_bad_override() && !isolate->strong()) {
+  if (isolate->error_on_bad_override() && !FLAG_strong) {
     CollectInterfaces(cls, &interfaces);
     // Include superclasses in list of interfaces and super interfaces.
     super_class = cls.SuperClass();
@@ -1765,7 +1764,7 @@
     FinalizeSignature(cls, function);
     name = function.name();
     // Report signature conflicts only.
-    if (isolate->error_on_bad_override() && !isolate->strong() &&
+    if (isolate->error_on_bad_override() && !FLAG_strong &&
         !function.is_static() && !function.IsGenerativeConstructor()) {
       // A constructor cannot override anything.
       for (intptr_t i = 0; i < interfaces.length(); i++) {
@@ -2748,10 +2747,13 @@
   }
 }
 
+volatile int ctr = 0;
+
 void ClassFinalizer::FinalizeClass(const Class& cls) {
   Thread* thread = Thread::Current();
   HANDLESCOPE(thread);
   ASSERT(cls.is_type_finalized());
+  if (strstr(cls.ToCString(), "AssertionError")) ++ctr;
   if (cls.is_finalized()) {
     return;
   }
@@ -2787,7 +2789,7 @@
   }
   // Ensure interfaces are finalized in case we check for bad overrides.
   Isolate* isolate = Isolate::Current();
-  if (isolate->error_on_bad_override() && !isolate->strong()) {
+  if (isolate->error_on_bad_override() && !FLAG_strong) {
     GrowableArray<const Class*> interfaces(4);
     CollectInterfaces(cls, &interfaces);
     for (intptr_t i = 0; i < interfaces.length(); i++) {
@@ -2801,6 +2803,7 @@
     ApplyMixinMembers(cls);
   }
   // Mark as parsed and finalized.
+  if (strstr(cls.ToCString(), "AssertionError")) ++ctr;
   cls.Finalize();
   // Mixin app alias classes may still lack their forwarding constructor.
   if (cls.is_mixin_app_alias() &&
diff --git a/runtime/vm/clustered_snapshot.cc b/runtime/vm/clustered_snapshot.cc
index f799a8d..84bc363 100644
--- a/runtime/vm/clustered_snapshot.cc
+++ b/runtime/vm/clustered_snapshot.cc
@@ -1666,7 +1666,7 @@
     s->Push(code->ptr()->exception_handlers_);
     s->Push(code->ptr()->pc_descriptors_);
 #if defined(DART_PRECOMPILED_RUNTIME) || defined(DART_PRECOMPILER)
-    s->Push(code->ptr()->catch_entry_.catch_entry_state_maps_);
+    s->Push(code->ptr()->catch_entry_.catch_entry_moves_maps_);
 #else
     s->Push(code->ptr()->catch_entry_.variables_);
 #endif
@@ -1727,7 +1727,7 @@
       s->WriteRef(code->ptr()->exception_handlers_);
       s->WriteRef(code->ptr()->pc_descriptors_);
 #if defined(DART_PRECOMPILED_RUNTIME) || defined(DART_PRECOMPILER)
-      s->WriteRef(code->ptr()->catch_entry_.catch_entry_state_maps_);
+      s->WriteRef(code->ptr()->catch_entry_.catch_entry_moves_maps_);
 #else
       s->WriteRef(code->ptr()->catch_entry_.variables_);
 #endif
@@ -1810,7 +1810,7 @@
       code->ptr()->pc_descriptors_ =
           reinterpret_cast<RawPcDescriptors*>(d->ReadRef());
 #if defined(DART_PRECOMPILED_RUNTIME) || defined(DART_PRECOMPILER)
-      code->ptr()->catch_entry_.catch_entry_state_maps_ =
+      code->ptr()->catch_entry_.catch_entry_moves_maps_ =
           reinterpret_cast<RawTypedData*>(d->ReadRef());
 #else
       code->ptr()->catch_entry_.variables_ =
diff --git a/runtime/vm/code_descriptors.cc b/runtime/vm/code_descriptors.cc
index da77114..84d9882 100644
--- a/runtime/vm/code_descriptors.cc
+++ b/runtime/vm/code_descriptors.cc
@@ -112,18 +112,19 @@
   return handlers.raw();
 }
 
-static uint8_t* zone_allocator(uint8_t* ptr,
-                               intptr_t old_size,
-                               intptr_t new_size) {
+static uint8_t* ZoneAllocator(uint8_t* ptr,
+                              intptr_t old_size,
+                              intptr_t new_size) {
   Zone* zone = Thread::Current()->zone();
   return zone->Realloc<uint8_t>(ptr, old_size, new_size);
 }
 
-class CatchEntryStateMapBuilder::TrieNode : public ZoneAllocated {
+#if !defined(DART_PRECOMPILED_RUNTIME)
+class CatchEntryMovesMapBuilder::TrieNode : public ZoneAllocated {
  public:
-  TrieNode() : pair_(), entry_state_offset_(-1) {}
-  TrieNode(CatchEntryStatePair pair, intptr_t index)
-      : pair_(pair), entry_state_offset_(index) {}
+  TrieNode() : move_(), entry_state_offset_(-1) {}
+  TrieNode(CatchEntryMove move, intptr_t index)
+      : move_(move), entry_state_offset_(index) {}
 
   intptr_t Offset() { return entry_state_offset_; }
 
@@ -132,42 +133,36 @@
     return node;
   }
 
-  TrieNode* Follow(CatchEntryStatePair next) {
+  TrieNode* Follow(CatchEntryMove next) {
     for (intptr_t i = 0; i < children_.length(); i++) {
-      if (children_[i]->pair_ == next) return children_[i];
+      if (children_[i]->move_ == next) return children_[i];
     }
     return NULL;
   }
 
  private:
-  CatchEntryStatePair pair_;
+  CatchEntryMove move_;
   const intptr_t entry_state_offset_;
   GrowableArray<TrieNode*> children_;
 };
 
-CatchEntryStateMapBuilder::CatchEntryStateMapBuilder()
+CatchEntryMovesMapBuilder::CatchEntryMovesMapBuilder()
     : zone_(Thread::Current()->zone()),
       root_(new TrieNode()),
       current_pc_offset_(0),
       buffer_(NULL),
-      stream_(&buffer_, zone_allocator, 64) {}
+      stream_(&buffer_, ZoneAllocator, 64) {}
 
-void CatchEntryStateMapBuilder::AppendMove(intptr_t src_slot,
-                                           intptr_t dest_slot) {
-  moves_.Add(CatchEntryStatePair::FromMove(src_slot, dest_slot));
+void CatchEntryMovesMapBuilder::Append(const CatchEntryMove& move) {
+  moves_.Add(move);
 }
 
-void CatchEntryStateMapBuilder::AppendConstant(intptr_t pool_id,
-                                               intptr_t dest_slot) {
-  moves_.Add(CatchEntryStatePair::FromConstant(pool_id, dest_slot));
-}
-
-void CatchEntryStateMapBuilder::NewMapping(intptr_t pc_offset) {
+void CatchEntryMovesMapBuilder::NewMapping(intptr_t pc_offset) {
   moves_.Clear();
   current_pc_offset_ = pc_offset;
 }
 
-void CatchEntryStateMapBuilder::EndMapping() {
+void CatchEntryMovesMapBuilder::EndMapping() {
   intptr_t suffix_length = 0;
   TrieNode* suffix = root_;
   // Find the largest common suffix, get the last node of the path.
@@ -189,8 +184,7 @@
   // Write the unshared part, adding it to the trie.
   TrieNode* node = suffix;
   for (intptr_t i = length - 1; i >= 0; i--) {
-    Writer::Write(&stream_, moves_[i].src);
-    Writer::Write(&stream_, moves_[i].dest);
+    moves_[i].WriteTo(&stream_);
 
     TrieNode* child = new (zone_) TrieNode(moves_[i], current_offset);
     node->Insert(child);
@@ -198,7 +192,7 @@
   }
 }
 
-RawTypedData* CatchEntryStateMapBuilder::FinalizeCatchEntryStateMap() {
+RawTypedData* CatchEntryMovesMapBuilder::FinalizeCatchEntryMovesMap() {
   TypedData& td = TypedData::Handle(TypedData::New(
       kTypedDataInt8ArrayCid, stream_.bytes_written(), Heap::kOld));
   NoSafepointScope no_safepoint;
@@ -209,6 +203,7 @@
   }
   return td.raw();
 }
+#endif  // !defined(DART_PRECOMPILED_RUNTIME)
 
 const TokenPosition CodeSourceMapBuilder::kInitialPosition =
     TokenPosition(TokenPosition::kDartCodeProloguePos);
@@ -230,7 +225,7 @@
       inlined_functions_(
           GrowableObjectArray::Handle(GrowableObjectArray::New(Heap::kOld))),
       buffer_(NULL),
-      stream_(&buffer_, zone_allocator, 64),
+      stream_(&buffer_, ZoneAllocator, 64),
       stack_traces_only_(stack_traces_only) {
   buffered_inline_id_stack_.Add(0);
   buffered_token_pos_stack_.Add(kInitialPosition);
diff --git a/runtime/vm/code_descriptors.h b/runtime/vm/code_descriptors.h
index 6c0daab..dfec824 100644
--- a/runtime/vm/code_descriptors.h
+++ b/runtime/vm/code_descriptors.h
@@ -144,43 +144,16 @@
   DISALLOW_COPY_AND_ASSIGN(ExceptionHandlerList);
 };
 
-// An encoded move from stack/constant to stack performed
-struct CatchEntryStatePair {
-  enum { kCatchEntryStateIsMove = 1, kCatchEntryStateDestShift = 1 };
-
-  intptr_t src, dest;
-
-  static CatchEntryStatePair FromConstant(intptr_t pool_id,
-                                          intptr_t dest_slot) {
-    CatchEntryStatePair pair;
-    pair.src = pool_id;
-    pair.dest = (dest_slot << kCatchEntryStateDestShift);
-    return pair;
-  }
-
-  static CatchEntryStatePair FromMove(intptr_t src_slot, intptr_t dest_slot) {
-    CatchEntryStatePair pair;
-    pair.src = src_slot;
-    pair.dest =
-        (dest_slot << kCatchEntryStateDestShift) | kCatchEntryStateIsMove;
-    return pair;
-  }
-
-  bool operator==(const CatchEntryStatePair& rhs) {
-    return src == rhs.src && dest == rhs.dest;
-  }
-};
-
-// Used to construct CatchEntryState metadata for AoT mode of compilation.
-class CatchEntryStateMapBuilder : public ZoneAllocated {
+#if !defined(DART_PRECOMPILED_RUNTIME)
+// Used to construct CatchEntryMoves for the AOT mode of compilation.
+class CatchEntryMovesMapBuilder : public ZoneAllocated {
  public:
-  CatchEntryStateMapBuilder();
+  CatchEntryMovesMapBuilder();
 
   void NewMapping(intptr_t pc_offset);
-  void AppendMove(intptr_t src_slot, intptr_t dest_slot);
-  void AppendConstant(intptr_t pool_id, intptr_t dest_slot);
+  void Append(const CatchEntryMove& move);
   void EndMapping();
-  RawTypedData* FinalizeCatchEntryStateMap();
+  RawTypedData* FinalizeCatchEntryMovesMap();
 
  private:
   class TrieNode;
@@ -188,12 +161,13 @@
   Zone* zone_;
   TrieNode* root_;
   intptr_t current_pc_offset_;
-  GrowableArray<CatchEntryStatePair> moves_;
+  GrowableArray<CatchEntryMove> moves_;
   uint8_t* buffer_;
   WriteStream stream_;
 
-  DISALLOW_COPY_AND_ASSIGN(CatchEntryStateMapBuilder);
+  DISALLOW_COPY_AND_ASSIGN(CatchEntryMovesMapBuilder);
 };
+#endif  // !defined(DART_PRECOMPILED_RUNTIME)
 
 // A CodeSourceMap maps from pc offsets to a stack of inlined functions and
 // their positions. This is encoded as a little bytecode that pushes and pops
diff --git a/runtime/vm/code_patcher.h b/runtime/vm/code_patcher.h
index 17ff119..fb3716c 100644
--- a/runtime/vm/code_patcher.h
+++ b/runtime/vm/code_patcher.h
@@ -112,6 +112,18 @@
 // Example pattern: `[0x3d, 0x8b, -1, -1]`.
 bool MatchesPattern(uword addr, int16_t* pattern, intptr_t size);
 
+class KBCPatcher : public AllStatic {
+ public:
+  static NativeFunctionWrapper GetNativeCallAt(uword return_address,
+                                               const Code& bytecode,
+                                               NativeFunction* function);
+
+  static void PatchNativeCallAt(uword return_address,
+                                const Code& bytecode,
+                                NativeFunction function,
+                                NativeFunctionWrapper trampoline);
+};
+
 }  // namespace dart
 
 #endif  // RUNTIME_VM_CODE_PATCHER_H_
diff --git a/runtime/vm/code_patcher_kbc.cc b/runtime/vm/code_patcher_kbc.cc
new file mode 100644
index 0000000..de7cac4
--- /dev/null
+++ b/runtime/vm/code_patcher_kbc.cc
@@ -0,0 +1,38 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+#include "vm/globals.h"
+#if !defined(DART_PRECOMPILED_RUNTIME)
+
+#include "vm/code_patcher.h"
+
+#include "vm/instructions_kbc.h"
+#include "vm/native_entry.h"
+
+namespace dart {
+
+void KBCPatcher::PatchNativeCallAt(uword return_address,
+                                   const Code& bytecode,
+                                   NativeFunction function,
+                                   NativeFunctionWrapper trampoline) {
+  ASSERT(bytecode.ContainsInstructionAt(return_address));
+  NativeEntryData native_entry_data(TypedData::Handle(
+      KBCNativeCallPattern::GetNativeEntryDataAt(return_address, bytecode)));
+  native_entry_data.set_trampoline(trampoline);
+  native_entry_data.set_native_function(function);
+}
+
+NativeFunctionWrapper KBCPatcher::GetNativeCallAt(uword return_address,
+                                                  const Code& bytecode,
+                                                  NativeFunction* function) {
+  ASSERT(bytecode.ContainsInstructionAt(return_address));
+  NativeEntryData native_entry_data(TypedData::Handle(
+      KBCNativeCallPattern::GetNativeEntryDataAt(return_address, bytecode)));
+  *function = native_entry_data.native_function();
+  return native_entry_data.trampoline();
+}
+
+}  // namespace dart
+
+#endif  // !defined(DART_PRECOMPILED_RUNTIME)
diff --git a/runtime/vm/compiler/aot/entry_points_json.md b/runtime/vm/compiler/aot/entry_points_json.md
deleted file mode 100644
index 4ab2356..0000000
--- a/runtime/vm/compiler/aot/entry_points_json.md
+++ /dev/null
@@ -1,110 +0,0 @@
-
-# Entry points file format
-
-Dart VM precompiler (AOT compiler) performs whole-program optimizations such as
-tree shaking in order to decrease size of the resulting compiled apps and
-improve their performance. Such optimizations assume that compiler can see
-the whole Dart program, and is able to discover and analyze all Dart functions
-and members which can be potentially executed at run time. While the Dart code
-is fully available for precompiler, native code of the embedder and native
-methods are out of reach of the compiler. Such native code can call back to
-Dart via native Dart API.
-
-In order to aid precompiler, programmer can explicitly list entry
-points (roots) - Dart classes and members which are accessed from native code.
-Note that listing entry points is not optional: as long as program defines
-native methods which call into Dart, the entry points are required for the
-correctness of compilation.
-
-This memo describes _new_ format of entry points file, which is intended to
-replace old comma-separated lists of entry points. At the time of writing,
-new format is not fully adopted yet. 
-
-The native entry points are described in a JSON text file. The descriptor has the form
-
-```json
-{
- "roots": [
-    <root1>,
-    ...
-    <rootN>
-  ],
-
-  “native-methods”: {
-    “<native1_name>” : [
-      <native1_root1>,
-      ...
-      <native1_rootM1>,
-    ],
-
-    ...
-
-    “<nativeK_name>” : [
-      <nativeK_root1>,
-      ...
-      <nativeK_rootMK>,
-    ]
-  }
-```
-
-## "roots" element
-
-The “roots” element describes entry points which can be accessed by arbitrary native code.
-Each root has the following elements:
-
-```json
-{
- "library": "<library URI>",
- "class": "<class name>",
- "name": "<member name>",
- "action": "<action>"
-}
-```
-
-| Element | Meaning                                   | Can be omitted                     |
-| ------- | ----------------------------------------- | ---------------------------------- |
-| library | Library URI of the entry point.           | No.                                |
-| class   | Dart class name.                          | Omitted for top-level functions.   |
-| name    | Dart function name or member name.        | Omitted for class-related actions. |
-| action  | Specifies kind of the entry point access. | Depends on the entry point.        |
-
-
-The following actions are supported:
-* _"create-instance"_ - native code creates an instance of given Dart class.
-* _"call"_ - native code calls given Dart function or member.
-* _"get"_ - native code calls given getter or retrieves value of a given field.
-* _“set”_ - native code calls given setter or sets value to a given field.
-
-If action element is omitted, the following actions are assumed by default:
-* For classes - “create-instance”.
-* For fields - both “get” and “set” (only “get” if a field is final).
-* For others - “call”.
-
-If needed, the description of an entry point can be extended by supporting
-more elements or actions.
-
-## “native-methods” element
-
-The “native-methods” section contains description of entry points accessed from
-specific native methods. It can be used to declare behavior of a native method
-more accurately.
-Each element in “native-methods” section is identified by the native name - the
-name specified after the native clause in the Dart method or function declaration.
-
-Native method descriptor may contain arbitrary number of entry points.
-In addition to the declaration of entry points described above, native methods
-may contain the root with the action “return”, which describes the specific
-concrete type of a Dart instance returned from the native method:
-
-```json
-{
- "action": "return",
- "library": "<library URI>",
- "class": "<class name>",
- "nullable": "false|true"
-}
-```
-
-“nullable” attribute may be omitted defaulting to “true”.
-If “nullable” is “true” (or omitted), then native method can return an instance
-of the given class or null.
diff --git a/runtime/vm/compiler/aot/precompiler.cc b/runtime/vm/compiler/aot/precompiler.cc
index aa25729..5395c71 100644
--- a/runtime/vm/compiler/aot/precompiler.cc
+++ b/runtime/vm/compiler/aot/precompiler.cc
@@ -624,43 +624,6 @@
   }
 
   writer.CloseArray();  // roots
-
-  writer.OpenObject("native-methods");
-
-  GrowableObjectArray& recognized_methods = GrowableObjectArray::Handle(
-      Z, MethodRecognizer::QueryRecognizedMethods(Z));
-  ASSERT(!recognized_methods.IsNull());
-
-  for (intptr_t i = 0; i < recognized_methods.Length(); ++i) {
-    const Function& func = Function::CheckedHandle(Z, recognized_methods.At(i));
-    if (!func.is_native()) {
-      continue;
-    }
-
-    intptr_t result_cid = MethodRecognizer::ResultCid(func);
-    if (result_cid == kDynamicCid) {
-      continue;
-    }
-
-    ASSERT(Isolate::Current()->class_table()->HasValidClassAt(result_cid));
-
-    writer.OpenArray(String::Handle(func.native_name()).ToCString());
-    writer.OpenObject();
-
-    writer.PrintProperty("action", "return");
-
-    const Class& result_cls =
-        Class::Handle(Isolate::Current()->class_table()->At(result_cid));
-    DescribeClass(&writer, result_cls);
-
-    writer.PrintPropertyBool("nullable", false);
-
-    writer.CloseObject();
-    writer.CloseArray();
-  }
-
-  writer.CloseObject();  // native-methods
-
   writer.CloseObject();  // top-level
 
   const char* contents = writer.ToCString();
@@ -2678,46 +2641,6 @@
   I->set_all_classes_finalized(true);
 }
 
-void Precompiler::PopulateWithICData(const Function& function,
-                                     FlowGraph* graph) {
-  Zone* zone = Thread::Current()->zone();
-
-  for (BlockIterator block_it = graph->reverse_postorder_iterator();
-       !block_it.Done(); block_it.Advance()) {
-    ForwardInstructionIterator it(block_it.Current());
-    for (; !it.Done(); it.Advance()) {
-      Instruction* instr = it.Current();
-      if (instr->IsInstanceCall()) {
-        InstanceCallInstr* call = instr->AsInstanceCall();
-        if (!call->HasICData()) {
-          const Array& arguments_descriptor =
-              Array::Handle(zone, call->GetArgumentsDescriptor());
-          const ICData& ic_data = ICData::ZoneHandle(
-              zone,
-              ICData::New(function, call->function_name(), arguments_descriptor,
-                          call->deopt_id(), call->checked_argument_count(),
-                          ICData::kInstance));
-          call->set_ic_data(&ic_data);
-        }
-      } else if (instr->IsStaticCall()) {
-        StaticCallInstr* call = instr->AsStaticCall();
-        if (!call->HasICData()) {
-          const Array& arguments_descriptor =
-              Array::Handle(zone, call->GetArgumentsDescriptor());
-          const Function& target = call->function();
-          int num_args_checked =
-              MethodRecognizer::NumArgsCheckedForStaticCall(target);
-          const ICData& ic_data = ICData::ZoneHandle(
-              zone, ICData::New(function, String::Handle(zone, target.name()),
-                                arguments_descriptor, call->deopt_id(),
-                                num_args_checked, ICData::kStatic));
-          ic_data.AddTarget(target);
-          call->set_ic_data(&ic_data);
-        }
-      }
-    }
-  }
-}
 
 void Precompiler::ResetPrecompilerState() {
   changed_ = false;
@@ -2786,7 +2709,7 @@
   graph_compiler->FinalizeStackMaps(code);
   graph_compiler->FinalizeVarDescriptors(code);
   graph_compiler->FinalizeExceptionHandlers(code);
-  graph_compiler->FinalizeCatchEntryStateMap(code);
+  graph_compiler->FinalizeCatchEntryMovesMap(code);
   graph_compiler->FinalizeStaticCallTargetsTable(code);
   graph_compiler->FinalizeCodeSourceMap(code);
 
@@ -2851,13 +2774,12 @@
                                   "BuildFlowGraph");
 #endif  // !PRODUCT
         flow_graph =
-            pipeline->BuildFlowGraph(zone, parsed_function(), *ic_data_array,
+            pipeline->BuildFlowGraph(zone, parsed_function(), ic_data_array,
                                      Compiler::kNoOSRDeoptId, optimized());
       }
 
       if (optimized()) {
-        Precompiler::PopulateWithICData(parsed_function()->function(),
-                                        flow_graph);
+        flow_graph->PopulateWithICData(parsed_function()->function());
       }
 
       const bool print_flow_graph =
diff --git a/runtime/vm/compiler/aot/precompiler.h b/runtime/vm/compiler/aot/precompiler.h
index 671e4bd..5bb7053 100644
--- a/runtime/vm/compiler/aot/precompiler.h
+++ b/runtime/vm/compiler/aot/precompiler.h
@@ -344,8 +344,6 @@
 
   FieldTypeMap* field_type_map() { return &field_type_map_; }
 
-  static void PopulateWithICData(const Function& func, FlowGraph* graph);
-
  private:
   explicit Precompiler(Thread* thread);
 
diff --git a/runtime/vm/compiler/assembler/assembler_arm.cc b/runtime/vm/compiler/assembler/assembler_arm.cc
index 397c4e9..6c918ea 100644
--- a/runtime/vm/compiler/assembler/assembler_arm.cc
+++ b/runtime/vm/compiler/assembler/assembler_arm.cc
@@ -1587,13 +1587,45 @@
                                 Register value,
                                 CanBeSmi can_be_smi,
                                 bool lr_reserved) {
+  // x.slot = x. Barrier should have be removed at the IL level.
   ASSERT(object != value);
+  ASSERT(object != LR);
+  ASSERT(value != LR);
+
+#if defined(CONCURRENT_MARKING)
+  ASSERT(object != TMP);
+  ASSERT(value != TMP);
+
+  str(value, dest);
+
+  // In parallel, test whether
+  //  - object is old and not remembered and value is new, or
+  //  - object is old and value is old and not marked and concurrent marking is
+  //    in progress
+  // If so, call the WriteBarrier stub, which will either add object to the
+  // store buffer (case 1) or add value to the marking stack (case 2).
+  // Compare RawObject::StorePointer.
+  Label done;
+  if (can_be_smi == kValueCanBeSmi) {
+    BranchIfSmi(value, &done);
+  }
+  if (!lr_reserved) Push(LR);
+  ldrb(TMP, FieldAddress(object, Object::tags_offset()));
+  ldrb(LR, FieldAddress(value, Object::tags_offset()));
+  and_(TMP, LR, Operand(TMP, LSR, RawObject::kBarrierOverlapShift));
+  ldr(LR, Address(THR, Thread::write_barrier_mask_offset()));
+  tst(TMP, Operand(LR));
+  mov(TMP, Operand(value), NE);
+  ldr(LR, Address(THR, Thread::write_barrier_wrappers_offset(object)), NE);
+  blx(LR, NE);
+  if (!lr_reserved) Pop(LR);
+  Bind(&done);
+#else
   str(value, dest);
   // A store buffer update is required.
   if (lr_reserved) {
     StoreIntoObjectFilter(object, value, nullptr, can_be_smi, kNoJump);
-    ldr(LR, Address(THR, Thread::update_store_buffer_wrappers_offset(object)),
-        NE);
+    ldr(LR, Address(THR, Thread::write_barrier_wrappers_offset(object)), NE);
     blx(LR, NE);
   } else {
     Label done;
@@ -1607,11 +1639,12 @@
     if (object != R0) {
       mov(R0, Operand(object));
     }
-    ldr(LR, Address(THR, Thread::update_store_buffer_entry_point_offset()));
+    ldr(LR, Address(THR, Thread::write_barrier_entry_point_offset()));
     blx(LR);
     PopList(regs);
     Bind(&done);
   }
+#endif
 }
 
 void Assembler::StoreIntoObjectOffset(Register object,
@@ -2456,8 +2489,11 @@
   const int32_t offset = ObjectPool::element_offset(
       object_pool_wrapper().FindObject(target_code, patchable));
   LoadWordFromPoolOffset(CODE_REG, offset - kHeapObjectTag, pp, cond);
-  ldr(IP, FieldAddress(CODE_REG, Code::entry_point_offset()), cond);
-  bx(IP, cond);
+  Branch(FieldAddress(CODE_REG, Code::entry_point_offset()), cond);
+}
+
+void Assembler::Branch(const Address& address, Condition cond) {
+  ldr(PC, address, cond);
 }
 
 void Assembler::BranchLink(const Code& target,
@@ -3032,7 +3068,7 @@
 void Assembler::EnterCallRuntimeFrame(intptr_t frame_space) {
   Comment("EnterCallRuntimeFrame");
   // Preserve volatile CPU registers and PP.
-  EnterFrame(kDartVolatileCpuRegs | (1 << PP) | (1 << FP), 0);
+  EnterFrame(kDartVolatileCpuRegs | (1 << PP) | (1 << FP) | (1 << LR), 0);
   COMPILE_ASSERT((kDartVolatileCpuRegs & (1 << PP)) == 0);
 
   // Preserve all volatile FPU registers.
@@ -3084,7 +3120,7 @@
   }
 
   // Restore volatile CPU registers.
-  LeaveFrame(kDartVolatileCpuRegs | (1 << PP) | (1 << FP));
+  LeaveFrame(kDartVolatileCpuRegs | (1 << PP) | (1 << FP) | (1 << LR));
 }
 
 void Assembler::CallRuntime(const RuntimeEntry& entry,
@@ -3160,17 +3196,11 @@
   set_use_far_branches(false);
 #endif
 
-  Label miss;
-  Bind(&miss);
-  ldr(IP, Address(THR, Thread::monomorphic_miss_entry_offset()));
-  bx(IP);
-
   Comment("MonomorphicCheckedEntry");
   ASSERT(CodeSize() == Instructions::kCheckedEntryOffset);
   LoadClassIdMayBeSmi(IP, R0);
-  SmiUntag(R9);
-  cmp(IP, Operand(R9));
-  b(&miss, NE);
+  cmp(R9, Operand(IP, LSL, 1));
+  Branch(Address(THR, Thread::monomorphic_miss_entry_offset()), NE);
 
   // Fall through to unchecked entry.
   ASSERT(CodeSize() == Instructions::kUncheckedEntryOffset);
diff --git a/runtime/vm/compiler/assembler/assembler_arm.h b/runtime/vm/compiler/assembler/assembler_arm.h
index 6669caa..e78943db 100644
--- a/runtime/vm/compiler/assembler/assembler_arm.h
+++ b/runtime/vm/compiler/assembler/assembler_arm.h
@@ -696,6 +696,8 @@
               Register pp = PP,
               Condition cond = AL);
 
+  void Branch(const Address& address, Condition cond = AL);
+
   void BranchLink(
       const StubEntry& stub_entry,
       ObjectPool::Patchability patchable = ObjectPool::kNotPatchable);
@@ -806,6 +808,11 @@
     kValueCanBeSmi,
   };
 
+  // Store into a heap object and apply the generational and incremental write
+  // barriers. All stores into heap objects must pass through this function or,
+  // if the value can be proven either Smi or old-and-premarked, its NoBarrier
+  // variants.
+  // Preserves object and value registers.
   void StoreIntoObject(Register object,      // Object we are storing into.
                        const Address& dest,  // Where we are storing into.
                        Register value,       // Value we are storing.
diff --git a/runtime/vm/compiler/assembler/assembler_arm64.cc b/runtime/vm/compiler/assembler/assembler_arm64.cc
index 118f0d7..0f44233 100644
--- a/runtime/vm/compiler/assembler/assembler_arm64.cc
+++ b/runtime/vm/compiler/assembler/assembler_arm64.cc
@@ -408,6 +408,46 @@
   ldr(dst, Address(dst, lower12));
 }
 
+void Assembler::LoadDoubleWordFromPoolOffset(Register lower,
+                                             Register upper,
+                                             uint32_t offset) {
+  // This implementation needs to be kept in sync with
+  // [InstructionPattern::DecodeLoadDoubleWordFromPool].
+  ASSERT(constant_pool_allowed());
+  ASSERT(lower != PP && upper != PP);
+  ASSERT(offset < (1 << 24));
+
+  Operand op;
+  const uint32_t upper20 = offset & 0xfffff000;
+  const uint32_t lower12 = offset & 0x00000fff;
+  if (Address::CanHoldOffset(offset, Address::PairOffset)) {
+    ldp(lower, upper, Address(PP, offset, Address::PairOffset));
+  } else if (Operand::CanHold(offset, kXRegSizeInBits, &op) ==
+             Operand::Immediate) {
+    add(TMP, PP, op);
+    ldp(lower, upper, Address(TMP, 0, Address::PairOffset));
+  } else if (Operand::CanHold(upper20, kXRegSizeInBits, &op) ==
+                 Operand::Immediate &&
+             Address::CanHoldOffset(lower12, Address::PairOffset)) {
+    add(TMP, PP, op);
+    ldp(lower, upper, Address(TMP, lower12, Address::PairOffset));
+  } else {
+    const uint32_t lower12 = offset & 0xfff;
+    const uint32_t higher12 = offset & 0xfff000;
+
+    Operand op_high, op_low;
+    bool ok = Operand::CanHold(higher12, kXRegSizeInBits, &op_high) ==
+                  Operand::Immediate &&
+              Operand::CanHold(lower12, kXRegSizeInBits, &op_low) ==
+                  Operand::Immediate;
+    RELEASE_ASSERT(ok);
+
+    add(TMP, PP, op_high);
+    add(TMP, TMP, op_low);
+    ldp(lower, upper, Address(TMP, 0, Address::PairOffset));
+  }
+}
+
 intptr_t Assembler::FindImmediate(int64_t imm) {
   return object_pool_wrapper().FindImmediate(imm);
 }
@@ -459,7 +499,7 @@
     LoadWordFromPoolOffset(dst, offset);
   } else {
     ASSERT(object.IsSmi());
-    LoadDecodableImmediate(dst, reinterpret_cast<int64_t>(object.raw()));
+    LoadImmediate(dst, reinterpret_cast<int64_t>(object.raw()));
   }
 }
 
@@ -497,32 +537,7 @@
   }
 }
 
-void Assembler::LoadDecodableImmediate(Register reg, int64_t imm) {
-  if (constant_pool_allowed()) {
-    const int32_t offset = ObjectPool::element_offset(FindImmediate(imm));
-    LoadWordFromPoolOffset(reg, offset);
-  } else {
-    // TODO(zra): Since this sequence only needs to be decodable, it can be
-    // of variable length.
-    LoadImmediateFixed(reg, imm);
-  }
-}
-
-void Assembler::LoadImmediateFixed(Register reg, int64_t imm) {
-  const uint32_t w0 = Utils::Low32Bits(imm);
-  const uint32_t w1 = Utils::High32Bits(imm);
-  const uint16_t h0 = Utils::Low16Bits(w0);
-  const uint16_t h1 = Utils::High16Bits(w0);
-  const uint16_t h2 = Utils::Low16Bits(w1);
-  const uint16_t h3 = Utils::High16Bits(w1);
-  movz(reg, Immediate(h0), 0);
-  movk(reg, Immediate(h1), 1);
-  movk(reg, Immediate(h2), 2);
-  movk(reg, Immediate(h3), 3);
-}
-
 void Assembler::LoadImmediate(Register reg, int64_t imm) {
-  Comment("LoadImmediate");
   // Is it 0?
   if (imm == 0) {
     movz(reg, Immediate(0), 0);
@@ -961,15 +976,56 @@
                                 Register value,
                                 CanBeSmi can_be_smi,
                                 bool lr_reserved) {
+  // x.slot = x. Barrier should have be removed at the IL level.
   ASSERT(object != value);
+  ASSERT(object != LR);
+  ASSERT(value != LR);
+
+#if defined(CONCURRENT_MARKING)
+  ASSERT(object != TMP);
+  ASSERT(object != TMP2);
+  ASSERT(value != TMP);
+  ASSERT(value != TMP2);
+
+  str(value, dest);
+
+  // In parallel, test whether
+  //  - object is old and not remembered and value is new, or
+  //  - object is old and value is old and not marked and concurrent marking is
+  //    in progress
+  // If so, call the WriteBarrier stub, which will either add object to the
+  // store buffer (case 1) or add value to the marking stack (case 2).
+  // Compare RawObject::StorePointer.
+  Label done;
+  if (can_be_smi == kValueCanBeSmi) {
+    BranchIfSmi(value, &done);
+  }
+  ldr(TMP, FieldAddress(object, Object::tags_offset()), kUnsignedByte);
+  ldr(TMP2, FieldAddress(value, Object::tags_offset()), kUnsignedByte);
+  and_(TMP, TMP2, Operand(TMP, LSR, RawObject::kBarrierOverlapShift));
+  tst(TMP, Operand(BARRIER_MASK));
+  b(&done, EQ);
+
+  if (!lr_reserved) Push(LR);
+  mov(TMP2, value);
+  ldr(LR, Address(THR, Thread::write_barrier_wrappers_offset(object)));
+  blr(LR);
+  if (!lr_reserved) Pop(LR);
+  Bind(&done);
+#else
+  ASSERT(object != value);
+  ASSERT(object != LR);
+  ASSERT(value != LR);
+
   str(value, dest);
   Label done;
   StoreIntoObjectFilter(object, value, &done, can_be_smi, kJumpToNoUpdate);
   if (!lr_reserved) Push(LR);
-  ldr(LR, Address(THR, Thread::update_store_buffer_wrappers_offset(object)));
+  ldr(LR, Address(THR, Thread::write_barrier_wrappers_offset(object)));
   blr(LR);
   if (!lr_reserved) Pop(LR);
   Bind(&done);
+#endif
 }
 
 void Assembler::StoreIntoObjectNoBarrier(Register object,
@@ -1269,25 +1325,15 @@
   bool saved_use_far_branches = use_far_branches();
   set_use_far_branches(false);
 
-  Label immediate, have_cid, miss;
+  Label immediate, miss;
   Bind(&miss);
   ldr(IP0, Address(THR, Thread::monomorphic_miss_entry_offset()));
   br(IP0);
 
-  Bind(&immediate);
-  movz(IP0, Immediate(kSmiCid), 0);
-  b(&have_cid);
-
   Comment("MonomorphicCheckedEntry");
   ASSERT(CodeSize() == Instructions::kCheckedEntryOffset);
-  tsti(R0, Immediate(kSmiTagMask));
-  SmiUntag(R5);
-  b(&immediate, EQ);
-
-  LoadClassId(IP0, R0);
-
-  Bind(&have_cid);
-  cmp(IP0, Operand(R5));
+  LoadClassIdMayBeSmi(IP0, R0);
+  cmp(R5, Operand(IP0, LSL, 1));
   b(&miss, NE);
 
   // Fall through to unchecked entry.
@@ -1356,31 +1402,34 @@
 void Assembler::TryAllocate(const Class& cls,
                             Label* failure,
                             Register instance_reg,
-                            Register temp_reg) {
+                            Register top_reg,
+                            bool tag_result) {
   ASSERT(failure != NULL);
   const intptr_t instance_size = cls.instance_size();
   if (FLAG_inline_alloc && Heap::IsAllocatableInNewSpace(instance_size)) {
     // If this allocation is traced, program will jump to failure path
     // (i.e. the allocation stub) which will allocate the object and trace the
     // allocation call site.
-    NOT_IN_PRODUCT(MaybeTraceAllocation(cls.id(), temp_reg, failure));
-    NOT_IN_PRODUCT(Heap::Space space = Heap::kNew);
-    ldr(instance_reg, Address(THR, Thread::top_offset()));
-    // TODO(koda): Protect against unsigned overflow here.
-    AddImmediateSetFlags(instance_reg, instance_reg, instance_size);
+    NOT_IN_PRODUCT(
+        MaybeTraceAllocation(cls.id(), /*temp_reg=*/top_reg, failure));
+
+    const Register kEndReg = TMP;
 
     // instance_reg: potential next object start.
-    ldr(TMP, Address(THR, Thread::end_offset()));
-    CompareRegisters(TMP, instance_reg);
-    // fail if heap end unsigned less than or equal to instance_reg.
-    b(failure, LS);
+    RELEASE_ASSERT((Thread::top_offset() + kWordSize) == Thread::end_offset());
+    ldp(instance_reg, kEndReg,
+        Address(THR, Thread::top_offset(), Address::PairOffset));
+
+    // TODO(koda): Protect against unsigned overflow here.
+    AddImmediate(top_reg, instance_reg, instance_size);
+    cmp(kEndReg, Operand(top_reg));
+    b(failure, LS);  // Unsigned lower or equal.
 
     // Successfully allocated the object, now update top to point to
     // next object start and store the class in the class field of object.
-    str(instance_reg, Address(THR, Thread::top_offset()));
+    str(top_reg, Address(THR, Thread::top_offset()));
 
-    ASSERT(instance_size >= kHeapObjectTag);
-    AddImmediate(instance_reg, -instance_size + kHeapObjectTag);
+    NOT_IN_PRODUCT(Heap::Space space = Heap::kNew);
     NOT_IN_PRODUCT(UpdateAllocationStats(cls.id(), space));
 
     uint32_t tags = 0;
@@ -1391,7 +1440,11 @@
     // Extends the 32 bit tags with zeros, which is the uninitialized
     // hash code.
     LoadImmediate(TMP, tags);
-    StoreFieldToOffset(TMP, instance_reg, Object::tags_offset());
+    StoreToOffset(TMP, instance_reg, Object::tags_offset());
+
+    if (tag_result) {
+      AddImmediate(instance_reg, kHeapObjectTag);
+    }
   } else {
     b(failure);
   }
@@ -1608,21 +1661,43 @@
 
   // The order in which the registers are pushed must match the order
   // in which the registers are encoded in the safe point's stack map.
+  Register prev = kNoRegister;
   for (intptr_t i = kNumberOfCpuRegisters - 1; i >= 0; --i) {
     Register reg = static_cast<Register>(i);
     if (regs.ContainsRegister(reg)) {
-      Push(reg);
+      if (prev != kNoRegister) {
+        PushPair(/*low=*/reg, /*high=*/prev);
+        prev = kNoRegister;
+      } else {
+        prev = reg;
+      }
     }
   }
+  if (prev != kNoRegister) {
+    Push(prev);
+  }
 }
 
 void Assembler::PopRegisters(const RegisterSet& regs) {
+  bool pop_single = (regs.CpuRegisterCount() & 1) == 1;
+  Register prev = kNoRegister;
   for (intptr_t i = 0; i < kNumberOfCpuRegisters; ++i) {
     Register reg = static_cast<Register>(i);
     if (regs.ContainsRegister(reg)) {
-      Pop(reg);
+      if (pop_single) {
+        // Emit the leftover pop at the beginning instead of the end to
+        // mirror PushRegisters.
+        Pop(reg);
+        pop_single = false;
+      } else if (prev != kNoRegister) {
+        PopPair(/*low=*/prev, /*high=*/reg);
+        prev = kNoRegister;
+      } else {
+        prev = reg;
+      }
     }
   }
+  ASSERT(prev == kNoRegister);
 
   const intptr_t fpu_regs_count = regs.FpuRegisterCount();
   if (fpu_regs_count > 0) {
diff --git a/runtime/vm/compiler/assembler/assembler_arm64.h b/runtime/vm/compiler/assembler/assembler_arm64.h
index 3cbafae..785b0ac 100644
--- a/runtime/vm/compiler/assembler/assembler_arm64.h
+++ b/runtime/vm/compiler/assembler/assembler_arm64.h
@@ -435,8 +435,17 @@
   void PushRegisters(const RegisterSet& registers);
   void PopRegisters(const RegisterSet& registers);
 
+  void MoveRegister(Register rd, Register rn) {
+    if (rd != rn) {
+      mov(rd, rn);
+    }
+  }
+
   void Drop(intptr_t stack_elements) {
-    add(SP, SP, Operand(stack_elements * kWordSize));
+    ASSERT(stack_elements >= 0);
+    if (stack_elements > 0) {
+      add(SP, SP, Operand(stack_elements * kWordSize));
+    }
   }
 
   void Bind(Label* label);
@@ -1458,7 +1467,11 @@
     kValueCanBeSmi,
   };
 
-  // Storing into an object.
+  // Store into a heap object and apply the generational and incremental write
+  // barriers. All stores into heap objects must pass through this function or,
+  // if the value can be proven either Smi or old-and-premarked, its NoBarrier
+  // variants.
+  // Preserves object and value registers.
   void StoreIntoObject(Register object,
                        const Address& dest,
                        Register value,
@@ -1499,14 +1512,15 @@
   void LoadIsolate(Register dst);
   void LoadObject(Register dst, const Object& obj);
   void LoadUniqueObject(Register dst, const Object& obj);
-  void LoadDecodableImmediate(Register reg, int64_t imm);
-  void LoadImmediateFixed(Register reg, int64_t imm);
   void LoadImmediate(Register reg, int64_t imm);
   void LoadDImmediate(VRegister reg, double immd);
 
   // Load word from pool from the given offset using encoding that
   // InstructionPattern::DecodeLoadWordFromPool can decode.
   void LoadWordFromPoolOffset(Register dst, uint32_t offset, Register pp = PP);
+  void LoadDoubleWordFromPoolOffset(Register lower,
+                                    Register upper,
+                                    uint32_t offset);
 
   void PushObject(const Object& object) {
     LoadObject(TMP, object);
@@ -1563,10 +1577,14 @@
   // calls. Jump to 'failure' if the instance cannot be allocated here.
   // Allocated instance is returned in 'instance_reg'.
   // Only the tags field of the object is initialized.
+  // Result:
+  //   * [instance_reg] will contain allocated new-space object
+  //   * [top_reg] will contain Thread::top_offset()
   void TryAllocate(const Class& cls,
                    Label* failure,
                    Register instance_reg,
-                   Register temp_reg);
+                   Register top_reg,
+                   bool tag_result = true);
 
   void TryAllocateArray(intptr_t cid,
                         intptr_t instance_size,
diff --git a/runtime/vm/compiler/assembler/assembler_arm64_test.cc b/runtime/vm/compiler/assembler/assembler_arm64_test.cc
index bf690bc..e3625d0 100644
--- a/runtime/vm/compiler/assembler/assembler_arm64_test.cc
+++ b/runtime/vm/compiler/assembler/assembler_arm64_test.cc
@@ -2058,14 +2058,17 @@
   __ EnterFrame(0);
   __ Push(CODE_REG);
   __ Push(THR);
+  __ Push(BARRIER_MASK);
   __ TagAndPushPP();
   __ ldr(CODE_REG, Address(R0, VMHandles::kOffsetOfRawPtrInHandle));
   __ mov(THR, R1);
+  __ ldr(BARRIER_MASK, Address(THR, Thread::write_barrier_mask_offset()));
   __ LoadPoolPointer(PP);
 }
 
 static void LeaveTestFrame(Assembler* assembler) {
   __ PopAndUntagPP();
+  __ Pop(BARRIER_MASK);
   __ Pop(THR);
   __ Pop(CODE_REG);
   __ LeaveFrame();
@@ -4090,11 +4093,14 @@
   __ SetupDartSP();
   __ Push(CODE_REG);
   __ Push(THR);
+  __ Push(BARRIER_MASK);
   __ Push(LR);
   __ mov(THR, R2);
+  __ ldr(BARRIER_MASK, Address(THR, Thread::write_barrier_mask_offset()));
   __ StoreIntoObject(R1, FieldAddress(R1, GrowableObjectArray::data_offset()),
                      R0);
   __ Pop(LR);
+  __ Pop(BARRIER_MASK);
   __ Pop(THR);
   __ Pop(CODE_REG);
   __ RestoreCSP();
diff --git a/runtime/vm/compiler/assembler/assembler_ia32.cc b/runtime/vm/compiler/assembler/assembler_ia32.cc
index 5e77c27..082f20f 100644
--- a/runtime/vm/compiler/assembler/assembler_ia32.cc
+++ b/runtime/vm/compiler/assembler/assembler_ia32.cc
@@ -1870,12 +1870,13 @@
   j(condition, label, distance);
 }
 
-// Destroys the value register.
 void Assembler::StoreIntoObject(Register object,
                                 const Address& dest,
                                 Register value,
                                 CanBeSmi can_be_smi) {
+  // x.slot = x. Barrier should have be removed at the IL level.
   ASSERT(object != value);
+
   movl(dest, value);
   Label done;
   StoreIntoObjectFilter(object, value, &done, can_be_smi, kJumpToNoUpdate);
@@ -1886,7 +1887,7 @@
   if (object != EDX) {
     movl(EDX, object);
   }
-  call(Address(THR, Thread::update_store_buffer_entry_point_offset()));
+  call(Address(THR, Thread::write_barrier_entry_point_offset()));
   if (value != EDX) {
     popl(EDX);  // Restore EDX.
   }
diff --git a/runtime/vm/compiler/assembler/assembler_ia32.h b/runtime/vm/compiler/assembler/assembler_ia32.h
index 1684bb6..c3b8492 100644
--- a/runtime/vm/compiler/assembler/assembler_ia32.h
+++ b/runtime/vm/compiler/assembler/assembler_ia32.h
@@ -605,6 +605,12 @@
     kValueCanBeSmi,
   };
 
+  // Store into a heap object and apply the generational write barrier. (Unlike
+  // the other architectures, this does not apply the incremental write barrier,
+  // and so concurrent marking is not enabled for now on IA32.) All stores into
+  // heap objects must pass through this function or, if the value can be proven
+  // either Smi or old-and-premarked, its NoBarrier variants.
+  // Destroys the value register.
   void StoreIntoObject(Register object,      // Object we are storing into.
                        const Address& dest,  // Where we are storing into.
                        Register value,       // Value we are storing.
diff --git a/runtime/vm/compiler/assembler/assembler_x64.cc b/runtime/vm/compiler/assembler/assembler_x64.cc
index 07f946f..24384ca 100644
--- a/runtime/vm/compiler/assembler/assembler_x64.cc
+++ b/runtime/vm/compiler/assembler/assembler_x64.cc
@@ -1272,13 +1272,43 @@
                                 const Address& dest,
                                 Register value,
                                 CanBeSmi can_be_smi) {
+  // x.slot = x. Barrier should have be removed at the IL level.
   ASSERT(object != value);
+
+#if defined(CONCURRENT_MARKING)
+  ASSERT(object != TMP);
+  ASSERT(value != TMP);
+
+  movq(dest, value);
+
+  // In parallel, test whether
+  //  - object is old and not remembered and value is new, or
+  //  - object is old and value is old and not marked and concurrent marking is
+  //    in progress
+  // If so, call the WriteBarrier stub, which will either add object to the
+  // store buffer (case 1) or add value to the marking stack (case 2).
+  // Compare RawObject::StorePointer.
+  Label done;
+  if (can_be_smi == kValueCanBeSmi) {
+    testq(value, Immediate(kSmiTagMask));
+    j(ZERO, &done, kNearJump);
+  }
+  movb(TMP, FieldAddress(object, Object::tags_offset()));
+  shrl(TMP, Immediate(RawObject::kBarrierOverlapShift));
+  andl(TMP, Address(THR, Thread::write_barrier_mask_offset()));
+  testb(FieldAddress(value, Object::tags_offset()), TMP);
+  j(ZERO, &done, kNearJump);
+  movq(TMP, value);
+  call(Address(THR, Thread::write_barrier_wrappers_offset(object)));
+  Bind(&done);
+#else
   movq(dest, value);
   Label done;
   StoreIntoObjectFilter(object, value, &done, can_be_smi, kJumpToNoUpdate);
   // A store buffer update is required.
-  call(Address(THR, Thread::update_store_buffer_wrappers_offset(object)));
+  call(Address(THR, Thread::write_barrier_wrappers_offset(object)));
   Bind(&done);
+#endif
 }
 
 void Assembler::StoreIntoObjectNoBarrier(Register object,
diff --git a/runtime/vm/compiler/assembler/assembler_x64.h b/runtime/vm/compiler/assembler/assembler_x64.h
index bec61ed..cd5f054 100644
--- a/runtime/vm/compiler/assembler/assembler_x64.h
+++ b/runtime/vm/compiler/assembler/assembler_x64.h
@@ -719,7 +719,11 @@
     kValueCanBeSmi,
   };
 
-  // Destroys value.
+  // Store into a heap object and apply the generational and incremental write
+  // barriers. All stores into heap objects must pass through this function or,
+  // if the value can be proven either Smi or old-and-premarked, its NoBarrier
+  // variants.
+  // Preserves object and value registers.
   void StoreIntoObject(Register object,      // Object we are storing into.
                        const Address& dest,  // Where we are storing into.
                        Register value,       // Value we are storing.
diff --git a/runtime/vm/compiler/assembler/disassembler_kbc.cc b/runtime/vm/compiler/assembler/disassembler_kbc.cc
index 69d4736..a1da9ee 100644
--- a/runtime/vm/compiler/assembler/disassembler_kbc.cc
+++ b/runtime/vm/compiler/assembler/disassembler_kbc.cc
@@ -3,7 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 #include "vm/globals.h"
-#if defined(DART_USE_INTERPRETER)
+#if !defined(DART_PRECOMPILED_RUNTIME)
 
 #include "vm/compiler/assembler/disassembler_kbc.h"
 
@@ -370,4 +370,4 @@
 
 }  // namespace dart
 
-#endif  // defined(DART_USE_INTERPRETER)
+#endif  // !defined(DART_PRECOMPILED_RUNTIME)
diff --git a/runtime/vm/compiler/assembler/disassembler_kbc.h b/runtime/vm/compiler/assembler/disassembler_kbc.h
index b3e2408..3512779 100644
--- a/runtime/vm/compiler/assembler/disassembler_kbc.h
+++ b/runtime/vm/compiler/assembler/disassembler_kbc.h
@@ -6,7 +6,7 @@
 #define RUNTIME_VM_COMPILER_ASSEMBLER_DISASSEMBLER_KBC_H_
 
 #include "vm/globals.h"
-#if defined(DART_USE_INTERPRETER)
+#if !defined(DART_PRECOMPILED_RUNTIME)
 
 #include "vm/compiler/assembler/disassembler.h"
 
@@ -84,6 +84,6 @@
 
 }  // namespace dart
 
-#endif  // defined(DART_USE_INTERPRETER)
+#endif  // !defined(DART_PRECOMPILED_RUNTIME)
 
 #endif  // RUNTIME_VM_COMPILER_ASSEMBLER_DISASSEMBLER_KBC_H_
diff --git a/runtime/vm/compiler/backend/flow_graph.cc b/runtime/vm/compiler/backend/flow_graph.cc
index e92b110..161889f 100644
--- a/runtime/vm/compiler/backend/flow_graph.cc
+++ b/runtime/vm/compiler/backend/flow_graph.cc
@@ -1048,7 +1048,7 @@
 
   // Check if inlining_parameters include a type argument vector parameter.
   const intptr_t inlined_type_args_param =
-      (isolate()->reify_generic_functions() && (inlining_parameters != NULL) &&
+      (FLAG_reify_generic_functions && (inlining_parameters != NULL) &&
        function().IsGeneric())
           ? 1
           : 0;
@@ -1091,7 +1091,7 @@
 
     if (!IsCompiledForOsr()) {
       const bool reify_generic_argument =
-          function().IsGeneric() && isolate()->reify_generic_functions();
+          function().IsGeneric() && FLAG_reify_generic_functions;
 
       // Replace the type arguments slot with a special parameter.
       if (reify_generic_argument) {
@@ -1702,32 +1702,12 @@
   }
 }
 
-void FlowGraph::ConvertEnvironmentUse(Value* use, Representation from_rep) {
-  const Representation to_rep = kTagged;
-  if (from_rep == to_rep) {
-    return;
-  }
-  InsertConversion(from_rep, to_rep, use, /*is_environment_use=*/true);
-}
-
 void FlowGraph::InsertConversionsFor(Definition* def) {
   const Representation from_rep = def->representation();
 
   for (Value::Iterator it(def->input_use_list()); !it.Done(); it.Advance()) {
     ConvertUse(it.Current(), from_rep);
   }
-
-  if (!graph_entry()->catch_entries().is_empty()) {
-    for (Value::Iterator it(def->env_use_list()); !it.Done(); it.Advance()) {
-      Value* use = it.Current();
-      if (use->instruction()->MayThrow() &&
-          use->instruction()->GetBlock()->InsideTryBlock()) {
-        // Environment uses at calls inside try-blocks must be converted to
-        // tagged representation.
-        ConvertEnvironmentUse(it.Current(), from_rep);
-      }
-    }
-  }
 }
 
 static void UnboxPhi(PhiInstr* phi) {
@@ -2132,6 +2112,46 @@
   return changed;
 }
 
+void FlowGraph::PopulateWithICData(const Function& function) {
+  Zone* zone = Thread::Current()->zone();
+
+  for (BlockIterator block_it = reverse_postorder_iterator(); !block_it.Done();
+       block_it.Advance()) {
+    ForwardInstructionIterator it(block_it.Current());
+    for (; !it.Done(); it.Advance()) {
+      Instruction* instr = it.Current();
+      if (instr->IsInstanceCall()) {
+        InstanceCallInstr* call = instr->AsInstanceCall();
+        if (!call->HasICData()) {
+          const Array& arguments_descriptor =
+              Array::Handle(zone, call->GetArgumentsDescriptor());
+          const ICData& ic_data = ICData::ZoneHandle(
+              zone,
+              ICData::New(function, call->function_name(), arguments_descriptor,
+                          call->deopt_id(), call->checked_argument_count(),
+                          ICData::kInstance));
+          call->set_ic_data(&ic_data);
+        }
+      } else if (instr->IsStaticCall()) {
+        StaticCallInstr* call = instr->AsStaticCall();
+        if (!call->HasICData()) {
+          const Array& arguments_descriptor =
+              Array::Handle(zone, call->GetArgumentsDescriptor());
+          const Function& target = call->function();
+          int num_args_checked =
+              MethodRecognizer::NumArgsCheckedForStaticCall(target);
+          const ICData& ic_data = ICData::ZoneHandle(
+              zone, ICData::New(function, String::Handle(zone, target.name()),
+                                arguments_descriptor, call->deopt_id(),
+                                num_args_checked, ICData::kStatic));
+          ic_data.AddTarget(target);
+          call->set_ic_data(&ic_data);
+        }
+      }
+    }
+  }
+}
+
 // Optimize (a << b) & c pattern: if c is a positive Smi or zero, then the
 // shift can be a truncating Smi shift-left and result is always Smi.
 // Merging occurs only per basic-block.
diff --git a/runtime/vm/compiler/backend/flow_graph.h b/runtime/vm/compiler/backend/flow_graph.h
index 37445e6..a027b8a 100644
--- a/runtime/vm/compiler/backend/flow_graph.h
+++ b/runtime/vm/compiler/backend/flow_graph.h
@@ -128,7 +128,9 @@
   }
 
   intptr_t CurrentContextEnvIndex() const {
-    return EnvIndex(parsed_function().current_context_var());
+    return FLAG_use_bytecode_compiler
+               ? -1
+               : EnvIndex(parsed_function().current_context_var());
   }
 
   intptr_t RawTypeArgumentEnvIndex() const {
@@ -325,6 +327,10 @@
   // Returns true if any instructions were canonicalized away.
   bool Canonicalize();
 
+  // Attaches new ICData's to static/instance calls which don't already have
+  // them.
+  void PopulateWithICData(const Function& function);
+
   void SelectRepresentations();
 
   void WidenSmiToInt32();
@@ -434,7 +440,6 @@
 
   void InsertConversionsFor(Definition* def);
   void ConvertUse(Value* use, Representation from);
-  void ConvertEnvironmentUse(Value* use, Representation from);
   void InsertConversion(Representation from,
                         Representation to,
                         Value* use,
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler.cc b/runtime/vm/compiler/backend/flow_graph_compiler.cc
index ad396ce..efb9313 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler.cc
@@ -119,7 +119,7 @@
       pc_descriptors_list_(NULL),
       stackmap_table_builder_(NULL),
       code_source_map_builder_(NULL),
-      catch_entry_state_maps_builder_(NULL),
+      catch_entry_moves_maps_builder_(NULL),
       block_info_(block_order_.length()),
       deopt_infos_(),
       static_calls_target_table_(),
@@ -183,7 +183,9 @@
 void FlowGraphCompiler::InitCompiler() {
   pc_descriptors_list_ = new (zone()) DescriptorList(64);
   exception_handlers_list_ = new (zone()) ExceptionHandlerList();
-  catch_entry_state_maps_builder_ = new (zone()) CatchEntryStateMapBuilder();
+#if defined(DART_PRECOMPILER)
+  catch_entry_moves_maps_builder_ = new (zone()) CatchEntryMovesMapBuilder();
+#endif
   block_info_.Clear();
   // Initialize block info and search optimized (non-OSR) code for calls
   // indicating a non-leaf routine and calls without IC data indicating
@@ -340,80 +342,122 @@
   return 0;
 }
 
-void FlowGraphCompiler::EmitCatchEntryState(Environment* env,
-                                            intptr_t try_index) {
-#if defined(DART_PRECOMPILER) || defined(DART_PRECOMPILED_RUNTIME)
+#if defined(DART_PRECOMPILER)
+static intptr_t LocationToStackIndex(const Location& src) {
+  ASSERT(src.HasStackIndex());
+  return -compiler_frame_layout.VariableIndexForFrameSlot(src.stack_index());
+}
+
+static CatchEntryMove CatchEntryMoveFor(Assembler* assembler,
+                                        Representation src_rep,
+                                        const Location& src,
+                                        intptr_t dst_index) {
+  if (src.IsConstant()) {
+    // Skip dead locations.
+    if (src.constant().raw() == Symbols::OptimizedOut().raw()) {
+      return CatchEntryMove();
+    }
+    const intptr_t pool_index =
+        assembler->object_pool_wrapper().FindObject(src.constant());
+    return CatchEntryMove::FromSlot(CatchEntryMove::SourceKind::kConstant,
+                                    pool_index, dst_index);
+  }
+
+  if (src.IsPairLocation()) {
+    const auto lo_loc = src.AsPairLocation()->At(0);
+    const auto hi_loc = src.AsPairLocation()->At(1);
+    ASSERT(lo_loc.IsStackSlot() && hi_loc.IsStackSlot());
+    return CatchEntryMove::FromSlot(
+        CatchEntryMove::SourceKind::kInt64PairSlot,
+        CatchEntryMove::EncodePairSource(LocationToStackIndex(lo_loc),
+                                         LocationToStackIndex(hi_loc)),
+        dst_index);
+  }
+
+  CatchEntryMove::SourceKind src_kind;
+  switch (src_rep) {
+    case kTagged:
+      src_kind = CatchEntryMove::SourceKind::kTaggedSlot;
+      break;
+    case kUnboxedInt64:
+      src_kind = CatchEntryMove::SourceKind::kInt64Slot;
+      break;
+    case kUnboxedInt32:
+      src_kind = CatchEntryMove::SourceKind::kInt32Slot;
+      break;
+    case kUnboxedUint32:
+      src_kind = CatchEntryMove::SourceKind::kUint32Slot;
+      break;
+    case kUnboxedDouble:
+      src_kind = CatchEntryMove::SourceKind::kDoubleSlot;
+      break;
+    case kUnboxedFloat32x4:
+      src_kind = CatchEntryMove::SourceKind::kFloat32x4Slot;
+      break;
+    case kUnboxedFloat64x2:
+      src_kind = CatchEntryMove::SourceKind::kFloat64x2Slot;
+      break;
+    case kUnboxedInt32x4:
+      src_kind = CatchEntryMove::SourceKind::kInt32x4Slot;
+      break;
+    default:
+      UNREACHABLE();
+      break;
+  }
+
+  return CatchEntryMove::FromSlot(src_kind, LocationToStackIndex(src),
+                                  dst_index);
+}
+#endif
+
+void FlowGraphCompiler::RecordCatchEntryMoves(Environment* env,
+                                              intptr_t try_index) {
+#if defined(DART_PRECOMPILER)
   env = env ? env : pending_deoptimization_env_;
   try_index = try_index != CatchClauseNode::kInvalidTryIndex
                   ? try_index
                   : CurrentTryIndex();
-  if (is_optimizing() && env != NULL &&
+  if (is_optimizing() && env != nullptr &&
       (try_index != CatchClauseNode::kInvalidTryIndex)) {
     env = env->Outermost();
     CatchBlockEntryInstr* catch_block =
         flow_graph().graph_entry()->GetCatchEntry(try_index);
     const GrowableArray<Definition*>* idefs =
         catch_block->initial_definitions();
-    catch_entry_state_maps_builder_->NewMapping(assembler()->CodeSize());
-    // Parameters first.
-    intptr_t i = 0;
+    catch_entry_moves_maps_builder_->NewMapping(assembler()->CodeSize());
 
     const intptr_t num_direct_parameters = flow_graph().num_direct_parameters();
-    for (; i < num_direct_parameters; ++i) {
+    const intptr_t ex_idx =
+        catch_block->raw_exception_var() != nullptr
+            ? flow_graph().EnvIndex(catch_block->raw_exception_var())
+            : -1;
+    const intptr_t st_idx =
+        catch_block->raw_stacktrace_var() != nullptr
+            ? flow_graph().EnvIndex(catch_block->raw_stacktrace_var())
+            : -1;
+    for (intptr_t i = 0; i < flow_graph().variable_count(); ++i) {
       // Don't sync captured parameters. They are not in the environment.
       if (flow_graph().captured_parameters()->Contains(i)) continue;
-      if ((*idefs)[i]->IsConstant()) continue;  // Common constants.
+      // Don't sync exception or stack trace variables.
+      if (i == ex_idx || i == st_idx) continue;
+      // Don't sync values that have been replaced with constants.
+      if ((*idefs)[i]->IsConstant()) continue;
+
       Location src = env->LocationAt(i);
+      // Can only occur if AllocationSinking is enabled - and it is disabled
+      // in functions with try.
+      ASSERT(!src.IsInvalid());
+      const Representation src_rep =
+          env->ValueAt(i)->definition()->representation();
       intptr_t dest_index = i - num_direct_parameters;
-      if (!src.IsStackSlot()) {
-        ASSERT(src.IsConstant());
-        // Skip dead locations.
-        if (src.constant().raw() == Symbols::OptimizedOut().raw()) {
-          continue;
-        }
-        intptr_t id =
-            assembler()->object_pool_wrapper().FindObject(src.constant());
-        catch_entry_state_maps_builder_->AppendConstant(id, dest_index);
-        continue;
-      }
-      const intptr_t src_index =
-          -compiler_frame_layout.VariableIndexForFrameSlot(src.stack_index());
-      if (src_index != dest_index) {
-        catch_entry_state_maps_builder_->AppendMove(src_index, dest_index);
+      const auto move =
+          CatchEntryMoveFor(assembler(), src_rep, src, dest_index);
+      if (!move.IsRedundant()) {
+        catch_entry_moves_maps_builder_->Append(move);
       }
     }
 
-    // Process locals. Skip exception_var and stacktrace_var.
-    intptr_t local_base = num_direct_parameters;
-    intptr_t ex_idx = local_base - catch_block->exception_var().index().value();
-    intptr_t st_idx =
-        local_base - catch_block->stacktrace_var().index().value();
-    for (; i < flow_graph().variable_count(); ++i) {
-      // Don't sync captured parameters. They are not in the environment.
-      if (flow_graph().captured_parameters()->Contains(i)) continue;
-      if (i == ex_idx || i == st_idx) continue;
-      if ((*idefs)[i]->IsConstant()) continue;  // Common constants.
-      Location src = env->LocationAt(i);
-      if (src.IsInvalid()) continue;
-      intptr_t dest_index = i - num_direct_parameters;
-      if (!src.IsStackSlot()) {
-        ASSERT(src.IsConstant());
-        // Skip dead locations.
-        if (src.constant().raw() == Symbols::OptimizedOut().raw()) {
-          continue;
-        }
-        intptr_t id =
-            assembler()->object_pool_wrapper().FindObject(src.constant());
-        catch_entry_state_maps_builder_->AppendConstant(id, dest_index);
-        continue;
-      }
-      const intptr_t src_index =
-          -compiler_frame_layout.VariableIndexForFrameSlot(src.stack_index());
-      if (src_index != dest_index) {
-        catch_entry_state_maps_builder_->AppendMove(src_index, dest_index);
-      }
-    }
-    catch_entry_state_maps_builder_->EndMapping();
+    catch_entry_moves_maps_builder_->EndMapping();
   }
 #endif  // defined(DART_PRECOMPILER) || defined(DART_PRECOMPILED_RUNTIME)
 }
@@ -424,7 +468,7 @@
                                              LocationSummary* locs) {
   AddCurrentDescriptor(kind, deopt_id, token_pos);
   RecordSafepoint(locs);
-  EmitCatchEntryState();
+  RecordCatchEntryMoves();
   if (deopt_id != DeoptId::kNone) {
     // Marks either the continuation point in unoptimized code or the
     // deoptimization point in optimized code, after call.
@@ -993,7 +1037,8 @@
 }
 
 void FlowGraphCompiler::FinalizeVarDescriptors(const Code& code) {
-  if (code.is_optimized()) {
+  // TODO(alexmarkov): revise local vars descriptors when compiling bytecode
+  if (code.is_optimized() || FLAG_use_bytecode_compiler) {
     // Optimized code does not need variable descriptors. They are
     // only stored in the unoptimized version.
     code.set_var_descriptors(Object::empty_var_descriptors());
@@ -1019,11 +1064,11 @@
   code.set_var_descriptors(var_descs);
 }
 
-void FlowGraphCompiler::FinalizeCatchEntryStateMap(const Code& code) {
-#if defined(DART_PRECOMPILED_RUNTIME) || defined(DART_PRECOMPILER)
+void FlowGraphCompiler::FinalizeCatchEntryMovesMap(const Code& code) {
+#if defined(DART_PRECOMPILER)
   TypedData& maps = TypedData::Handle(
-      catch_entry_state_maps_builder_->FinalizeCatchEntryStateMap());
-  code.set_catch_entry_state_maps(maps);
+      catch_entry_moves_maps_builder_->FinalizeCatchEntryMovesMap());
+  code.set_catch_entry_moves_maps(maps);
 #else
   code.set_variables(Smi::Handle(Smi::New(flow_graph().variable_count())));
 #endif
@@ -2223,7 +2268,7 @@
       (compiler->CurrentTryIndex() != CatchClauseNode::kInvalidTryIndex)) {
     Environment* env =
         compiler->SlowPathEnvironmentFor(instruction(), num_args_);
-    compiler->EmitCatchEntryState(env, try_index_);
+    compiler->RecordCatchEntryMoves(env, try_index_);
   }
   if (!use_shared_stub) {
     __ Breakpoint();
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler.h b/runtime/vm/compiler/backend/flow_graph_compiler.h
index 7baed3c..1df8a26 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler.h
+++ b/runtime/vm/compiler/backend/flow_graph_compiler.h
@@ -15,6 +15,7 @@
 namespace dart {
 
 // Forward declarations.
+class CatchEntryMovesMapBuilder;
 class Code;
 class DeoptInfoBuilder;
 class FlowGraph;
@@ -592,7 +593,7 @@
 
   void EmitEdgeCounter(intptr_t edge_id);
 #endif  // !defined(TARGET_ARCH_DBC)
-  void EmitCatchEntryState(
+  void RecordCatchEntryMoves(
       Environment* env = NULL,
       intptr_t try_index = CatchClauseNode::kInvalidTryIndex);
 
@@ -665,7 +666,7 @@
   RawArray* CreateDeoptInfo(Assembler* assembler);
   void FinalizeStackMaps(const Code& code);
   void FinalizeVarDescriptors(const Code& code);
-  void FinalizeCatchEntryStateMap(const Code& code);
+  void FinalizeCatchEntryMovesMap(const Code& code);
   void FinalizeStaticCallTargetsTable(const Code& code);
   void FinalizeCodeSourceMap(const Code& code);
 
@@ -953,7 +954,7 @@
   DescriptorList* pc_descriptors_list_;
   StackMapTableBuilder* stackmap_table_builder_;
   CodeSourceMapBuilder* code_source_map_builder_;
-  CatchEntryStateMapBuilder* catch_entry_state_maps_builder_;
+  CatchEntryMovesMapBuilder* catch_entry_moves_maps_builder_;
   GrowableArray<BlockInfo*> block_info_;
   GrowableArray<CompilerDeoptInfo*> deopt_infos_;
   GrowableArray<SlowPathCode*> slow_path_code_;
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler_arm.cc b/runtime/vm/compiler/backend/flow_graph_compiler_arm.cc
index cd5b029..6c3cb3a 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler_arm.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler_arm.cc
@@ -169,11 +169,8 @@
 
   ASSERT(deopt_env() != NULL);
 
-  // LR may be live. It will be clobbered by BranchLink, so cache it in IP.
-  // It will be restored at the top of the deoptimization stub, specifically in
-  // GenerateDeoptimizationSequence in stub_code_arm.cc.
   __ Push(CODE_REG);
-  __ mov(IP, Operand(LR));
+  ASSERT(kReservedCpuRegisters & (1 << LR));
   __ BranchLink(*StubCode::Deoptimize_entry());
   set_pc_offset(assembler->CodeSize());
 #undef __
@@ -907,6 +904,13 @@
     }
     EmitFrameEntry();
     ASSERT(__ constant_pool_allowed());
+  } else {
+    // For JIT we have multiple entrypoints functionality which moved the frame
+    // setup into the [TargetEntryInstr] (which will set the constant pool
+    // allowed bit to true).  Despite this we still have to set the
+    // constant pool allowed bit to true here as well, because we can generate
+    // code for [CatchEntryInstr]s, which need the pool.
+    __ set_constant_pool_allowed(true);
   }
 
   VisitBlocks();
@@ -1063,7 +1067,7 @@
     // arguments are removed.
     AddCurrentDescriptor(RawPcDescriptors::kDeopt, deopt_id_after, token_pos);
   }
-  EmitCatchEntryState(pending_deoptimization_env_, try_index);
+  RecordCatchEntryMoves(pending_deoptimization_env_, try_index);
   __ Drop(args_desc.CountWithTypeArgs());
 }
 
@@ -1112,7 +1116,7 @@
     Code::EntryKind entry_kind) {
   ASSERT(!function.IsClosureFunction());
   if (function.HasOptionalParameters() ||
-      (isolate()->reify_generic_functions() && function.IsGeneric())) {
+      (FLAG_reify_generic_functions && function.IsGeneric())) {
     __ LoadObject(R4, arguments_descriptor);
   } else {
     __ LoadImmediate(R4, 0);  // GC safe smi zero because of stub.
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler_arm64.cc b/runtime/vm/compiler/backend/flow_graph_compiler_arm64.cc
index 99af7c4..998842a 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler_arm64.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler_arm64.cc
@@ -1039,7 +1039,7 @@
     // arguments are removed.
     AddCurrentDescriptor(RawPcDescriptors::kDeopt, deopt_id_after, token_pos);
   }
-  EmitCatchEntryState(pending_deoptimization_env_, try_index);
+  RecordCatchEntryMoves(pending_deoptimization_env_, try_index);
   __ Drop(args_desc.CountWithTypeArgs());
 }
 
@@ -1051,12 +1051,21 @@
   const Code& initial_stub =
       Code::ZoneHandle(StubCode::ICCallThroughFunction_entry()->code());
 
+  auto& op = __ object_pool_wrapper();
+
   __ Comment("SwitchableCall");
   __ LoadFromOffset(R0, SP, (ic_data.CountWithoutTypeArgs() - 1) * kWordSize);
-  __ LoadUniqueObject(CODE_REG, initial_stub);
+
+  const intptr_t ic_data_index =
+      op.AddObject(ic_data, ObjectPool::Patchability::kPatchable);
+  const intptr_t initial_stub_index =
+      op.AddObject(initial_stub, ObjectPool::Patchability::kPatchable);
+  ASSERT((ic_data_index + 1) == initial_stub_index);
+
+  __ LoadDoubleWordFromPoolOffset(R5, CODE_REG,
+                                  ObjectPool::element_offset(ic_data_index));
   __ ldr(TMP, FieldAddress(CODE_REG, Code::entry_point_offset(
                                          Code::EntryKind::kMonomorphic)));
-  __ LoadUniqueObject(R5, ic_data);
   __ blr(TMP);
 
   EmitCallsiteMetadata(token_pos, DeoptId::kNone, RawPcDescriptors::kOther,
@@ -1088,7 +1097,7 @@
   // TODO(sjindel/entrypoints): Support multiple entrypoints on ARM64.
   ASSERT(!function.IsClosureFunction());
   if (function.HasOptionalParameters() ||
-      (isolate()->reify_generic_functions() && function.IsGeneric())) {
+      (FLAG_reify_generic_functions && function.IsGeneric())) {
     __ LoadObject(R4, arguments_descriptor);
   } else {
     __ LoadImmediate(R4, 0);  // GC safe smi zero because of stub.
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler_ia32.cc b/runtime/vm/compiler/backend/flow_graph_compiler_ia32.cc
index 41c287c..bfc712a 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler_ia32.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler_ia32.cc
@@ -979,7 +979,7 @@
     // arguments are removed.
     AddCurrentDescriptor(RawPcDescriptors::kDeopt, deopt_id_after, token_pos);
   }
-  EmitCatchEntryState(pending_deoptimization_env_, try_index);
+  RecordCatchEntryMoves(pending_deoptimization_env_, try_index);
   __ Drop(args_desc.CountWithTypeArgs());
 }
 
@@ -1001,7 +1001,7 @@
     Code::EntryKind entry_kind) {
   // TODO(sjindel/entrypoints): Support multiple entrypoints on IA32.
   if (function.HasOptionalParameters() ||
-      (isolate()->reify_generic_functions() && function.IsGeneric())) {
+      (FLAG_reify_generic_functions && function.IsGeneric())) {
     __ LoadObject(EDX, arguments_descriptor);
   } else {
     __ xorl(EDX, EDX);  // GC safe smi zero because of stub.
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler_x64.cc b/runtime/vm/compiler/backend/flow_graph_compiler_x64.cc
index 4542805..ae17719 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler_x64.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler_x64.cc
@@ -897,6 +897,13 @@
     }
     EmitFrameEntry();
     ASSERT(__ constant_pool_allowed());
+  } else {
+    // For JIT we have multiple entrypoints functionality which moved the frame
+    // setup into the [TargetEntryInstr] (which will set the constant pool
+    // allowed bit to true).  Despite this we still have to set the
+    // constant pool allowed bit to true here as well, because we can generate
+    // code for [CatchEntryInstr]s, which need the pool.
+    __ set_constant_pool_allowed(true);
   }
 
   ASSERT(!block_order().is_empty());
@@ -1055,7 +1062,7 @@
     // arguments are removed.
     AddCurrentDescriptor(RawPcDescriptors::kDeopt, deopt_id_after, token_pos);
   }
-  EmitCatchEntryState(pending_deoptimization_env_, try_index);
+  RecordCatchEntryMoves(pending_deoptimization_env_, try_index);
   __ Drop(args_desc.CountWithTypeArgs(), RCX);
 }
 
@@ -1089,7 +1096,7 @@
     Code::EntryKind entry_kind) {
   ASSERT(!function.IsClosureFunction());
   if (function.HasOptionalParameters() ||
-      (isolate()->reify_generic_functions() && function.IsGeneric())) {
+      (FLAG_reify_generic_functions && function.IsGeneric())) {
     __ LoadObject(R10, arguments_descriptor);
   } else {
     __ xorl(R10, R10);  // GC safe smi zero because of stub.
diff --git a/runtime/vm/compiler/backend/il.cc b/runtime/vm/compiler/backend/il.cc
index 145fc3d..63fc9df 100644
--- a/runtime/vm/compiler/backend/il.cc
+++ b/runtime/vm/compiler/backend/il.cc
@@ -45,7 +45,6 @@
             unbox_numeric_fields,
             !USING_DBC,
             "Support unboxed double and float32x4 fields.");
-DECLARE_FLAG(bool, eliminate_type_checks);
 
 class SubclassFinder {
  public:
@@ -780,17 +779,21 @@
   }
 }
 
-const NativeFieldDesc* NativeFieldDesc::GetTypeArgumentsFieldFor(
-    Zone* zone,
-    const Class& cls) {
+const NativeFieldDesc* NativeFieldDesc::GetTypeArgumentsField(Zone* zone,
+                                                              intptr_t offset) {
   // TODO(vegorov) consider caching type arguments fields for specific classes
   // in some sort of a flow-graph specific cache.
-  const intptr_t offset = cls.type_arguments_field_offset();
   ASSERT(offset != Class::kNoTypeArguments);
   return new (zone) NativeFieldDesc(kTypeArguments, offset, kDynamicCid,
                                     /*immutable=*/true);
 }
 
+const NativeFieldDesc* NativeFieldDesc::GetTypeArgumentsFieldFor(
+    Zone* zone,
+    const Class& cls) {
+  return GetTypeArgumentsField(zone, cls.type_arguments_field_offset());
+}
+
 RawAbstractType* NativeFieldDesc::type() const {
   if (cid() == kSmiCid) {
     return Type::SmiType();
@@ -1192,12 +1195,20 @@
   }
 }
 
-bool Value::NeedsStoreBuffer() {
+bool Value::NeedsWriteBarrier() {
   if (Type()->IsNull() || (Type()->ToNullableCid() == kSmiCid) ||
       (Type()->ToNullableCid() == kBoolCid)) {
     return false;
   }
 
+  // Strictly speaking, the incremental barrier can only be skipped for
+  // immediate objects (Smis) or permanent objects (vm-isolate heap or
+  // image pages). Here we choose to skip the barrier for any constant on
+  // the assumption it will remain reachable through the object pool.
+  // TODO(concurrent-marking): Consider ensuring marking is not in progress
+  // when code is disabled or only omitting the barrier if code collection
+  // is disabled.
+
   return !BindsToConstant();
 }
 
@@ -1226,7 +1237,10 @@
 }
 
 void Value::AddToList(Value* value, Value** list) {
+  ASSERT(value->next_use() == nullptr);
+  ASSERT(value->previous_use() == nullptr);
   Value* next = *list;
+  ASSERT(value != next);
   *list = value;
   value->set_next_use(next);
   value->set_previous_use(NULL);
@@ -2696,7 +2710,7 @@
 
     // In strong mode type is already verified either by static analysis
     // or runtime checks, so AssertBoolean just ensures that value is not null.
-    if (Isolate::Current()->strong() && !value()->Type()->is_nullable()) {
+    if (FLAG_strong && !value()->Type()->is_nullable()) {
       return value()->definition();
     }
   }
@@ -2817,19 +2831,8 @@
   return NULL;
 }
 
-static bool HasTryBlockUse(Value* use_list) {
-  for (Value::Iterator it(use_list); !it.Done(); it.Advance()) {
-    Value* use = it.Current();
-    if (use->instruction()->MayThrow() &&
-        use->instruction()->GetBlock()->InsideTryBlock()) {
-      return true;
-    }
-  }
-  return false;
-}
-
 Definition* BoxInstr::Canonicalize(FlowGraph* flow_graph) {
-  if ((input_use_list() == NULL) && !HasTryBlockUse(env_use_list())) {
+  if (input_use_list() == nullptr) {
     // Environments can accommodate any representation. No need to box.
     return value()->definition();
   }
@@ -2852,7 +2855,7 @@
 }
 
 Definition* BoxIntegerInstr::Canonicalize(FlowGraph* flow_graph) {
-  if ((input_use_list() == NULL) && !HasTryBlockUse(env_use_list())) {
+  if (input_use_list() == nullptr) {
     // Environments can accommodate any representation. No need to box.
     return value()->definition();
   }
@@ -3969,7 +3972,8 @@
   }
 
 #if !defined(TARGET_ARCH_DBC)
-  if (compiler->is_optimizing() && HasICData()) {
+  if ((compiler->is_optimizing() || FLAG_use_bytecode_compiler) &&
+      HasICData()) {
     ASSERT(HasICData());
     if (ic_data()->NumberOfUsedChecks() > 0) {
       const ICData& unary_ic_data =
diff --git a/runtime/vm/compiler/backend/il.h b/runtime/vm/compiler/backend/il.h
index 46cfc60..ca93a55 100644
--- a/runtime/vm/compiler/backend/il.h
+++ b/runtime/vm/compiler/backend/il.h
@@ -296,9 +296,9 @@
   // Assert if BindsToConstant() is false, otherwise returns the constant value.
   const Object& BoundConstant() const;
 
-  // Compile time constants, Bool, Smi and Nulls do not need to update
-  // the store buffer.
-  bool NeedsStoreBuffer();
+  // Return true if storing the value into a heap object requires applying the
+  // write barrier.
+  bool NeedsWriteBarrier();
 
   bool Equals(Value* other) const;
 
@@ -1708,10 +1708,10 @@
                        GraphEntryInstr* graph_entry,
                        const Array& handler_types,
                        intptr_t catch_try_index,
-                       const LocalVariable& exception_var,
-                       const LocalVariable& stacktrace_var,
                        bool needs_stacktrace,
                        intptr_t deopt_id,
+                       const LocalVariable* exception_var,
+                       const LocalVariable* stacktrace_var,
                        const LocalVariable* raw_exception_var,
                        const LocalVariable* raw_stacktrace_var)
       : BlockEntryInstr(block_id, try_index, deopt_id),
@@ -1739,8 +1739,8 @@
 
   GraphEntryInstr* graph_entry() const { return graph_entry_; }
 
-  const LocalVariable& exception_var() const { return exception_var_; }
-  const LocalVariable& stacktrace_var() const { return stacktrace_var_; }
+  const LocalVariable* exception_var() const { return exception_var_; }
+  const LocalVariable* stacktrace_var() const { return stacktrace_var_; }
 
   const LocalVariable* raw_exception_var() const { return raw_exception_var_; }
   const LocalVariable* raw_stacktrace_var() const {
@@ -1775,8 +1775,8 @@
   const Array& catch_handler_types_;
   const intptr_t catch_try_index_;
   GrowableArray<Definition*> initial_definitions_;
-  const LocalVariable& exception_var_;
-  const LocalVariable& stacktrace_var_;
+  const LocalVariable* exception_var_;
+  const LocalVariable* stacktrace_var_;
   const LocalVariable* raw_exception_var_;
   const LocalVariable* raw_stacktrace_var_;
   const bool needs_stacktrace_;
@@ -2993,6 +2993,7 @@
     ASSERT(!dst_type.IsNull());
     ASSERT(!dst_type.IsTypeRef());
     ASSERT(!dst_name.IsNull());
+    ASSERT(!FLAG_strong || !dst_type.IsDynamicType());
     SetInputAt(0, value);
     SetInputAt(1, instantiator_type_arguments);
     SetInputAt(2, function_type_arguments);
@@ -4216,7 +4217,13 @@
   intptr_t offset_in_bytes() const { return offset_in_bytes_; }
 
   bool ShouldEmitStoreBarrier() const {
-    return value()->NeedsStoreBuffer() &&
+    if (instance()->definition() == value()->definition()) {
+      // `x.slot = x` cannot create an old->new or old&marked->old&unmarked
+      // reference.
+      return false;
+    }
+
+    return value()->NeedsWriteBarrier() &&
            (emit_store_barrier_ == kEmitStoreBarrier);
   }
 
@@ -4251,7 +4258,7 @@
 
   Assembler::CanBeSmi CanValueBeSmi() const {
     Isolate* isolate = Isolate::Current();
-    if (isolate->type_checks() && !isolate->strong()) {
+    if (isolate->type_checks() && !FLAG_strong) {
       // Dart 1 sometimes places a store into a context before a parameter
       // type check.
       return Assembler::kValueCanBeSmi;
@@ -4424,7 +4431,7 @@
  private:
   Assembler::CanBeSmi CanValueBeSmi() const {
     Isolate* isolate = Isolate::Current();
-    if (isolate->type_checks() && !isolate->strong()) {
+    if (isolate->type_checks() && !FLAG_strong) {
       // Dart 1 sometimes places a store into a context before a parameter
       // type check.
       return Assembler::kValueCanBeSmi;
@@ -4667,7 +4674,13 @@
   bool aligned() const { return alignment_ == kAlignedAccess; }
 
   bool ShouldEmitStoreBarrier() const {
-    return value()->NeedsStoreBuffer() &&
+    if (array()->definition() == value()->definition()) {
+      // `x[slot] = x` cannot create an old->new or old&marked->old&unmarked
+      // reference.
+      return false;
+    }
+
+    return value()->NeedsWriteBarrier() &&
            (emit_store_barrier_ == kEmitStoreBarrier);
   }
 
@@ -4688,6 +4701,10 @@
   virtual bool HasUnknownSideEffects() const { return false; }
 
  private:
+  Assembler::CanBeSmi CanValueBeSmi() const {
+    return Assembler::kValueCanBeSmi;
+  }
+
   const StoreBarrierType emit_store_barrier_;
   const intptr_t index_scale_;
   const intptr_t class_id_;
@@ -5115,6 +5132,8 @@
 
   static const NativeFieldDesc* Get(Kind kind);
   static const NativeFieldDesc* GetLengthFieldForArrayCid(intptr_t array_cid);
+  static const NativeFieldDesc* GetTypeArgumentsField(Zone* zone,
+                                                      intptr_t offset);
   static const NativeFieldDesc* GetTypeArgumentsFieldFor(Zone* zone,
                                                          const Class& cls);
 
diff --git a/runtime/vm/compiler/backend/il_arm.cc b/runtime/vm/compiler/backend/il_arm.cc
index 2d80341..f84d17a 100644
--- a/runtime/vm/compiler/backend/il_arm.cc
+++ b/runtime/vm/compiler/backend/il_arm.cc
@@ -64,8 +64,7 @@
                 Temp<Register> temp)) {
   __ LoadObject(CODE_REG, instr->code());
   __ LeaveDartFrame();  // The arguments are still on the stack.
-  __ ldr(temp, FieldAddress(CODE_REG, Code::entry_point_offset()));
-  __ bx(temp);
+  __ Branch(FieldAddress(CODE_REG, Code::entry_point_offset()));
 
   // Even though the TailCallInstr will be the last instruction in a basic
   // block, the flow graph compiler will emit native code for other blocks after
@@ -501,7 +500,7 @@
     __ CompareObject(reg, Bool::False());
     __ b(&done, EQ);
   } else {
-    ASSERT(isolate->asserts() || isolate->strong());
+    ASSERT(isolate->asserts() || FLAG_strong);
     __ CompareObject(reg, Object::null_instance());
     __ b(&done, NE);
   }
@@ -937,9 +936,9 @@
   const Register result = locs()->out(0).reg();
 
   // All arguments are already @SP due to preceding PushArgument()s.
-  ASSERT(ArgumentCount() == function().NumParameters() +
-                                (function().IsGeneric() &&
-                                 Isolate::Current()->reify_generic_functions())
+  ASSERT(ArgumentCount() ==
+                 function().NumParameters() +
+                     (function().IsGeneric() && FLAG_reify_generic_functions)
              ? 1
              : 0);
 
@@ -1334,10 +1333,10 @@
         } else {
           const Register value = locs()->temp(1).reg();
           __ LoadWordUnaligned(value, address, TMP);
-          __ vmovsr(EvenSRegisterOf(dresult0), value);
+          __ vmovdr(dresult0, 0, value);
           __ AddImmediate(address, address, 4);
           __ LoadWordUnaligned(value, address, TMP);
-          __ vmovsr(OddSRegisterOf(dresult0), value);
+          __ vmovdr(dresult0, 1, value);
         }
         break;
       case kTypedDataFloat64x2ArrayCid:
@@ -1559,6 +1558,7 @@
       UNREACHABLE();
       return NULL;
   }
+
   return locs;
 }
 
@@ -1604,7 +1604,8 @@
     case kArrayCid:
       if (ShouldEmitStoreBarrier()) {
         const Register value = locs()->in(2).reg();
-        __ StoreIntoObject(array, element_address, value);
+        __ StoreIntoObject(array, element_address, value, CanValueBeSmi(),
+                           /*lr_reserved=*/!compiler->intrinsic_mode());
       } else if (locs()->in(2).IsConstant()) {
         const Object& constant = locs()->in(2).constant();
         __ StoreIntoObjectNoBarrier(array, element_address, constant);
@@ -2188,8 +2189,7 @@
                                                               bool opt) const {
   const intptr_t kNumInputs = 2;
   const intptr_t kNumTemps =
-      ((IsUnboxedStore() && opt) ? 2 : ((IsPotentialUnboxedStore()) ? 3 : 0)) +
-      (ShouldEmitStoreBarrier() ? 1 : 0);  // block LR for the store barrier
+      ((IsUnboxedStore() && opt) ? 2 : ((IsPotentialUnboxedStore()) ? 3 : 0));
   LocationSummary* summary = new (zone)
       LocationSummary(zone, kNumInputs, kNumTemps,
                       ((IsUnboxedStore() && opt && is_initialization()) ||
@@ -2210,12 +2210,15 @@
     summary->set_temp(2, opt ? Location::RequiresFpuRegister()
                              : Location::FpuRegisterLocation(Q1));
   } else {
+#if defined(CONCURRENT_MARKING)
+    summary->set_in(1, ShouldEmitStoreBarrier()
+                           ? Location::RequiresRegister()
+                           : Location::RegisterOrConstant(value()));
+#else
     summary->set_in(1, ShouldEmitStoreBarrier()
                            ? Location::WritableRegister()
                            : Location::RegisterOrConstant(value()));
-  }
-  if (ShouldEmitStoreBarrier()) {
-    summary->set_temp(kNumTemps - 1, Location::RegisterLocation(LR));
+#endif
   }
   return summary;
 }
@@ -2235,7 +2238,8 @@
   BoxAllocationSlowPath::Allocate(compiler, instruction, cls, box_reg, temp);
 
   __ MoveRegister(temp, box_reg);
-  __ StoreIntoObjectOffset(instance_reg, offset, temp);
+  __ StoreIntoObjectOffset(instance_reg, offset, temp,
+                           Assembler::kValueIsNotSmi);
   __ Bind(&done);
 }
 
@@ -2270,7 +2274,8 @@
 
       BoxAllocationSlowPath::Allocate(compiler, this, *cls, temp, temp2);
       __ MoveRegister(temp2, temp);
-      __ StoreIntoObjectOffset(instance_reg, offset_in_bytes_, temp2);
+      __ StoreIntoObjectOffset(instance_reg, offset_in_bytes_, temp2,
+                               Assembler::kValueIsNotSmi);
     } else {
       __ ldr(temp, FieldAddress(instance_reg, offset_in_bytes_));
     }
@@ -2416,10 +2421,16 @@
 
 LocationSummary* StoreStaticFieldInstr::MakeLocationSummary(Zone* zone,
                                                             bool opt) const {
-  LocationSummary* locs =
-      new (zone) LocationSummary(zone, 1, 1, LocationSummary::kNoCall);
-  locs->set_in(0, value()->NeedsStoreBuffer() ? Location::WritableRegister()
-                                              : Location::RequiresRegister());
+  const intptr_t kNumInputs = 1;
+  const intptr_t kNumTemps = 1;
+  LocationSummary* locs = new (zone)
+      LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
+#if defined(CONCURRENT_MARKING)
+  locs->set_in(0, Location::RequiresRegister());
+#else
+  locs->set_in(0, value()->NeedsWriteBarrier() ? Location::WritableRegister()
+                                               : Location::RequiresRegister());
+#endif
   locs->set_temp(0, Location::RequiresRegister());
   return locs;
 }
@@ -2429,9 +2440,10 @@
   const Register temp = locs()->temp(0).reg();
 
   __ LoadObject(temp, Field::ZoneHandle(Z, field().Original()));
-  if (this->value()->NeedsStoreBuffer()) {
+  if (this->value()->NeedsWriteBarrier()) {
     __ StoreIntoObject(temp, FieldAddress(temp, Field::static_value_offset()),
-                       value, CanValueBeSmi());
+                       value, CanValueBeSmi(),
+                       /*lr_reserved=*/!compiler->intrinsic_mode());
   } else {
     __ StoreIntoObjectNoBarrier(
         temp, FieldAddress(temp, Field::static_value_offset()), value);
@@ -3036,12 +3048,11 @@
               ? Thread::stack_overflow_shared_with_fpu_regs_entry_point_offset()
               : Thread::
                     stack_overflow_shared_without_fpu_regs_entry_point_offset();
-      ASSERT(instruction()->locs()->temp(1).IsRegister() &&
-             instruction()->locs()->temp(1).reg() == LR);
+      ASSERT(kReservedCpuRegisters & (1 << LR));
       __ ldr(LR, Address(THR, entry_point_offset));
       __ blx(LR);
       compiler->RecordSafepoint(instruction()->locs(), kNumSlowPathArgs);
-      compiler->EmitCatchEntryState();
+      compiler->RecordCatchEntryMoves();
       compiler->AddDescriptor(
           RawPcDescriptors::kOther, compiler->assembler()->CodeSize(),
           instruction()->deopt_id(), instruction()->token_pos(),
diff --git a/runtime/vm/compiler/backend/il_arm64.cc b/runtime/vm/compiler/backend/il_arm64.cc
index de564df..41fcd15 100644
--- a/runtime/vm/compiler/backend/il_arm64.cc
+++ b/runtime/vm/compiler/backend/il_arm64.cc
@@ -497,7 +497,7 @@
     __ CompareObject(reg, Bool::False());
     __ b(&done, EQ);
   } else {
-    ASSERT(isolate->asserts() || isolate->strong());
+    ASSERT(isolate->asserts() || FLAG_strong);
     __ CompareObject(reg, Object::null_instance());
     __ b(&done, NE);
   }
@@ -824,9 +824,9 @@
   const Register result = locs()->out(0).reg();
 
   // All arguments are already @SP due to preceding PushArgument()s.
-  ASSERT(ArgumentCount() == function().NumParameters() +
-                                (function().IsGeneric() &&
-                                 Isolate::Current()->reify_generic_functions())
+  ASSERT(ArgumentCount() ==
+                 function().NumParameters() +
+                     (function().IsGeneric() && FLAG_reify_generic_functions)
              ? 1
              : 0);
 
@@ -1141,7 +1141,6 @@
       (representation() == kUnboxedFloat64x2)) {
     const VRegister result = locs()->out(0).fpu_reg();
     switch (class_id()) {
-      ASSERT(aligned());
       case kTypedDataFloat32ArrayCid:
         // Load single precision float.
         if (aligned()) {
@@ -1440,7 +1439,8 @@
       ASSERT(aligned());
       if (ShouldEmitStoreBarrier()) {
         const Register value = locs()->in(2).reg();
-        __ StoreIntoObject(array, element_address, value);
+        __ StoreIntoObject(array, element_address, value, CanValueBeSmi(),
+                           /*lr_reserved=*/!compiler->intrinsic_mode());
       } else if (locs()->in(2).IsConstant()) {
         const Object& constant = locs()->in(2).constant();
         __ StoreIntoObjectNoBarrier(array, element_address, constant);
@@ -1861,7 +1861,7 @@
     compiler->SaveLiveRegisters(locs);
     compiler->GenerateCall(TokenPosition::kNoSource,  // No token position.
                            stub_entry, RawPcDescriptors::kOther, locs);
-    __ mov(result_, R0);
+    __ MoveRegister(result_, R0);
     compiler->RestoreLiveRegisters(locs);
     __ b(exit_label());
   }
@@ -1900,8 +1900,10 @@
   __ CompareObject(box_reg, Object::null_object());
   __ b(&done, NE);
   BoxAllocationSlowPath::Allocate(compiler, instruction, cls, box_reg, temp);
-  __ mov(temp, box_reg);
-  __ StoreIntoObjectOffset(instance_reg, offset, temp);
+  __ MoveRegister(temp, box_reg);
+  __ StoreIntoObjectOffset(instance_reg, offset, temp,
+                           Assembler::kValueIsNotSmi,
+                           /*lr_reserved=*/!compiler->intrinsic_mode());
   __ Bind(&done);
 }
 
@@ -1928,9 +1930,15 @@
     summary->set_temp(0, Location::RequiresRegister());
     summary->set_temp(1, Location::RequiresRegister());
   } else {
+#if defined(CONCURRENT_MARKING)
+    summary->set_in(1, ShouldEmitStoreBarrier()
+                           ? Location::RequiresRegister()
+                           : Location::RegisterOrConstant(value()));
+#else
     summary->set_in(1, ShouldEmitStoreBarrier()
                            ? Location::WritableRegister()
                            : Location::RegisterOrConstant(value()));
+#endif
   }
   return summary;
 }
@@ -1964,8 +1972,10 @@
       }
 
       BoxAllocationSlowPath::Allocate(compiler, this, *cls, temp, temp2);
-      __ mov(temp2, temp);
-      __ StoreIntoObjectOffset(instance_reg, offset_in_bytes_, temp2);
+      __ MoveRegister(temp2, temp);
+      __ StoreIntoObjectOffset(instance_reg, offset_in_bytes_, temp2,
+                               Assembler::kValueIsNotSmi,
+                               /*lr_reserved=*/!compiler->intrinsic_mode());
     } else {
       __ LoadFieldFromOffset(temp, instance_reg, offset_in_bytes_);
     }
@@ -2118,8 +2128,12 @@
                                                             bool opt) const {
   LocationSummary* locs =
       new (zone) LocationSummary(zone, 1, 1, LocationSummary::kNoCall);
-  locs->set_in(0, value()->NeedsStoreBuffer() ? Location::WritableRegister()
-                                              : Location::RequiresRegister());
+#if defined(CONCURRENT_MARKING)
+  locs->set_in(0, Location::RequiresRegister());
+#else
+  locs->set_in(0, value()->NeedsWriteBarrier() ? Location::WritableRegister()
+                                               : Location::RequiresRegister());
+#endif
   locs->set_temp(0, Location::RequiresRegister());
   return locs;
 }
@@ -2129,9 +2143,10 @@
   const Register temp = locs()->temp(0).reg();
 
   __ LoadObject(temp, Field::ZoneHandle(Z, field().Original()));
-  if (this->value()->NeedsStoreBuffer()) {
+  if (this->value()->NeedsWriteBarrier()) {
     __ StoreIntoObjectOffset(temp, Field::static_value_offset(), value,
-                             CanValueBeSmi());
+                             CanValueBeSmi(),
+                             /*lr_reserved=*/!compiler->intrinsic_mode());
   } else {
     __ StoreIntoObjectOffsetNoBarrier(temp, Field::static_value_offset(),
                                       value);
@@ -2736,7 +2751,7 @@
       __ ldr(LR, Address(THR, entry_point_offset));
       __ blr(LR);
       compiler->RecordSafepoint(instruction()->locs(), kNumSlowPathArgs);
-      compiler->EmitCatchEntryState();
+      compiler->RecordCatchEntryMoves();
       compiler->AddDescriptor(
           RawPcDescriptors::kOther, compiler->assembler()->CodeSize(),
           instruction()->deopt_id(), instruction()->token_pos(),
diff --git a/runtime/vm/compiler/backend/il_ia32.cc b/runtime/vm/compiler/backend/il_ia32.cc
index 18f3279..a0b36d6 100644
--- a/runtime/vm/compiler/backend/il_ia32.cc
+++ b/runtime/vm/compiler/backend/il_ia32.cc
@@ -320,7 +320,7 @@
     __ CompareObject(reg, Bool::False());
     __ j(EQUAL, &done, Assembler::kNearJump);
   } else {
-    ASSERT(isolate->asserts() || isolate->strong());
+    ASSERT(isolate->asserts() || FLAG_strong);
     __ CompareObject(reg, Object::null_instance());
     __ j(NOT_EQUAL, &done, Assembler::kNearJump);
   }
@@ -821,9 +821,9 @@
   const intptr_t argc_tag = NativeArguments::ComputeArgcTag(function());
 
   // All arguments are already @ESP due to preceding PushArgument()s.
-  ASSERT(ArgumentCount() == function().NumParameters() +
-                                (function().IsGeneric() &&
-                                 Isolate::Current()->reify_generic_functions())
+  ASSERT(ArgumentCount() ==
+                 function().NumParameters() +
+                     (function().IsGeneric() && FLAG_reify_generic_functions)
              ? 1
              : 0);
 
@@ -1345,7 +1345,7 @@
     case kArrayCid:
       if (ShouldEmitStoreBarrier()) {
         Register value = locs()->in(2).reg();
-        __ StoreIntoObject(array, element_address, value);
+        __ StoreIntoObject(array, element_address, value, CanValueBeSmi());
       } else if (locs()->in(2).IsConstant()) {
         const Object& constant = locs()->in(2).constant();
         __ StoreIntoObjectNoBarrier(array, element_address, constant);
@@ -1813,7 +1813,8 @@
   __ j(NOT_EQUAL, &done);
   BoxAllocationSlowPath::Allocate(compiler, instruction, cls, box_reg, temp);
   __ movl(temp, box_reg);
-  __ StoreIntoObject(instance_reg, FieldAddress(instance_reg, offset), temp);
+  __ StoreIntoObject(instance_reg, FieldAddress(instance_reg, offset), temp,
+                     Assembler::kValueIsNotSmi);
 
   __ Bind(&done);
 }
@@ -1849,7 +1850,8 @@
       BoxAllocationSlowPath::Allocate(compiler, this, *cls, temp, temp2);
       __ movl(temp2, temp);
       __ StoreIntoObject(instance_reg,
-                         FieldAddress(instance_reg, offset_in_bytes_), temp2);
+                         FieldAddress(instance_reg, offset_in_bytes_), temp2,
+                         Assembler::kValueIsNotSmi);
     } else {
       __ movl(temp, FieldAddress(instance_reg, offset_in_bytes_));
     }
@@ -1999,8 +2001,8 @@
                                                             bool opt) const {
   LocationSummary* locs =
       new (zone) LocationSummary(zone, 1, 1, LocationSummary::kNoCall);
-  locs->set_in(0, value()->NeedsStoreBuffer() ? Location::WritableRegister()
-                                              : Location::RequiresRegister());
+  locs->set_in(0, value()->NeedsWriteBarrier() ? Location::WritableRegister()
+                                               : Location::RequiresRegister());
   locs->set_temp(0, Location::RequiresRegister());
   return locs;
 }
@@ -2010,7 +2012,7 @@
   Register temp = locs()->temp(0).reg();
 
   __ LoadObject(temp, Field::ZoneHandle(Z, field().Original()));
-  if (this->value()->NeedsStoreBuffer()) {
+  if (this->value()->NeedsWriteBarrier()) {
     __ StoreIntoObject(temp, FieldAddress(temp, Field::static_value_offset()),
                        value, CanValueBeSmi());
   } else {
diff --git a/runtime/vm/compiler/backend/il_printer.cc b/runtime/vm/compiler/backend/il_printer.cc
index ed6af4d..233b45d 100644
--- a/runtime/vm/compiler/backend/il_printer.cc
+++ b/runtime/vm/compiler/backend/il_printer.cc
@@ -707,7 +707,7 @@
   instantiator_type_arguments()->PrintTo(f);
   f->Print("), function_type_args(");
   function_type_arguments()->PrintTo(f);
-  f->Print(")");
+  f->Print("), instantiator_class(%s)", instantiator_class().ToCString());
 }
 
 void AllocateContextInstr::PrintOperandsTo(BufferFormatter* f) const {
diff --git a/runtime/vm/compiler/backend/il_x64.cc b/runtime/vm/compiler/backend/il_x64.cc
index 313be83..f0cfb7b 100644
--- a/runtime/vm/compiler/backend/il_x64.cc
+++ b/runtime/vm/compiler/backend/il_x64.cc
@@ -473,7 +473,7 @@
     __ CompareObject(reg, Bool::False());
     __ j(EQUAL, &done, Assembler::kNearJump);
   } else {
-    ASSERT(isolate->asserts() || isolate->strong());
+    ASSERT(isolate->asserts() || FLAG_strong);
     __ CompareObject(reg, Object::null_instance());
     __ j(NOT_EQUAL, &done, Assembler::kNearJump);
   }
@@ -847,9 +847,9 @@
   const intptr_t argc_tag = NativeArguments::ComputeArgcTag(function());
 
   // All arguments are already @RSP due to preceding PushArgument()s.
-  ASSERT(ArgumentCount() == function().NumParameters() +
-                                (function().IsGeneric() &&
-                                 Isolate::Current()->reify_generic_functions())
+  ASSERT(ArgumentCount() ==
+                 function().NumParameters() +
+                     (function().IsGeneric() && FLAG_reify_generic_functions)
              ? 1
              : 0);
 
@@ -1467,7 +1467,7 @@
     case kArrayCid:
       if (ShouldEmitStoreBarrier()) {
         Register value = locs()->in(2).reg();
-        __ StoreIntoObject(array, element_address, value);
+        __ StoreIntoObject(array, element_address, value, CanValueBeSmi());
       } else if (locs()->in(2).IsConstant()) {
         const Object& constant = locs()->in(2).constant();
         __ StoreIntoObjectNoBarrier(array, element_address, constant);
@@ -1919,9 +1919,15 @@
     summary->set_temp(2, opt ? Location::RequiresFpuRegister()
                              : Location::FpuRegisterLocation(XMM1));
   } else {
+#if defined(CONCURRENT_MARKING)
+    summary->set_in(1, ShouldEmitStoreBarrier()
+                           ? Location::RequiresRegister()
+                           : Location::RegisterOrConstant(value()));
+#else
     summary->set_in(1, ShouldEmitStoreBarrier()
                            ? Location::WritableRegister()
                            : Location::RegisterOrConstant(value()));
+#endif
   }
   return summary;
 }
@@ -1939,7 +1945,8 @@
   __ j(NOT_EQUAL, &done);
   BoxAllocationSlowPath::Allocate(compiler, instruction, cls, box_reg, temp);
   __ movq(temp, box_reg);
-  __ StoreIntoObject(instance_reg, FieldAddress(instance_reg, offset), temp);
+  __ StoreIntoObject(instance_reg, FieldAddress(instance_reg, offset), temp,
+                     Assembler::kValueIsNotSmi);
 
   __ Bind(&done);
 }
@@ -1975,7 +1982,8 @@
       BoxAllocationSlowPath::Allocate(compiler, this, *cls, temp, temp2);
       __ movq(temp2, temp);
       __ StoreIntoObject(instance_reg,
-                         FieldAddress(instance_reg, offset_in_bytes_), temp2);
+                         FieldAddress(instance_reg, offset_in_bytes_), temp2,
+                         Assembler::kValueIsNotSmi);
     } else {
       __ movq(temp, FieldAddress(instance_reg, offset_in_bytes_));
     }
@@ -2121,8 +2129,12 @@
                                                             bool opt) const {
   LocationSummary* locs =
       new (zone) LocationSummary(zone, 1, 1, LocationSummary::kNoCall);
-  locs->set_in(0, value()->NeedsStoreBuffer() ? Location::WritableRegister()
-                                              : Location::RequiresRegister());
+#if defined(CONCURRENT_MARKING)
+  locs->set_in(0, Location::RequiresRegister());
+#else
+  locs->set_in(0, value()->NeedsWriteBarrier() ? Location::WritableRegister()
+                                               : Location::RequiresRegister());
+#endif
   locs->set_temp(0, Location::RequiresRegister());
   return locs;
 }
@@ -2132,7 +2144,7 @@
   Register temp = locs()->temp(0).reg();
 
   __ LoadObject(temp, Field::ZoneHandle(Z, field().Original()));
-  if (this->value()->NeedsStoreBuffer()) {
+  if (this->value()->NeedsWriteBarrier()) {
     __ StoreIntoObject(temp, FieldAddress(temp, Field::static_value_offset()),
                        value, CanValueBeSmi());
   } else {
@@ -2740,7 +2752,7 @@
                     stack_overflow_shared_without_fpu_regs_entry_point_offset();
       __ call(Address(THR, entry_point_offset));
       compiler->RecordSafepoint(instruction()->locs(), kNumSlowPathArgs);
-      compiler->EmitCatchEntryState();
+      compiler->RecordCatchEntryMoves();
       compiler->AddDescriptor(
           RawPcDescriptors::kOther, compiler->assembler()->CodeSize(),
           instruction()->deopt_id(), instruction()->token_pos(),
diff --git a/runtime/vm/compiler/backend/inliner.cc b/runtime/vm/compiler/backend/inliner.cc
index ccacbd2..2d35fbd 100644
--- a/runtime/vm/compiler/backend/inliner.cc
+++ b/runtime/vm/compiler/backend/inliner.cc
@@ -973,7 +973,7 @@
             entry_kind = instr->entry_kind();
           }
           kernel::FlowGraphBuilder builder(
-              parsed_function, *ic_data_array, /* not building var desc */ NULL,
+              parsed_function, ic_data_array, /* not building var desc */ NULL,
               exit_collector,
               /* optimized = */ true, Compiler::kNoOSRDeoptId,
               caller_graph_->max_block_id() + 1,
@@ -999,8 +999,14 @@
 #if defined(DART_PRECOMPILER) && !defined(TARGET_ARCH_DBC) &&                  \
     !defined(TARGET_ARCH_IA32)
         if (FLAG_precompiled_mode) {
-          Precompiler::PopulateWithICData(parsed_function->function(),
-                                          callee_graph);
+          callee_graph->PopulateWithICData(parsed_function->function());
+        }
+#else
+        // If we inline a function which is intrinsified without a fall-through
+        // to IR code, we will not have any ICData attached, so we do it
+        // manually here.
+        if (function.is_intrinsic()) {
+          callee_graph->PopulateWithICData(parsed_function->function());
         }
 #endif  // defined(DART_PRECOMPILER) && !defined(TARGET_ARCH_DBC) &&           \
     // !defined(TARGET_ARCH_IA32)
@@ -1011,8 +1017,7 @@
         // TODO(zerny): Put more information in the stubs, eg, type information.
         const intptr_t first_actual_param_index = call_data->first_arg_index;
         const intptr_t inlined_type_args_param =
-            (isolate->reify_generic_functions() && function.IsGeneric()) ? 1
-                                                                         : 0;
+            (FLAG_reify_generic_functions && function.IsGeneric()) ? 1 : 0;
         const intptr_t num_inlined_params =
             inlined_type_args_param + function.NumParameters();
         ZoneGrowableArray<Definition*>* param_stubs =
diff --git a/runtime/vm/compiler/backend/locations.cc b/runtime/vm/compiler/backend/locations.cc
index 22ea322..569be42 100644
--- a/runtime/vm/compiler/backend/locations.cc
+++ b/runtime/vm/compiler/backend/locations.cc
@@ -28,11 +28,7 @@
                                  intptr_t temp_count,
                                  LocationSummary::ContainsCall contains_call)
     : num_inputs_(input_count),
-#if defined(TARGET_ARCH_ARM)
-      num_temps_(temp_count + (contains_call == kCallOnSharedSlowPath ? 1 : 0)),
-#else
       num_temps_(temp_count),
-#endif
       stack_bitmap_(NULL),
       contains_call_(contains_call),
       live_registers_() {
@@ -41,14 +37,6 @@
 #endif
   input_locations_ = zone->Alloc<Location>(num_inputs_);
   temp_locations_ = zone->Alloc<Location>(num_temps_);
-
-#if defined(TARGET_ARCH_ARM)
-  if (contains_call == kCallOnSharedSlowPath) {
-    // TODO(sjindel): Mitigate the negative effect on the fast-path of blocking
-    // LR.
-    set_temp(temp_count, Location::RegisterLocation(LR));
-  }
-#endif
 }
 
 LocationSummary* LocationSummary::Make(
diff --git a/runtime/vm/compiler/backend/redundancy_elimination.cc b/runtime/vm/compiler/backend/redundancy_elimination.cc
index e74aaff..c734370 100644
--- a/runtime/vm/compiler/backend/redundancy_elimination.cc
+++ b/runtime/vm/compiler/backend/redundancy_elimination.cc
@@ -2569,6 +2569,16 @@
   }
 }
 
+//
+// Allocation Sinking
+//
+
+// Returns true if the given instruction is an allocation that
+// can be sunk by the Allocation Sinking pass.
+static bool IsSupportedAllocation(Instruction* instr) {
+  return instr->IsAllocateObject() || instr->IsAllocateUninitializedContext();
+}
+
 enum SafeUseCheck { kOptimisticCheck, kStrictCheck };
 
 // Check if the use is safe for allocation sinking. Allocation sinking
@@ -2600,7 +2610,7 @@
   if (store != NULL) {
     if (use == store->value()) {
       Definition* instance = store->instance()->definition();
-      return instance->IsAllocateObject() &&
+      return IsSupportedAllocation(instance) &&
              ((check_type == kOptimisticCheck) ||
               instance->Identity().IsAllocationSinkingCandidate());
     }
@@ -2683,22 +2693,15 @@
        !block_it.Done(); block_it.Advance()) {
     BlockEntryInstr* block = block_it.Current();
     for (ForwardInstructionIterator it(block); !it.Done(); it.Advance()) {
-      {
-        AllocateObjectInstr* alloc = it.Current()->AsAllocateObject();
-        if ((alloc != NULL) &&
-            IsAllocationSinkingCandidate(alloc, kOptimisticCheck)) {
-          alloc->SetIdentity(AliasIdentity::AllocationSinkingCandidate());
-          candidates_.Add(alloc);
-        }
+      Instruction* current = it.Current();
+      if (!IsSupportedAllocation(current)) {
+        continue;
       }
-      {
-        AllocateUninitializedContextInstr* alloc =
-            it.Current()->AsAllocateUninitializedContext();
-        if ((alloc != NULL) &&
-            IsAllocationSinkingCandidate(alloc, kOptimisticCheck)) {
-          alloc->SetIdentity(AliasIdentity::AllocationSinkingCandidate());
-          candidates_.Add(alloc);
-        }
+
+      Definition* alloc = current->Cast<Definition>();
+      if (IsAllocationSinkingCandidate(alloc, kOptimisticCheck)) {
+        alloc->SetIdentity(AliasIdentity::AllocationSinkingCandidate());
+        candidates_.Add(alloc);
       }
     }
   }
diff --git a/runtime/vm/compiler/backend/type_propagator.cc b/runtime/vm/compiler/backend/type_propagator.cc
index b5aaa95..67ac074 100644
--- a/runtime/vm/compiler/backend/type_propagator.cc
+++ b/runtime/vm/compiler/backend/type_propagator.cc
@@ -753,7 +753,7 @@
     Isolate* I = Isolate::Current();
     const Class& type_class = Class::Handle(I->class_table()->At(cid_));
     if (type_class.NumTypeArguments() > 0) {
-      if (I->strong()) {
+      if (FLAG_strong) {
         type_ = &AbstractType::ZoneHandle(type_class.RareType());
       } else {
         type_ = &Object::dynamic_type();
@@ -938,6 +938,12 @@
     return CompileType::Dynamic();
   }
 
+  if (FLAG_use_bytecode_compiler &&
+      graph_entry->parsed_function().node_sequence() == nullptr) {
+    // TODO(alexmarkov): Consider adding node_sequence() and scope.
+    return CompileType::Dynamic();
+  }
+
   // Parameter is the receiver.
   if ((index() == 0) &&
       (function.IsDynamicFunction() || function.IsGenerativeConstructor())) {
@@ -1189,7 +1195,7 @@
   }
 
   const Isolate* isolate = Isolate::Current();
-  if ((isolate->can_use_strong_mode_types()) || isolate->type_checks()) {
+  if (isolate->can_use_strong_mode_types() || isolate->type_checks()) {
     const AbstractType& result_type =
         AbstractType::ZoneHandle(function().result_type());
     // TODO(dartbug.com/30480): instantiate generic result_type if possible.
diff --git a/runtime/vm/compiler/call_specializer.cc b/runtime/vm/compiler/call_specializer.cc
index b119b07..75e6d4c 100644
--- a/runtime/vm/compiler/call_specializer.cc
+++ b/runtime/vm/compiler/call_specializer.cc
@@ -998,14 +998,12 @@
   }
 
   // Build an AssertAssignable if necessary.
-  if (I->argument_type_checks()) {
-    const AbstractType& dst_type =
-        AbstractType::ZoneHandle(zone(), field.type());
-
+  const AbstractType& dst_type = AbstractType::ZoneHandle(zone(), field.type());
+  if (I->argument_type_checks() && !dst_type.IsTopType()) {
     // Compute if we need to type check the value. Always type check if
     // not in strong mode or if at a dynamic invocation.
     bool needs_check = true;
-    if (I->strong() && !instr->interface_target().IsNull() &&
+    if (FLAG_strong && !instr->interface_target().IsNull() &&
         (field.kernel_offset() >= 0)) {
       bool is_covariant = false;
       bool is_generic_covariant = false;
diff --git a/runtime/vm/compiler/compiler_sources.gni b/runtime/vm/compiler/compiler_sources.gni
index a3f399d..9300603 100644
--- a/runtime/vm/compiler/compiler_sources.gni
+++ b/runtime/vm/compiler/compiler_sources.gni
@@ -78,6 +78,8 @@
   "compiler_state.h",
   "frontend/base_flow_graph_builder.cc",
   "frontend/base_flow_graph_builder.h",
+  "frontend/bytecode_flow_graph_builder.cc",
+  "frontend/bytecode_flow_graph_builder.h",
   "frontend/bytecode_reader.cc",
   "frontend/bytecode_reader.h",
   "frontend/constant_evaluator.cc",
diff --git a/runtime/vm/compiler/frontend/base_flow_graph_builder.cc b/runtime/vm/compiler/frontend/base_flow_graph_builder.cc
index 55e3531..af1c0c7 100644
--- a/runtime/vm/compiler/frontend/base_flow_graph_builder.cc
+++ b/runtime/vm/compiler/frontend/base_flow_graph_builder.cc
@@ -302,6 +302,14 @@
   }
 }
 
+Fragment BaseFlowGraphBuilder::LoadField(const Field& field) {
+  LoadFieldInstr* load = new (Z) LoadFieldInstr(
+      Pop(), &MayCloneField(field), AbstractType::ZoneHandle(Z, field.type()),
+      TokenPosition::kNoSource, parsed_function_);
+  Push(load);
+  return Fragment(load);
+}
+
 Fragment BaseFlowGraphBuilder::LoadField(intptr_t offset, intptr_t class_id) {
   LoadFieldInstr* load = new (Z) LoadFieldInstr(
       Pop(), offset, AbstractType::ZoneHandle(Z), TokenPosition::kNoSource);
@@ -495,14 +503,6 @@
   return variable;
 }
 
-intptr_t BaseFlowGraphBuilder::CurrentTryIndex() {
-  if (try_catch_block_ == NULL) {
-    return CatchClauseNode::kInvalidTryIndex;
-  } else {
-    return try_catch_block_->try_index();
-  }
-}
-
 void BaseFlowGraphBuilder::SetTempIndex(Definition* definition) {
   definition->set_temp_index(
       stack_ == NULL ? 0 : stack_->definition()->temp_index() + 1);
diff --git a/runtime/vm/compiler/frontend/base_flow_graph_builder.h b/runtime/vm/compiler/frontend/base_flow_graph_builder.h
index 190635c..28d4a4b 100644
--- a/runtime/vm/compiler/frontend/base_flow_graph_builder.h
+++ b/runtime/vm/compiler/frontend/base_flow_graph_builder.h
@@ -113,6 +113,7 @@
   BaseFlowGraphBuilder(
       const ParsedFunction* parsed_function,
       intptr_t last_used_block_id,
+      intptr_t osr_id = DeoptId::kNone,
       ZoneGrowableArray<intptr_t>* context_level_array = nullptr,
       InlineExitCollector* exit_collector = nullptr,
       bool inlining_unchecked_entry = false)
@@ -120,10 +121,11 @@
         function_(parsed_function_->function()),
         thread_(Thread::Current()),
         zone_(thread_->zone()),
+        osr_id_(osr_id),
         context_level_array_(context_level_array),
         context_depth_(0),
         last_used_block_id_(last_used_block_id),
-        try_catch_block_(NULL),
+        current_try_index_(CatchClauseNode::kInvalidTryIndex),
         next_used_try_index_(0),
         stack_(NULL),
         pending_argument_count_(0),
@@ -131,6 +133,7 @@
         exit_collector_(exit_collector),
         inlining_unchecked_entry_(inlining_unchecked_entry) {}
 
+  Fragment LoadField(const Field& field);
   Fragment LoadField(intptr_t offset, intptr_t class_id = kDynamicCid);
   Fragment LoadNativeField(const NativeFieldDesc* native_field);
   Fragment LoadIndexed(intptr_t index_scale);
@@ -230,6 +233,12 @@
   }
 
   intptr_t AllocateTryIndex() { return next_used_try_index_++; }
+  intptr_t CurrentTryIndex() const { return current_try_index_; }
+  void SetCurrentTryIndex(intptr_t try_index) {
+    current_try_index_ = try_index;
+  }
+
+  bool IsCompiledForOsr() { return osr_id_ != DeoptId::kNone; }
 
   bool IsInlining() const { return exit_collector_ != nullptr; }
 
@@ -263,20 +272,18 @@
 
  protected:
   intptr_t AllocateBlockId() { return ++last_used_block_id_; }
-  intptr_t CurrentTryIndex();
 
   const ParsedFunction* parsed_function_;
   const Function& function_;
   Thread* thread_;
   Zone* zone_;
+  intptr_t osr_id_;
   // Contains (deopt_id, context_level) pairs.
   ZoneGrowableArray<intptr_t>* context_level_array_;
   intptr_t context_depth_;
   intptr_t last_used_block_id_;
 
-  // A chained list of try-catch blocks. Chaining and lookup is done by the
-  // [TryCatchBlock] class.
-  TryCatchBlock* try_catch_block_;
+  intptr_t current_try_index_;
   intptr_t next_used_try_index_;
 
   Value* stack_;
@@ -286,36 +293,13 @@
 
   const bool inlining_unchecked_entry_;
 
-  friend class TryCatchBlock;
   friend class StreamingFlowGraphBuilder;
+  friend class BytecodeFlowGraphBuilder;
 
  private:
   DISALLOW_COPY_AND_ASSIGN(BaseFlowGraphBuilder);
 };
 
-class TryCatchBlock {
- public:
-  explicit TryCatchBlock(BaseFlowGraphBuilder* builder,
-                         intptr_t try_handler_index = -1)
-      : builder_(builder),
-        outer_(builder->try_catch_block_),
-        try_index_(try_handler_index) {
-    if (try_index_ == -1) try_index_ = builder->AllocateTryIndex();
-    builder->try_catch_block_ = this;
-  }
-  ~TryCatchBlock() { builder_->try_catch_block_ = outer_; }
-
-  intptr_t try_index() { return try_index_; }
-  TryCatchBlock* outer() const { return outer_; }
-
- private:
-  BaseFlowGraphBuilder* builder_;
-  TryCatchBlock* outer_;
-  intptr_t try_index_;
-
-  DISALLOW_COPY_AND_ASSIGN(TryCatchBlock);
-};
-
 }  // namespace kernel
 }  // namespace dart
 
diff --git a/runtime/vm/compiler/frontend/bytecode_flow_graph_builder.cc b/runtime/vm/compiler/frontend/bytecode_flow_graph_builder.cc
new file mode 100644
index 0000000..6cacf81
--- /dev/null
+++ b/runtime/vm/compiler/frontend/bytecode_flow_graph_builder.cc
@@ -0,0 +1,1380 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+#include "vm/compiler/frontend/bytecode_flow_graph_builder.h"
+
+#include "vm/compiler/backend/il_printer.h"
+#include "vm/compiler/frontend/prologue_builder.h"
+#include "vm/compiler/jit/compiler.h"
+#include "vm/object_store.h"
+#include "vm/stack_frame.h"
+#include "vm/stack_frame_kbc.h"
+
+#if !defined(DART_PRECOMPILED_RUNTIME)
+
+#define B (flow_graph_builder_)
+#define Z (zone_)
+
+namespace dart {
+
+DEFINE_FLAG(bool,
+            print_flow_graph_from_bytecode,
+            false,
+            "Print flow graph constructed from bytecode");
+
+namespace kernel {
+
+// 8-bit unsigned operand at bits 8-15.
+BytecodeFlowGraphBuilder::Operand BytecodeFlowGraphBuilder::DecodeOperandA() {
+  if (is_generating_interpreter()) {
+    UNIMPLEMENTED();  // TODO(alexmarkov): interpreter
+  } else {
+    intptr_t value = KernelBytecode::DecodeA(bytecode_instr_);
+    return Operand(value);
+  }
+}
+
+// 8-bit unsigned operand at bits 16-23.
+BytecodeFlowGraphBuilder::Operand BytecodeFlowGraphBuilder::DecodeOperandB() {
+  if (is_generating_interpreter()) {
+    UNIMPLEMENTED();  // TODO(alexmarkov): interpreter
+  } else {
+    intptr_t value = KernelBytecode::DecodeB(bytecode_instr_);
+    return Operand(value);
+  }
+}
+
+// 8-bit unsigned operand at bits 24-31.
+BytecodeFlowGraphBuilder::Operand BytecodeFlowGraphBuilder::DecodeOperandC() {
+  if (is_generating_interpreter()) {
+    UNIMPLEMENTED();  // TODO(alexmarkov): interpreter
+  } else {
+    intptr_t value = KernelBytecode::DecodeC(bytecode_instr_);
+    return Operand(value);
+  }
+}
+
+// 16-bit unsigned operand at bits 16-31.
+BytecodeFlowGraphBuilder::Operand BytecodeFlowGraphBuilder::DecodeOperandD() {
+  if (is_generating_interpreter()) {
+    UNIMPLEMENTED();  // TODO(alexmarkov): interpreter
+  } else {
+    intptr_t value = KernelBytecode::DecodeD(bytecode_instr_);
+    return Operand(value);
+  }
+}
+
+// 16-bit signed operand at bits 16-31.
+BytecodeFlowGraphBuilder::Operand BytecodeFlowGraphBuilder::DecodeOperandX() {
+  if (is_generating_interpreter()) {
+    UNIMPLEMENTED();  // TODO(alexmarkov): interpreter
+  } else {
+    intptr_t value = KernelBytecode::DecodeX(bytecode_instr_);
+    return Operand(value);
+  }
+}
+
+// 24-bit signed operand at bits 8-31.
+BytecodeFlowGraphBuilder::Operand BytecodeFlowGraphBuilder::DecodeOperandT() {
+  if (is_generating_interpreter()) {
+    UNIMPLEMENTED();  // TODO(alexmarkov): interpreter
+  } else {
+    intptr_t value = KernelBytecode::DecodeT(bytecode_instr_);
+    return Operand(value);
+  }
+}
+
+KBCInstr BytecodeFlowGraphBuilder::InstructionAt(
+    intptr_t pc,
+    KernelBytecode::Opcode expect_opcode) {
+  ASSERT(!is_generating_interpreter());
+  ASSERT((0 <= pc) && (pc < bytecode_length_));
+
+  const KBCInstr instr = raw_bytecode_[pc];
+  if (KernelBytecode::DecodeOpcode(instr) != expect_opcode) {
+    FATAL3("Expected bytecode instruction %s, but found %s at %" Pd "",
+           KernelBytecode::NameOf(KernelBytecode::Encode(expect_opcode)),
+           KernelBytecode::NameOf(instr), pc);
+  }
+
+  return instr;
+}
+
+BytecodeFlowGraphBuilder::Constant BytecodeFlowGraphBuilder::ConstantAt(
+    Operand entry_index,
+    intptr_t add_index) {
+  if (is_generating_interpreter()) {
+    UNIMPLEMENTED();  // TODO(alexmarkov): interpreter
+  } else {
+    const Object& value = Object::ZoneHandle(
+        Z, object_pool_.ObjectAt(entry_index.value() + add_index));
+    return Constant(Z, value);
+  }
+}
+
+void BytecodeFlowGraphBuilder::PushConstant(Constant constant) {
+  if (is_generating_interpreter()) {
+    B->Push(constant.definition());
+  } else {
+    code_ += B->Constant(constant.value());
+  }
+}
+
+BytecodeFlowGraphBuilder::Constant BytecodeFlowGraphBuilder::PopConstant() {
+  if (is_generating_interpreter()) {
+    UNIMPLEMENTED();  // TODO(alexmarkov): interpreter
+  } else {
+    const Object& value = B->stack_->definition()->AsConstant()->value();
+    code_ += B->Drop();
+    return Constant(Z, value);
+  }
+}
+
+void BytecodeFlowGraphBuilder::LoadStackSlots(intptr_t num_slots) {
+  if (B->stack_ != nullptr) {
+    intptr_t stack_depth = B->stack_->definition()->temp_index() + 1;
+    ASSERT(stack_depth >= num_slots);
+    return;
+  }
+
+  ASSERT(is_generating_interpreter());
+  UNIMPLEMENTED();  // TODO(alexmarkov): interpreter
+}
+
+void BytecodeFlowGraphBuilder::AllocateLocalVariables(
+    Operand frame_size,
+    intptr_t num_param_locals) {
+  if (is_generating_interpreter()) {
+    UNIMPLEMENTED();  // TODO(alexmarkov): interpreter
+  } else {
+    // TODO(alexmarkov): Make table of local variables in bytecode and
+    // propagate type, name and positions.
+
+    ASSERT(local_vars_.is_empty());
+
+    const intptr_t num_bytecode_locals = frame_size.value();
+    ASSERT(num_bytecode_locals >= 0);
+
+    intptr_t num_locals = num_bytecode_locals;
+    if (exception_var_ != nullptr) {
+      ++num_locals;
+    }
+    if (stacktrace_var_ != nullptr) {
+      ++num_locals;
+    }
+    if (parsed_function()->has_arg_desc_var()) {
+      ++num_locals;
+    }
+
+    if (num_locals == 0) {
+      return;
+    }
+
+    local_vars_.EnsureLength(num_bytecode_locals, nullptr);
+    for (intptr_t i = num_param_locals; i < num_bytecode_locals; ++i) {
+      String& name =
+          String::ZoneHandle(Z, Symbols::NewFormatted(thread(), "var%" Pd, i));
+      LocalVariable* local = new (Z)
+          LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource,
+                        name, Object::dynamic_type());
+      local->set_index(VariableIndex(-i));
+      local_vars_[i] = local;
+    }
+
+    intptr_t idx = num_bytecode_locals;
+    if (exception_var_ != nullptr) {
+      exception_var_->set_index(VariableIndex(-idx));
+      ++idx;
+    }
+    if (stacktrace_var_ != nullptr) {
+      stacktrace_var_->set_index(VariableIndex(-idx));
+      ++idx;
+    }
+    if (parsed_function()->has_arg_desc_var()) {
+      parsed_function()->arg_desc_var()->set_index(VariableIndex(-idx));
+      ++idx;
+    }
+    ASSERT(idx == num_locals);
+
+    ASSERT(parsed_function()->node_sequence() == nullptr);
+    parsed_function()->AllocateBytecodeVariables(num_locals);
+  }
+}
+
+LocalVariable* BytecodeFlowGraphBuilder::AllocateParameter(
+    intptr_t param_index,
+    VariableIndex var_index) {
+  const String& name =
+      String::ZoneHandle(Z, function().ParameterNameAt(param_index));
+  const AbstractType& type =
+      AbstractType::ZoneHandle(Z, function().ParameterTypeAt(param_index));
+
+  LocalVariable* param_var = new (Z) LocalVariable(
+      TokenPosition::kNoSource, TokenPosition::kNoSource, name, type);
+  param_var->set_index(var_index);
+
+  if (var_index.value() <= 0) {
+    local_vars_[-var_index.value()] = param_var;
+  }
+
+  return param_var;
+}
+
+void BytecodeFlowGraphBuilder::AllocateFixedParameters() {
+  if (is_generating_interpreter()) {
+    return;
+  }
+
+  ASSERT(!function().HasOptionalParameters());
+
+  const intptr_t num_fixed_params = function().num_fixed_parameters();
+  auto parameters =
+      new (Z) ZoneGrowableArray<LocalVariable*>(Z, num_fixed_params);
+
+  for (intptr_t i = 0; i < num_fixed_params; ++i) {
+    LocalVariable* param_var =
+        AllocateParameter(i, VariableIndex(num_fixed_params - i));
+    parameters->Add(param_var);
+  }
+
+  parsed_function()->SetRawParameters(parameters);
+}
+
+LocalVariable* BytecodeFlowGraphBuilder::LocalVariableAt(intptr_t local_index) {
+  ASSERT(!is_generating_interpreter());
+  if (local_index < 0) {
+    // Parameter
+    ASSERT(!function().HasOptionalParameters());
+    const intptr_t param_index = local_index +
+                                 function().num_fixed_parameters() +
+                                 kKBCParamEndSlotFromFp;
+    ASSERT((0 <= param_index) &&
+           (param_index < function().num_fixed_parameters()));
+    return parsed_function()->RawParameterVariable(param_index);
+  } else {
+    return local_vars_.At(local_index);
+  }
+}
+
+void BytecodeFlowGraphBuilder::StoreLocal(Operand local_index) {
+  if (is_generating_interpreter()) {
+    UNIMPLEMENTED();  // TODO(alexmarkov): interpreter
+  } else {
+    LocalVariable* local_var = LocalVariableAt(local_index.value());
+    code_ += B->StoreLocalRaw(position_, local_var);
+  }
+}
+
+void BytecodeFlowGraphBuilder::LoadLocal(Operand local_index) {
+  if (is_generating_interpreter()) {
+    UNIMPLEMENTED();  // TODO(alexmarkov): interpreter
+  } else {
+    LocalVariable* local_var = LocalVariableAt(local_index.value());
+    code_ += B->LoadLocal(local_var);
+  }
+}
+
+Value* BytecodeFlowGraphBuilder::Pop() {
+  LoadStackSlots(1);
+  return B->Pop();
+}
+
+ArgumentArray BytecodeFlowGraphBuilder::GetArguments(int count) {
+  ArgumentArray arguments =
+      new (Z) ZoneGrowableArray<PushArgumentInstr*>(Z, count);
+  arguments->SetLength(count);
+  for (intptr_t i = count - 1; i >= 0; --i) {
+    Definition* arg_def = B->stack_->definition();
+    ASSERT(!arg_def->HasSSATemp());
+    ASSERT(arg_def->temp_index() >= i);
+
+    PushArgumentInstr* argument = new (Z) PushArgumentInstr(Pop());
+
+    if (code_.current == arg_def) {
+      code_ <<= argument;
+    } else {
+      Instruction* next = arg_def->next();
+      ASSERT(next != nullptr);
+      arg_def->LinkTo(argument);
+      argument->LinkTo(next);
+    }
+
+    arguments->data()[i] = argument;
+  }
+  return arguments;
+}
+
+void BytecodeFlowGraphBuilder::PropagateStackState(intptr_t target_pc) {
+  if (is_generating_interpreter() || (B->stack_ == nullptr)) {
+    return;
+  }
+
+  // Stack state propagation is supported for forward branches only.
+  // Bytecode generation guarantees that expression stack is empty between
+  // statements and backward jumps are only used to transfer control between
+  // statements (e.g. in loop and continue statements).
+  RELEASE_ASSERT(target_pc > pc_);
+
+  Value* current_stack = B->stack_;
+  Value* target_stack = stack_states_.Lookup(target_pc);
+
+  if (target_stack != nullptr) {
+    // Control flow join should observe the same stack state from
+    // all incoming branches.
+    RELEASE_ASSERT(target_stack == current_stack);
+  } else {
+    stack_states_.Insert(target_pc, current_stack);
+  }
+}
+
+void BytecodeFlowGraphBuilder::BuildInstruction(KernelBytecode::Opcode opcode) {
+  switch (opcode) {
+#define BUILD_BYTECODE_CASE(bytecode)                                          \
+  case KernelBytecode::k##bytecode:                                            \
+    Build##bytecode();                                                         \
+    break;
+
+    FOR_EACH_BYTECODE_IN_FLOW_GRAPH_BUILDER(BUILD_BYTECODE_CASE)
+
+#undef BUILD_BYTECODE_CASE
+    default:
+      FATAL1("Unsupported bytecode instruction %s\n",
+             KernelBytecode::NameOf(bytecode_instr_));
+  }
+}
+
+void BytecodeFlowGraphBuilder::BuildEntry() {
+  AllocateLocalVariables(DecodeOperandD());
+  AllocateFixedParameters();
+}
+
+void BytecodeFlowGraphBuilder::BuildEntryFixed() {
+  if (is_generating_interpreter()) {
+    UNIMPLEMENTED();  // TODO(alexmarkov): interpreter
+  }
+
+  const intptr_t num_fixed_params = DecodeOperandA().value();
+  ASSERT(num_fixed_params == function().num_fixed_parameters());
+
+  AllocateLocalVariables(DecodeOperandD());
+  AllocateFixedParameters();
+
+  Fragment check_args;
+
+  ASSERT(throw_no_such_method_ == nullptr);
+  throw_no_such_method_ = B->BuildThrowNoSuchMethod();
+
+  check_args += B->LoadArgDescriptor();
+  check_args += B->LoadField(ArgumentsDescriptor::positional_count_offset());
+  check_args += B->IntConstant(num_fixed_params);
+  TargetEntryInstr *success1, *fail1;
+  check_args += B->BranchIfEqual(&success1, &fail1);
+  check_args = Fragment(check_args.entry, success1);
+
+  check_args += B->LoadArgDescriptor();
+  check_args += B->LoadField(ArgumentsDescriptor::count_offset());
+  check_args += B->IntConstant(num_fixed_params);
+  TargetEntryInstr *success2, *fail2;
+  check_args += B->BranchIfEqual(&success2, &fail2);
+  check_args = Fragment(check_args.entry, success2);
+
+  Fragment(fail1) + B->Goto(throw_no_such_method_);
+  Fragment(fail2) + B->Goto(throw_no_such_method_);
+
+  ASSERT(B->stack_ == nullptr);
+
+  if (!B->IsInlining() && !B->IsCompiledForOsr()) {
+    code_ += check_args;
+  }
+}
+
+void BytecodeFlowGraphBuilder::BuildEntryOptional() {
+  if (is_generating_interpreter()) {
+    UNIMPLEMENTED();  // TODO(alexmarkov): interpreter
+  }
+
+  const intptr_t num_fixed_params = DecodeOperandA().value();
+  const intptr_t num_opt_pos_params = DecodeOperandB().value();
+  const intptr_t num_opt_named_params = DecodeOperandC().value();
+  ASSERT(num_fixed_params == function().num_fixed_parameters());
+  ASSERT(num_opt_pos_params == function().NumOptionalPositionalParameters());
+  ASSERT(num_opt_named_params == function().NumOptionalNamedParameters());
+
+  ASSERT((num_opt_pos_params == 0) || (num_opt_named_params == 0));
+  const intptr_t num_load_const = num_opt_pos_params + 2 * num_opt_named_params;
+
+  const KBCInstr frame_instr =
+      InstructionAt(pc_ + 1 + num_load_const, KernelBytecode::kFrame);
+  const intptr_t num_temps = (num_opt_named_params > 0) ? 1 : 0;
+  const intptr_t num_extra_locals =
+      KernelBytecode::DecodeD(frame_instr) + num_temps;
+  const intptr_t num_params =
+      num_fixed_params + num_opt_pos_params + num_opt_named_params;
+  const intptr_t total_locals = num_params + num_extra_locals;
+
+  AllocateLocalVariables(Operand(total_locals), num_params);
+
+  ZoneGrowableArray<const Instance*>* default_values =
+      new (Z) ZoneGrowableArray<const Instance*>(
+          Z, num_opt_pos_params + num_opt_named_params);
+  ZoneGrowableArray<LocalVariable*>* raw_parameters =
+      new (Z) ZoneGrowableArray<LocalVariable*>(Z, num_params);
+  LocalVariable* temp_var = nullptr;
+
+  intptr_t param = 0;
+  for (; param < num_fixed_params; ++param) {
+    LocalVariable* param_var = AllocateParameter(param, VariableIndex(-param));
+    raw_parameters->Add(param_var);
+  }
+
+  for (intptr_t i = 0; i < num_opt_pos_params; ++i, ++param) {
+    const KBCInstr load_value_instr =
+        InstructionAt(pc_ + 1 + i, KernelBytecode::kLoadConstant);
+    const Object& default_value =
+        ConstantAt(Operand(KernelBytecode::DecodeD(load_value_instr))).value();
+    ASSERT(KernelBytecode::DecodeA(load_value_instr) == param);
+
+    LocalVariable* param_var = AllocateParameter(param, VariableIndex(-param));
+    raw_parameters->Add(param_var);
+    default_values->Add(
+        &Instance::ZoneHandle(Z, Instance::RawCast(default_value.raw())));
+  }
+
+  if (num_opt_named_params > 0) {
+    default_values->EnsureLength(num_opt_named_params, nullptr);
+    raw_parameters->EnsureLength(num_params, nullptr);
+    temp_var = LocalVariableAt(total_locals - 1);
+
+    for (intptr_t i = 0; i < num_opt_named_params; ++i, ++param) {
+      const KBCInstr load_name_instr =
+          InstructionAt(pc_ + 1 + i * 2, KernelBytecode::kLoadConstant);
+      const KBCInstr load_value_instr =
+          InstructionAt(pc_ + 1 + i * 2 + 1, KernelBytecode::kLoadConstant);
+      const String& param_name = String::Cast(
+          ConstantAt(Operand(KernelBytecode::DecodeD(load_name_instr)))
+              .value());
+      ASSERT(param_name.IsSymbol());
+      const Object& default_value =
+          ConstantAt(Operand(KernelBytecode::DecodeD(load_value_instr)))
+              .value();
+
+      intptr_t param_index = num_fixed_params;
+      for (; param_index < num_params; ++param_index) {
+        if (function().ParameterNameAt(param_index) == param_name.raw()) {
+          break;
+        }
+      }
+      ASSERT(param_index < num_params);
+
+      ASSERT(default_values->At(param_index - num_fixed_params) == nullptr);
+      (*default_values)[param_index - num_fixed_params] =
+          &Instance::ZoneHandle(Z, Instance::RawCast(default_value.raw()));
+
+      const intptr_t local_index = KernelBytecode::DecodeA(load_name_instr);
+      ASSERT(local_index == KernelBytecode::DecodeA(load_value_instr));
+
+      LocalVariable* param_var =
+          AllocateParameter(param_index, VariableIndex(-param));
+      ASSERT(raw_parameters->At(param_index) == nullptr);
+      (*raw_parameters)[param_index] = param_var;
+    }
+  }
+
+  parsed_function()->set_default_parameter_values(default_values);
+  parsed_function()->SetRawParameters(raw_parameters);
+
+  Fragment copy_args_prologue;
+
+  // Code generated for EntryOptional is considered a prologue code.
+  // Prologue should span a range of block ids, so start a new block at the
+  // beginning and end a block at the end.
+  JoinEntryInstr* prologue_entry = B->BuildJoinEntry();
+  copy_args_prologue += B->Goto(prologue_entry);
+  copy_args_prologue = Fragment(copy_args_prologue.entry, prologue_entry);
+
+  ASSERT(throw_no_such_method_ == nullptr);
+  throw_no_such_method_ = B->BuildThrowNoSuchMethod();
+
+  PrologueBuilder prologue_builder(parsed_function(), B->last_used_block_id_,
+                                   B->IsCompiledForOsr(), B->IsInlining());
+
+  B->last_used_block_id_ = prologue_builder.last_used_block_id();
+
+  copy_args_prologue += prologue_builder.BuildOptionalParameterHandling(
+      throw_no_such_method_, temp_var);
+
+  JoinEntryInstr* prologue_exit = B->BuildJoinEntry();
+  copy_args_prologue += B->Goto(prologue_exit);
+  copy_args_prologue.current = prologue_exit;
+
+  if (!B->IsInlining() && !B->IsCompiledForOsr()) {
+    code_ += copy_args_prologue;
+  }
+
+  prologue_info_ =
+      PrologueInfo(prologue_entry->block_id(), prologue_exit->block_id() - 1);
+
+  // Skip LoadConstant and Frame instructions.
+  pc_ += num_load_const + 1;
+
+  ASSERT(B->stack_ == nullptr);
+}
+
+void BytecodeFlowGraphBuilder::BuildLoadConstant() {
+  if (is_generating_interpreter()) {
+    UNIMPLEMENTED();  // TODO(alexmarkov): interpreter
+  }
+
+  // Handled in EntryOptional instruction.
+  UNREACHABLE();
+}
+
+void BytecodeFlowGraphBuilder::BuildFrame() {
+  if (is_generating_interpreter()) {
+    UNIMPLEMENTED();  // TODO(alexmarkov): interpreter
+  }
+
+  // Handled in EntryOptional instruction.
+  UNREACHABLE();
+}
+
+void BytecodeFlowGraphBuilder::BuildCheckFunctionTypeArgs() {
+  if (is_generating_interpreter()) {
+    UNIMPLEMENTED();  // TODO(alexmarkov): interpreter
+  }
+
+  const intptr_t expected_num_type_args = DecodeOperandA().value();
+  LocalVariable* type_args_var = LocalVariableAt(DecodeOperandD().value());
+  ASSERT(function().IsGeneric());
+
+  if (throw_no_such_method_ == nullptr) {
+    throw_no_such_method_ = B->BuildThrowNoSuchMethod();
+  }
+
+  Fragment setup_type_args;
+  JoinEntryInstr* done = B->BuildJoinEntry();
+
+  // Type args are always optional, so length can always be zero.
+  // If expect_type_args, a non-zero length must match the declaration length.
+  TargetEntryInstr *then, *fail;
+  setup_type_args += B->LoadArgDescriptor();
+  setup_type_args += B->LoadNativeField(NativeFieldDesc::Get(
+      NativeFieldDesc::kArgumentsDescriptor_type_args_len));
+
+  if (expected_num_type_args != 0) {
+    JoinEntryInstr* join2 = B->BuildJoinEntry();
+
+    LocalVariable* len = B->MakeTemporary();
+
+    TargetEntryInstr* otherwise;
+    setup_type_args += B->LoadLocal(len);
+    setup_type_args += B->IntConstant(0);
+    setup_type_args += B->BranchIfEqual(&then, &otherwise);
+
+    TargetEntryInstr* then2;
+    Fragment check_len(otherwise);
+    check_len += B->LoadLocal(len);
+    check_len += B->IntConstant(expected_num_type_args);
+    check_len += B->BranchIfEqual(&then2, &fail);
+
+    Fragment null_type_args(then);
+    null_type_args += B->NullConstant();
+    null_type_args += B->StoreLocalRaw(TokenPosition::kNoSource, type_args_var);
+    null_type_args += B->Drop();
+    null_type_args += B->Goto(join2);
+
+    Fragment store_type_args(then2);
+    store_type_args += B->LoadArgDescriptor();
+    store_type_args += B->LoadField(ArgumentsDescriptor::count_offset());
+    store_type_args += B->LoadFpRelativeSlot(
+        kWordSize * (1 + compiler_frame_layout.param_end_from_fp));
+    store_type_args +=
+        B->StoreLocalRaw(TokenPosition::kNoSource, type_args_var);
+    store_type_args += B->Drop();
+    store_type_args += B->Goto(join2);
+
+    Fragment(join2) + B->Drop() + B->Goto(done);
+    Fragment(fail) + B->Goto(throw_no_such_method_);
+  } else {
+    setup_type_args += B->IntConstant(0);
+    setup_type_args += B->BranchIfEqual(&then, &fail);
+    Fragment(then) + B->Goto(done);
+    Fragment(fail) + B->Goto(throw_no_such_method_);
+  }
+
+  setup_type_args = Fragment(setup_type_args.entry, done);
+  ASSERT(B->stack_ == nullptr);
+
+  if (expected_num_type_args != 0) {
+    parsed_function()->set_function_type_arguments(type_args_var);
+    parsed_function()->SetRawTypeArgumentsVariable(type_args_var);
+  }
+
+  if (!B->IsInlining() && !B->IsCompiledForOsr()) {
+    code_ += setup_type_args;
+  }
+}
+
+void BytecodeFlowGraphBuilder::BuildCheckStack() {
+  // TODO(alexmarkov): update B->loop_depth_
+  code_ += B->CheckStackOverflow(position_);
+  ASSERT(B->stack_ == nullptr);
+}
+
+void BytecodeFlowGraphBuilder::BuildPushConstant() {
+  PushConstant(ConstantAt(DecodeOperandD()));
+}
+
+void BytecodeFlowGraphBuilder::BuildPushNull() {
+  code_ += B->NullConstant();
+}
+
+void BytecodeFlowGraphBuilder::BuildPushTrue() {
+  code_ += B->Constant(Bool::True());
+}
+
+void BytecodeFlowGraphBuilder::BuildPushFalse() {
+  code_ += B->Constant(Bool::False());
+}
+
+void BytecodeFlowGraphBuilder::BuildPushInt() {
+  if (is_generating_interpreter()) {
+    UNIMPLEMENTED();  // TODO(alexmarkov): interpreter
+  }
+  code_ += B->IntConstant(DecodeOperandX().value());
+}
+
+void BytecodeFlowGraphBuilder::BuildStoreLocal() {
+  LoadStackSlots(1);
+  const Operand local_index = DecodeOperandX();
+  StoreLocal(local_index);
+}
+
+void BytecodeFlowGraphBuilder::BuildPopLocal() {
+  BuildStoreLocal();
+  code_ += B->Drop();
+}
+
+void BytecodeFlowGraphBuilder::BuildPush() {
+  const Operand local_index = DecodeOperandX();
+  LoadLocal(local_index);
+}
+
+void BytecodeFlowGraphBuilder::BuildIndirectStaticCall() {
+  if (is_generating_interpreter()) {
+    UNIMPLEMENTED();  // TODO(alexmarkov): interpreter
+  }
+
+  const ICData& icdata = ICData::Cast(PopConstant().value());
+
+  const Function& target = Function::ZoneHandle(Z, icdata.GetTargetAt(0));
+  const ArgumentsDescriptor arg_desc(
+      Array::Cast(ConstantAt(DecodeOperandD()).value()));
+  intptr_t argc = DecodeOperandA().value();
+  ASSERT(ic_data_array_->At(icdata.deopt_id())->Original() == icdata.raw());
+
+  ArgumentArray arguments = GetArguments(argc);
+
+  // TODO(alexmarkov): pass ICData::kSuper for super calls
+  // (need to distinguish them in bytecode).
+  StaticCallInstr* call = new (Z) StaticCallInstr(
+      position_, target, arg_desc.TypeArgsLen(),
+      Array::ZoneHandle(Z, arg_desc.GetArgumentNames()), arguments,
+      *ic_data_array_, icdata.deopt_id(), ICData::kStatic);
+
+  // TODO(alexmarkov): add type info
+  // SetResultTypeForStaticCall(call, target, argument_count, result_type);
+
+  code_ <<= call;
+  B->Push(call);
+}
+
+void BytecodeFlowGraphBuilder::BuildInstanceCall() {
+  if (is_generating_interpreter()) {
+    UNIMPLEMENTED();  // TODO(alexmarkov): interpreter
+  }
+
+  const ICData& icdata = ICData::Cast(ConstantAt(DecodeOperandD()).value());
+  ASSERT(ic_data_array_->At(icdata.deopt_id())->Original() == icdata.raw());
+
+  const intptr_t argc = DecodeOperandA().value();
+  const ArgumentsDescriptor arg_desc(
+      Array::Handle(Z, icdata.arguments_descriptor()));
+
+  const String& name = String::ZoneHandle(Z, icdata.target_name());
+  const Token::Kind token_kind =
+      MethodTokenRecognizer::RecognizeTokenKind(name);
+
+  const ArgumentArray arguments = GetArguments(argc);
+
+  // TODO(alexmarkov): store interface_target in bytecode and pass it here.
+
+  InstanceCallInstr* call = new (Z) InstanceCallInstr(
+      position_, name, token_kind, arguments, arg_desc.TypeArgsLen(),
+      Array::ZoneHandle(Z, arg_desc.GetArgumentNames()), icdata.NumArgsTested(),
+      *ic_data_array_, icdata.deopt_id());
+
+  ASSERT(call->ic_data() != nullptr);
+  ASSERT(call->ic_data()->Original() == icdata.raw());
+
+  // TODO(alexmarkov): add type info - call->SetResultType()
+
+  code_ <<= call;
+  B->Push(call);
+}
+
+void BytecodeFlowGraphBuilder::BuildNativeCall() {
+  if (is_generating_interpreter()) {
+    UNIMPLEMENTED();  // TODO(alexmarkov): interpreter
+  }
+
+  // Default flow graph builder is used to compile native methods.
+  UNREACHABLE();
+}
+
+void BytecodeFlowGraphBuilder::BuildAllocate() {
+  if (is_generating_interpreter()) {
+    UNIMPLEMENTED();  // TODO(alexmarkov): interpreter
+  }
+
+  const Class& klass = Class::Cast(ConstantAt(DecodeOperandD()).value());
+
+  const ArgumentArray arguments =
+      new (Z) ZoneGrowableArray<PushArgumentInstr*>(Z, 0);
+
+  AllocateObjectInstr* allocate =
+      new (Z) AllocateObjectInstr(position_, klass, arguments);
+
+  code_ <<= allocate;
+  B->Push(allocate);
+}
+
+void BytecodeFlowGraphBuilder::BuildAllocateT() {
+  if (is_generating_interpreter()) {
+    UNIMPLEMENTED();  // TODO(alexmarkov): interpreter
+  }
+
+  const Class& klass = Class::Cast(PopConstant().value());
+  const ArgumentArray arguments = GetArguments(1);
+
+  AllocateObjectInstr* allocate =
+      new (Z) AllocateObjectInstr(position_, klass, arguments);
+
+  code_ <<= allocate;
+  B->Push(allocate);
+}
+
+void BytecodeFlowGraphBuilder::BuildAllocateContext() {
+  if (is_generating_interpreter()) {
+    UNIMPLEMENTED();  // TODO(alexmarkov): interpreter
+  }
+
+  code_ += B->AllocateContext(DecodeOperandD().value());
+}
+
+void BytecodeFlowGraphBuilder::BuildCloneContext() {
+  LoadStackSlots(1);
+  // TODO(alexmarkov): Pass context_size and use it in compiled mode.
+  CloneContextInstr* clone_instruction = new (Z) CloneContextInstr(
+      TokenPosition::kNoSource, Pop(), CloneContextInstr::kUnknownContextSize,
+      B->GetNextDeoptId());
+  code_ <<= clone_instruction;
+  B->Push(clone_instruction);
+}
+
+void BytecodeFlowGraphBuilder::BuildCreateArrayTOS() {
+  LoadStackSlots(2);
+  code_ += B->CreateArray();
+}
+
+void BytecodeFlowGraphBuilder::BuildStoreFieldTOS() {
+  if (is_generating_interpreter()) {
+    UNIMPLEMENTED();  // TODO(alexmarkov): interpreter
+  }
+
+  LoadStackSlots(2);
+  Operand cp_index = DecodeOperandD();
+
+  const Field& field = Field::Cast(ConstantAt(cp_index, 1).value());
+  ASSERT(Smi::Cast(ConstantAt(cp_index).value()).Value() * kWordSize ==
+         field.Offset());
+
+  if (field.Owner() == isolate()->object_store()->closure_class()) {
+    // Stores to _Closure fields are lower-level.
+    // TODO(alexmarkov): use NativeFieldDesc
+    code_ += B->StoreInstanceField(position_, field.Offset());
+  } else {
+    // The rest of the StoreFieldTOS are for field initializers.
+    // TODO(alexmarkov): Consider adding a flag to StoreFieldTOS or even
+    // adding a separate bytecode instruction.
+    code_ += B->StoreInstanceFieldGuarded(field,
+                                          /* is_initialization_store = */ true);
+  }
+}
+
+void BytecodeFlowGraphBuilder::BuildLoadFieldTOS() {
+  if (is_generating_interpreter()) {
+    UNIMPLEMENTED();  // TODO(alexmarkov): interpreter
+  }
+
+  LoadStackSlots(1);
+  Operand cp_index = DecodeOperandD();
+
+  const Field& field = Field::Cast(ConstantAt(cp_index, 1).value());
+  ASSERT(Smi::Cast(ConstantAt(cp_index).value()).Value() * kWordSize ==
+         field.Offset());
+
+  if (field.Owner() == isolate()->object_store()->closure_class()) {
+    // Loads from _Closure fields are lower-level.
+    // TODO(alexmarkov): use NativeFieldDesc
+    code_ += B->LoadField(field.Offset());
+  } else {
+    code_ += B->LoadField(field);
+  }
+}
+
+void BytecodeFlowGraphBuilder::BuildStoreContextParent() {
+  LoadStackSlots(2);
+
+  // TODO(alexmarkov): use NativeFieldDesc
+  code_ += B->StoreInstanceField(position_, Context::parent_offset());
+}
+
+void BytecodeFlowGraphBuilder::BuildLoadContextParent() {
+  LoadStackSlots(1);
+
+  // TODO(alexmarkov): use NativeFieldDesc
+  code_ += B->LoadField(Context::parent_offset());
+}
+
+void BytecodeFlowGraphBuilder::BuildStoreContextVar() {
+  if (is_generating_interpreter()) {
+    UNIMPLEMENTED();  // TODO(alexmarkov): interpreter
+  }
+
+  LoadStackSlots(2);
+  Operand var_index = DecodeOperandD();
+
+  // TODO(alexmarkov): use NativeFieldDesc
+  code_ += B->StoreInstanceField(position_,
+                                 Context::variable_offset(var_index.value()));
+}
+
+void BytecodeFlowGraphBuilder::BuildLoadContextVar() {
+  if (is_generating_interpreter()) {
+    UNIMPLEMENTED();  // TODO(alexmarkov): interpreter
+  }
+
+  LoadStackSlots(1);
+  Operand var_index = DecodeOperandD();
+
+  // TODO(alexmarkov): use NativeFieldDesc
+  code_ += B->LoadField(Context::variable_offset(var_index.value()));
+}
+
+void BytecodeFlowGraphBuilder::BuildLoadTypeArgumentsField() {
+  if (is_generating_interpreter()) {
+    UNIMPLEMENTED();  // TODO(alexmarkov): interpreter
+  }
+
+  LoadStackSlots(1);
+  const intptr_t offset =
+      Smi::Cast(ConstantAt(DecodeOperandD()).value()).Value() * kWordSize;
+
+  code_ +=
+      B->LoadNativeField(NativeFieldDesc::GetTypeArgumentsField(Z, offset));
+}
+
+void BytecodeFlowGraphBuilder::BuildStoreStaticTOS() {
+  if (is_generating_interpreter()) {
+    UNIMPLEMENTED();  // TODO(alexmarkov): interpreter
+  }
+
+  LoadStackSlots(1);
+  Operand cp_index = DecodeOperandD();
+
+  const Field& field = Field::Cast(ConstantAt(cp_index).value());
+
+  code_ += B->StoreStaticField(position_, field);
+}
+
+void BytecodeFlowGraphBuilder::BuildPushStatic() {
+  // Note: Field object is both pushed into the stack and
+  // available in constant pool entry D.
+  // TODO(alexmarkov): clean this up. If we stop pushing field object
+  // explicitly, we might need the following code to get it from constant
+  // pool: PushConstant(ConstantAt(DecodeOperandD()));
+
+  code_ += B->LoadStaticField();
+}
+
+void BytecodeFlowGraphBuilder::BuildStoreIndexedTOS() {
+  LoadStackSlots(3);
+  code_ += B->StoreIndexed(kArrayCid);
+  code_ += B->Drop();
+}
+
+void BytecodeFlowGraphBuilder::BuildBooleanNegateTOS() {
+  LoadStackSlots(1);
+  code_ += B->BooleanNegate();
+}
+
+void BytecodeFlowGraphBuilder::BuildInstantiateType() {
+  if (is_generating_interpreter()) {
+    UNIMPLEMENTED();  // TODO(alexmarkov): interpreter
+  }
+
+  const AbstractType& type =
+      AbstractType::Cast(ConstantAt(DecodeOperandD()).value());
+
+  LoadStackSlots(2);
+  code_ += B->InstantiateType(type);
+}
+
+void BytecodeFlowGraphBuilder::BuildInstantiateTypeArgumentsTOS() {
+  if (is_generating_interpreter()) {
+    UNIMPLEMENTED();  // TODO(alexmarkov): interpreter
+  }
+
+  const TypeArguments& type_args =
+      TypeArguments::Cast(ConstantAt(DecodeOperandD()).value());
+
+  LoadStackSlots(2);
+  code_ += B->InstantiateTypeArguments(type_args);
+}
+
+void BytecodeFlowGraphBuilder::BuildAssertBoolean() {
+  LoadStackSlots(1);
+  code_ += B->AssertBool(position_);
+}
+
+void BytecodeFlowGraphBuilder::BuildAssertAssignable() {
+  if (is_generating_interpreter()) {
+    UNIMPLEMENTED();  // TODO(alexmarkov): interpreter
+  }
+
+  LoadStackSlots(5);
+
+  const String& dst_name = String::Cast(PopConstant().value());
+  const AbstractType& dst_type = AbstractType::Cast(PopConstant().value());
+
+  Value* function_type_args = Pop();
+  Value* instantiator_type_args = Pop();
+  Value* value = Pop();
+
+  AssertAssignableInstr* instr = new (Z) AssertAssignableInstr(
+      position_, value, instantiator_type_args, function_type_args, dst_type,
+      dst_name, B->GetNextDeoptId());
+
+  code_ <<= instr;
+
+  B->Push(instr);
+}
+
+void BytecodeFlowGraphBuilder::BuildAssertSubtype() {
+  if (is_generating_interpreter()) {
+    UNIMPLEMENTED();  // TODO(alexmarkov): interpreter
+  }
+
+  LoadStackSlots(5);
+
+  const String& dst_name = String::Cast(PopConstant().value());
+  const AbstractType& super_type = AbstractType::Cast(PopConstant().value());
+  const AbstractType& sub_type = AbstractType::Cast(PopConstant().value());
+  Value* function_type_args = Pop();
+  Value* instantiator_type_args = Pop();
+
+  AssertSubtypeInstr* instr = new (Z)
+      AssertSubtypeInstr(position_, instantiator_type_args, function_type_args,
+                         sub_type, super_type, dst_name, B->GetNextDeoptId());
+  code_ <<= instr;
+}
+
+void BytecodeFlowGraphBuilder::BuildJump() {
+  if (is_generating_interpreter()) {
+    UNIMPLEMENTED();  // TODO(alexmarkov): interpreter
+  }
+
+  const intptr_t target_pc = pc_ + DecodeOperandT().value();
+  JoinEntryInstr* join = jump_targets_.Lookup(target_pc);
+  ASSERT(join != nullptr);
+  code_ += B->Goto(join);
+  PropagateStackState(target_pc);
+  B->stack_ = nullptr;
+}
+
+void BytecodeFlowGraphBuilder::BuildJumpIfNoAsserts() {
+  if (!isolate()->asserts()) {
+    BuildJump();
+  }
+}
+
+void BytecodeFlowGraphBuilder::BuildJumpIfNotZeroTypeArgs() {
+  if (is_generating_interpreter()) {
+    UNIMPLEMENTED();  // TODO(alexmarkov): interpreter
+  }
+
+  TargetEntryInstr *is_zero, *is_not_zero;
+  code_ += B->LoadArgDescriptor();
+  code_ += B->LoadNativeField(NativeFieldDesc::Get(
+      NativeFieldDesc::kArgumentsDescriptor_type_args_len));
+  code_ += B->IntConstant(0);
+  code_ += B->BranchIfEqual(&is_zero, &is_not_zero);
+
+  const intptr_t target_pc = pc_ + DecodeOperandT().value();
+  JoinEntryInstr* join = jump_targets_.Lookup(target_pc);
+  ASSERT(join != nullptr);
+  Fragment(is_not_zero) += B->Goto(join);
+  PropagateStackState(target_pc);
+
+  code_ = Fragment(code_.entry, is_zero);
+}
+
+void BytecodeFlowGraphBuilder::BuildIfStrictCompare(Token::Kind cmp_kind) {
+  ASSERT((cmp_kind == Token::kEQ) || (cmp_kind == Token::kNE));
+
+  // TODO(alexmarkov): revise If* bytecodes to include Jump
+  // (and maybe comparison to true/false)
+
+  if (is_generating_interpreter()) {
+    UNIMPLEMENTED();  // TODO(alexmarkov): interpreter
+  }
+
+  LoadStackSlots(2);
+
+  TargetEntryInstr* eq_branch = nullptr;
+  TargetEntryInstr* ne_branch = nullptr;
+  code_ += B->BranchIfStrictEqual(&eq_branch, &ne_branch);
+
+  TargetEntryInstr* then_entry =
+      (cmp_kind == Token::kEQ) ? eq_branch : ne_branch;
+  TargetEntryInstr* else_entry =
+      (cmp_kind == Token::kEQ) ? ne_branch : eq_branch;
+
+  // The next bytecode instruction should be a Jump.
+  ++pc_;
+  bytecode_instr_ = InstructionAt(pc_, KernelBytecode::kJump);
+  ASSERT(jump_targets_.Lookup(pc_) == nullptr);
+
+  const intptr_t target_pc = pc_ + DecodeOperandT().value();
+  JoinEntryInstr* join = jump_targets_.Lookup(target_pc);
+  ASSERT(join != nullptr);
+
+  code_ = Fragment(then_entry);
+  code_ += B->Goto(join);
+  PropagateStackState(target_pc);
+
+  code_ = Fragment(else_entry);
+}
+
+void BytecodeFlowGraphBuilder::BuildIfEqStrictTOS() {
+  BuildIfStrictCompare(Token::kEQ);
+}
+
+void BytecodeFlowGraphBuilder::BuildIfNeStrictTOS() {
+  BuildIfStrictCompare(Token::kNE);
+}
+
+void BytecodeFlowGraphBuilder::BuildIfEqNull() {
+  LoadLocal(DecodeOperandA());
+  code_ += B->NullConstant();
+  BuildIfEqStrictTOS();
+}
+
+void BytecodeFlowGraphBuilder::BuildDrop1() {
+  if (is_generating_interpreter()) {
+    UNIMPLEMENTED();  // TODO(alexmarkov): interpreter
+    // AdjustSP(-1);
+  } else {
+    code_ += B->Drop();
+  }
+}
+
+void BytecodeFlowGraphBuilder::BuildReturnTOS() {
+  LoadStackSlots(1);
+  ASSERT(code_.is_open());
+  code_ += B->Return(position_);
+}
+
+void BytecodeFlowGraphBuilder::BuildTrap() {
+  code_ += Fragment(new (Z) StopInstr("Bytecode Trap instruction")).closed();
+}
+
+void BytecodeFlowGraphBuilder::BuildThrow() {
+  if (is_generating_interpreter()) {
+    UNIMPLEMENTED();  // TODO(alexmarkov): interpreter
+  }
+
+  if (DecodeOperandA().value() == 0) {
+    // throw
+    LoadStackSlots(1);
+    code_ += B->PushArgument();
+    code_ += B->ThrowException(position_);
+  } else {
+    // rethrow
+    LoadStackSlots(2);
+    GetArguments(2);
+    code_ += Fragment(new (Z) ReThrowInstr(position_,
+                                           CatchClauseNode::kInvalidTryIndex,
+                                           B->GetNextDeoptId()))
+                 .closed();
+  }
+
+  ASSERT(code_.is_closed());
+
+  // Empty stack as closed fragment should not leave any values on the stack.
+  while (B->stack_ != nullptr) {
+    B->Pop();
+  }
+}
+
+void BytecodeFlowGraphBuilder::BuildMoveSpecial() {
+  if (is_generating_interpreter()) {
+    UNIMPLEMENTED();  // TODO(alexmarkov): interpreter
+  }
+
+  LocalVariable* special_var = nullptr;
+  switch (DecodeOperandD().value()) {
+    // TODO(alexmarkov): Move these constants to constants_kbc.h
+    case KernelBytecode::kExceptionSpecialIndex:
+      ASSERT(exception_var_ != nullptr);
+      special_var = exception_var_;
+      break;
+    case KernelBytecode::kStackTraceSpecialIndex:
+      ASSERT(stacktrace_var_ != nullptr);
+      special_var = stacktrace_var_;
+      break;
+    default:
+      UNREACHABLE();
+  }
+
+  code_ += B->LoadLocal(special_var);
+  StoreLocal(DecodeOperandA());
+  code_ += B->Drop();
+}
+
+void BytecodeFlowGraphBuilder::BuildSetFrame() {
+  if (is_generating_interpreter()) {
+    UNIMPLEMENTED();  // TODO(alexmarkov): interpreter
+  }
+
+  // No-op in compiled code.
+  ASSERT(B->stack_ == nullptr);
+}
+
+static bool IsICDataEntry(const ObjectPool& object_pool, intptr_t index) {
+  if (object_pool.TypeAt(index) != ObjectPool::kTaggedObject) {
+    return false;
+  }
+  RawObject* entry = object_pool.ObjectAt(index);
+  return entry->IsHeapObject() && entry->IsICData();
+}
+
+// Read ICData entries in object pool, skip deopt_ids and
+// pre-populate ic_data_array_.
+void BytecodeFlowGraphBuilder::ProcessICDataInObjectPool(
+    const ObjectPool& object_pool) {
+  CompilerState& compiler_state = thread()->compiler_state();
+  ASSERT(compiler_state.deopt_id() == 0);
+
+  const intptr_t pool_length = object_pool.Length();
+  for (intptr_t i = 0; i < pool_length; ++i) {
+    if (IsICDataEntry(object_pool, i)) {
+      const ICData& icdata = ICData::CheckedHandle(Z, object_pool.ObjectAt(i));
+      const intptr_t deopt_id = compiler_state.GetNextDeoptId();
+
+      ASSERT(icdata.deopt_id() == deopt_id);
+      ASSERT(ic_data_array_->is_empty() ||
+             (ic_data_array_->At(deopt_id)->Original() == icdata.raw()));
+    }
+  }
+
+  if (ic_data_array_->is_empty()) {
+    const intptr_t len = compiler_state.deopt_id();
+    ic_data_array_->EnsureLength(len, nullptr);
+    for (intptr_t i = 0; i < pool_length; ++i) {
+      if (IsICDataEntry(object_pool, i)) {
+        const ICData& icdata =
+            ICData::CheckedHandle(Z, object_pool.ObjectAt(i));
+        (*ic_data_array_)[icdata.deopt_id()] = &icdata;
+      }
+    }
+  }
+}
+
+intptr_t BytecodeFlowGraphBuilder::GetTryIndex(const PcDescriptors& descriptors,
+                                               intptr_t pc) {
+  const uword pc_offset =
+      KernelBytecode::BytecodePcToOffset(pc, /* is_return_address = */ true);
+  PcDescriptors::Iterator iter(descriptors, RawPcDescriptors::kAnyKind);
+  intptr_t try_index = CatchClauseNode::kInvalidTryIndex;
+  while (iter.MoveNext()) {
+    const intptr_t current_try_index = iter.TryIndex();
+    const uword start_pc = iter.PcOffset();
+    if (pc_offset < start_pc) {
+      break;
+    }
+    const bool has_next = iter.MoveNext();
+    ASSERT(has_next);
+    const uword end_pc = iter.PcOffset();
+    if (start_pc <= pc_offset && pc_offset < end_pc) {
+      ASSERT(try_index < current_try_index);
+      try_index = current_try_index;
+    }
+  }
+  return try_index;
+}
+
+JoinEntryInstr* BytecodeFlowGraphBuilder::EnsureControlFlowJoin(
+    const PcDescriptors& descriptors,
+    intptr_t pc) {
+  ASSERT((0 <= pc) && (pc < bytecode_length_));
+  JoinEntryInstr* join = jump_targets_.Lookup(pc);
+  if (join == nullptr) {
+    join = B->BuildJoinEntry(GetTryIndex(descriptors, pc));
+    jump_targets_.Insert(pc, join);
+  }
+  return join;
+}
+
+void BytecodeFlowGraphBuilder::CollectControlFlow(
+    const PcDescriptors& descriptors,
+    const ExceptionHandlers& handlers,
+    GraphEntryInstr* graph_entry) {
+  for (intptr_t pc = 0; pc < bytecode_length_; ++pc) {
+    const KBCInstr instr = raw_bytecode_[pc];
+    const KernelBytecode::Opcode opcode = KernelBytecode::DecodeOpcode(instr);
+
+    if ((opcode == KernelBytecode::kJump) ||
+        (opcode == KernelBytecode::kJumpIfNoAsserts) ||
+        (opcode == KernelBytecode::kJumpIfNotZeroTypeArgs)) {
+      const intptr_t target = pc + KernelBytecode::DecodeT(instr);
+      EnsureControlFlowJoin(descriptors, target);
+    }
+  }
+
+  PcDescriptors::Iterator iter(descriptors, RawPcDescriptors::kAnyKind);
+  while (iter.MoveNext()) {
+    const intptr_t start_pc = KernelBytecode::OffsetToBytecodePc(
+        iter.PcOffset(), /* is_return_address = */ true);
+    EnsureControlFlowJoin(descriptors, start_pc);
+
+    const bool has_next = iter.MoveNext();
+    ASSERT(has_next);
+    const intptr_t end_pc = KernelBytecode::OffsetToBytecodePc(
+        iter.PcOffset(), /* is_return_address = */ true);
+    EnsureControlFlowJoin(descriptors, end_pc);
+  }
+
+  if (handlers.num_entries() > 0) {
+    B->InlineBailout("kernel::BytecodeFlowGraphBuilder::CollectControlFlow");
+
+    exception_var_ = new (Z)
+        LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource,
+                      Symbols::ExceptionVar(), Object::dynamic_type());
+    stacktrace_var_ = new (Z)
+        LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource,
+                      Symbols::StackTraceVar(), Object::dynamic_type());
+  }
+
+  for (intptr_t try_index = 0; try_index < handlers.num_entries();
+       ++try_index) {
+    ExceptionHandlerInfo handler_info;
+    handlers.GetHandlerInfo(try_index, &handler_info);
+
+    const intptr_t handler_pc = KernelBytecode::OffsetToBytecodePc(
+        handler_info.handler_pc_offset, /* is_return_address = */ false);
+    JoinEntryInstr* join = EnsureControlFlowJoin(descriptors, handler_pc);
+
+    const Array& handler_types =
+        Array::ZoneHandle(Z, handlers.GetHandledTypes(try_index));
+
+    CatchBlockEntryInstr* entry = new (Z) CatchBlockEntryInstr(
+        TokenPosition::kNoSource, handler_info.is_generated,
+        B->AllocateBlockId(), handler_info.outer_try_index, graph_entry,
+        handler_types, try_index, handler_info.needs_stacktrace,
+        B->GetNextDeoptId(), nullptr, nullptr, exception_var_, stacktrace_var_);
+    graph_entry->AddCatchEntry(entry);
+
+    code_ = Fragment(entry);
+    code_ += B->Goto(join);
+  }
+}
+
+FlowGraph* BytecodeFlowGraphBuilder::BuildGraph() {
+  if (function().is_native()) {
+    // Use default flow graph builder for native methods.
+    return nullptr;
+  }
+
+  const Code& bytecode = Code::Handle(Z, function().Bytecode());
+
+  object_pool_ = bytecode.object_pool();
+  raw_bytecode_ = reinterpret_cast<KBCInstr*>(bytecode.EntryPoint());
+  bytecode_length_ = bytecode.Size() / sizeof(KBCInstr);
+
+  ProcessICDataInObjectPool(object_pool_);
+
+  TargetEntryInstr* normal_entry = B->BuildTargetEntry();
+  GraphEntryInstr* graph_entry =
+      new (Z) GraphEntryInstr(*parsed_function_, normal_entry, B->osr_id_);
+
+  const PcDescriptors& descriptors =
+      PcDescriptors::Handle(Z, bytecode.pc_descriptors());
+  const ExceptionHandlers& handlers =
+      ExceptionHandlers::Handle(Z, bytecode.exception_handlers());
+
+  CollectControlFlow(descriptors, handlers, graph_entry);
+
+  code_ = Fragment(normal_entry);
+
+  for (pc_ = 0; pc_ < bytecode_length_; ++pc_) {
+    bytecode_instr_ = raw_bytecode_[pc_];
+
+    JoinEntryInstr* join = jump_targets_.Lookup(pc_);
+    if (join != nullptr) {
+      Value* stack_state = stack_states_.Lookup(pc_);
+      if (code_.is_open()) {
+        ASSERT((stack_state == nullptr) || (stack_state == B->stack_));
+        code_ += B->Goto(join);
+      } else {
+        ASSERT(B->stack_ == nullptr);
+        B->stack_ = stack_state;
+      }
+      code_ = Fragment(join);
+      B->SetCurrentTryIndex(join->try_index());
+    } else if (code_.is_closed()) {
+      // Skip unreachable bytecode instructions.
+      continue;
+    }
+
+    BuildInstruction(KernelBytecode::DecodeOpcode(bytecode_instr_));
+
+    if (code_.is_closed()) {
+      ASSERT(B->stack_ == nullptr);
+    }
+  }
+
+  // When compiling for OSR, use a depth first search to find the OSR
+  // entry and make graph entry jump to it instead of normal entry.
+  // Catch entries are always considered reachable, even if they
+  // become unreachable after OSR.
+  if (B->IsCompiledForOsr()) {
+    graph_entry->RelinkToOsrEntry(Z, B->last_used_block_id_ + 1);
+  }
+
+  FlowGraph* flow_graph = new (Z) FlowGraph(
+      *parsed_function_, graph_entry, B->last_used_block_id_, prologue_info_);
+
+  if (FLAG_print_flow_graph_from_bytecode) {
+    FlowGraphPrinter::PrintGraph("Constructed from bytecode", flow_graph);
+  }
+
+  return flow_graph;
+}
+
+}  // namespace kernel
+}  // namespace dart
+
+#endif  // !defined(DART_PRECOMPILED_RUNTIME)
diff --git a/runtime/vm/compiler/frontend/bytecode_flow_graph_builder.h b/runtime/vm/compiler/frontend/bytecode_flow_graph_builder.h
new file mode 100644
index 0000000..7de8c02
--- /dev/null
+++ b/runtime/vm/compiler/frontend/bytecode_flow_graph_builder.h
@@ -0,0 +1,238 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+#ifndef RUNTIME_VM_COMPILER_FRONTEND_BYTECODE_FLOW_GRAPH_BUILDER_H_
+#define RUNTIME_VM_COMPILER_FRONTEND_BYTECODE_FLOW_GRAPH_BUILDER_H_
+
+#include "vm/compiler/backend/il.h"
+#include "vm/compiler/frontend/base_flow_graph_builder.h"
+#include "vm/constants_kbc.h"
+
+#if !defined(DART_PRECOMPILED_RUNTIME)
+
+namespace dart {
+namespace kernel {
+
+#define FOR_EACH_BYTECODE_IN_FLOW_GRAPH_BUILDER(M)                             \
+  M(Allocate)                                                                  \
+  M(AllocateContext)                                                           \
+  M(AllocateT)                                                                 \
+  M(AssertAssignable)                                                          \
+  M(AssertBoolean)                                                             \
+  M(AssertSubtype)                                                             \
+  M(BooleanNegateTOS)                                                          \
+  M(CheckFunctionTypeArgs)                                                     \
+  M(CheckStack)                                                                \
+  M(CloneContext)                                                              \
+  M(CreateArrayTOS)                                                            \
+  M(Drop1)                                                                     \
+  M(Entry)                                                                     \
+  M(EntryFixed)                                                                \
+  M(EntryOptional)                                                             \
+  M(Frame)                                                                     \
+  M(IfEqNull)                                                                  \
+  M(IfEqStrictTOS)                                                             \
+  M(IfNeStrictTOS)                                                             \
+  M(IndirectStaticCall)                                                        \
+  M(InstanceCall)                                                              \
+  M(InstantiateType)                                                           \
+  M(InstantiateTypeArgumentsTOS)                                               \
+  M(Jump)                                                                      \
+  M(JumpIfNoAsserts)                                                           \
+  M(JumpIfNotZeroTypeArgs)                                                     \
+  M(LoadConstant)                                                              \
+  M(LoadContextParent)                                                         \
+  M(LoadContextVar)                                                            \
+  M(LoadFieldTOS)                                                              \
+  M(LoadTypeArgumentsField)                                                    \
+  M(MoveSpecial)                                                               \
+  M(NativeCall)                                                                \
+  M(PopLocal)                                                                  \
+  M(Push)                                                                      \
+  M(PushConstant)                                                              \
+  M(PushFalse)                                                                 \
+  M(PushInt)                                                                   \
+  M(PushNull)                                                                  \
+  M(PushStatic)                                                                \
+  M(PushTrue)                                                                  \
+  M(ReturnTOS)                                                                 \
+  M(SetFrame)                                                                  \
+  M(StoreContextParent)                                                        \
+  M(StoreContextVar)                                                           \
+  M(StoreFieldTOS)                                                             \
+  M(StoreIndexedTOS)                                                           \
+  M(StoreLocal)                                                                \
+  M(StoreStaticTOS)                                                            \
+  M(Throw)                                                                     \
+  M(Trap)
+
+// This class builds flow graph from bytecode. It is used either to compile
+// from bytecode, or generate bytecode interpreter (the latter is not
+// fully implemented yet).
+// TODO(alexmarkov): extend this class and IL to generate an interpreter in
+// addition to compiling bytecode.
+class BytecodeFlowGraphBuilder {
+ public:
+  BytecodeFlowGraphBuilder(BaseFlowGraphBuilder* flow_graph_builder,
+                           ParsedFunction* parsed_function,
+                           ZoneGrowableArray<const ICData*>* ic_data_array)
+      : flow_graph_builder_(flow_graph_builder),
+        zone_(flow_graph_builder->zone_),
+        is_generating_interpreter_(
+            false),  // TODO(alexmarkov): pass as argument
+        parsed_function_(parsed_function),
+        ic_data_array_(ic_data_array),
+        object_pool_(ObjectPool::Handle(zone_)),
+        raw_bytecode_(nullptr),
+        bytecode_length_(0),
+        pc_(0),
+        bytecode_instr_(KernelBytecode::kTrap),
+        position_(TokenPosition::kNoSource),
+        local_vars_(zone_, 0),
+        parameters_(zone_, 0),
+        exception_var_(nullptr),
+        stacktrace_var_(nullptr),
+        prologue_info_(-1, -1),
+        throw_no_such_method_(nullptr) {}
+
+  FlowGraph* BuildGraph();
+
+ protected:
+  // Returns `true` if building a flow graph for a bytecode interpreter, or
+  // `false` if compiling a function from bytecode.
+  bool is_generating_interpreter() const { return is_generating_interpreter_; }
+
+ private:
+  // Operand of bytecode instruction, either intptr_t value (if compiling
+  // bytecode) or Definition (if generating interpreter).
+  class Operand {
+   public:
+    explicit Operand(Definition* definition)
+        : definition_(definition), value_(0) {
+      ASSERT(definition != nullptr);
+    }
+
+    explicit Operand(intptr_t value) : definition_(nullptr), value_(value) {}
+
+    Definition* definition() const {
+      ASSERT(definition_ != nullptr);
+      return definition_;
+    }
+
+    intptr_t value() const {
+      ASSERT(definition_ == nullptr);
+      return value_;
+    }
+
+   private:
+    Definition* definition_;
+    intptr_t value_;
+  };
+
+  // Constant from a constant pool.
+  // It is either Object (if compiling bytecode) or Definition
+  // (if generating interpreter).
+  class Constant {
+   public:
+    explicit Constant(Definition* definition)
+        : definition_(definition), value_(Object::null_object()) {
+      ASSERT(definition != nullptr);
+    }
+
+    explicit Constant(Zone* zone, const Object& value)
+        : definition_(nullptr), value_(value) {}
+
+    Definition* definition() const {
+      ASSERT(definition_ != nullptr);
+      return definition_;
+    }
+
+    const Object& value() const {
+      ASSERT(definition_ == nullptr);
+      return value_;
+    }
+
+   private:
+    Definition* definition_;
+    const Object& value_;
+  };
+
+  Operand DecodeOperandA();
+  Operand DecodeOperandB();
+  Operand DecodeOperandC();
+  Operand DecodeOperandD();
+  Operand DecodeOperandX();
+  Operand DecodeOperandT();
+  KBCInstr InstructionAt(intptr_t pc, KernelBytecode::Opcode expect_opcode);
+  Constant ConstantAt(Operand entry_index, intptr_t add_index = 0);
+  void PushConstant(Constant constant);
+  Constant PopConstant();
+  void LoadStackSlots(intptr_t num_slots);
+  void AllocateLocalVariables(Operand frame_size,
+                              intptr_t num_param_locals = 0);
+  LocalVariable* AllocateParameter(intptr_t param_index,
+                                   VariableIndex var_index);
+  void AllocateFixedParameters();
+  LocalVariable* LocalVariableAt(intptr_t local_index);
+  void StoreLocal(Operand local_index);
+  void LoadLocal(Operand local_index);
+  Value* Pop();
+  ArgumentArray GetArguments(int count);
+  void PropagateStackState(intptr_t target_pc);
+  void BuildIfStrictCompare(Token::Kind cmp_kind);
+
+  void BuildInstruction(KernelBytecode::Opcode opcode);
+
+#define DECLARE_BUILD_METHOD(bytecode) void Build##bytecode();
+
+  FOR_EACH_BYTECODE_IN_FLOW_GRAPH_BUILDER(DECLARE_BUILD_METHOD)
+#undef DECLARE_BUILD_METHOD
+
+  void ProcessICDataInObjectPool(const ObjectPool& object_pool);
+  intptr_t GetTryIndex(const PcDescriptors& descriptors, intptr_t pc);
+  JoinEntryInstr* EnsureControlFlowJoin(const PcDescriptors& descriptors,
+                                        intptr_t pc);
+  void CollectControlFlow(const PcDescriptors& descriptors,
+                          const ExceptionHandlers& handlers,
+                          GraphEntryInstr* graph_entry);
+
+  Thread* thread() const { return flow_graph_builder_->thread_; }
+  Isolate* isolate() const { return thread()->isolate(); }
+
+  ParsedFunction* parsed_function() {
+    ASSERT(!is_generating_interpreter());
+    return parsed_function_;
+  }
+  const Function& function() { return parsed_function()->function(); }
+
+  BaseFlowGraphBuilder* flow_graph_builder_;
+  Zone* zone_;
+  bool is_generating_interpreter_;
+
+  // The following members are available only when compiling bytecode.
+
+  ParsedFunction* parsed_function_;
+  ZoneGrowableArray<const ICData*>* ic_data_array_;
+  ObjectPool& object_pool_;
+  KBCInstr* raw_bytecode_;
+  intptr_t bytecode_length_;
+  intptr_t pc_;
+  KBCInstr bytecode_instr_;
+  TokenPosition position_;  // TODO(alexmarkov): Set/update.
+  Fragment code_;
+  ZoneGrowableArray<LocalVariable*> local_vars_;
+  ZoneGrowableArray<LocalVariable*> parameters_;
+  LocalVariable* exception_var_;
+  LocalVariable* stacktrace_var_;
+  IntMap<JoinEntryInstr*> jump_targets_;
+  IntMap<Value*> stack_states_;
+  PrologueInfo prologue_info_;
+  JoinEntryInstr* throw_no_such_method_;
+};
+
+}  // namespace kernel
+}  // namespace dart
+
+#endif  // !defined(DART_PRECOMPILED_RUNTIME)
+#endif  // RUNTIME_VM_COMPILER_FRONTEND_BYTECODE_FLOW_GRAPH_BUILDER_H_
diff --git a/runtime/vm/compiler/frontend/bytecode_reader.cc b/runtime/vm/compiler/frontend/bytecode_reader.cc
index 3f244f7..bac50ed 100644
--- a/runtime/vm/compiler/frontend/bytecode_reader.cc
+++ b/runtime/vm/compiler/frontend/bytecode_reader.cc
@@ -10,10 +10,10 @@
 #include "vm/compiler/assembler/disassembler_kbc.h"
 #include "vm/constants_kbc.h"
 #include "vm/dart_entry.h"
+#include "vm/object_store.h"
 #include "vm/timeline.h"
 
 #if !defined(DART_PRECOMPILED_RUNTIME)
-#if defined(DART_USE_INTERPRETER)
 
 #define Z (zone_)
 #define H (translation_helper_)
@@ -52,7 +52,16 @@
   const intptr_t obj_count = helper_->reader_.ReadListLength();
   const ObjectPool& pool =
       ObjectPool::Handle(helper_->zone_, ObjectPool::New(obj_count));
-  ReadPoolEntries(function, function, pool, 0);
+
+  {
+    // While reading pool entries, deopt_ids are allocated for
+    // ICData objects.
+    //
+    // TODO(alexmarkov): allocate deopt_ids for closures separately
+    DeoptIdScope deopt_id_scope(H.thread(), 0);
+
+    ReadPoolEntries(function, function, pool, 0);
+  }
 
   // Read bytecode and attach to function.
   const Code& bytecode = Code::Handle(helper_->zone_, ReadBytecode(pool));
@@ -124,6 +133,7 @@
     kSubtypeTestCache,
     kPartialTearOffInstantiation,
     kEmptyTypeArguments,
+    kSymbol,
   };
 
   enum InvocationKind {
@@ -132,13 +142,19 @@
     setter   // x.foo = ...
   };
 
+  const int kInvocationKindMask = 0x3;
+  const int kFlagDynamic = 1 << 2;
+
   Object& obj = Object::Handle(helper_->zone_);
   Object& elem = Object::Handle(helper_->zone_);
   Array& array = Array::Handle(helper_->zone_);
   Field& field = Field::Handle(helper_->zone_);
   Class& cls = Class::Handle(helper_->zone_);
+  Library& lib = Library::Handle(helper_->zone_);
   String& name = String::Handle(helper_->zone_);
   TypeArguments& type_args = TypeArguments::Handle(helper_->zone_);
+  Class* symbol_class = nullptr;
+  Field* symbol_name_field = nullptr;
   const intptr_t obj_count = pool.Length();
   for (intptr_t i = from_index; i < obj_count; ++i) {
     const intptr_t tag = helper_->ReadTag();
@@ -157,14 +173,16 @@
         uint32_t low_bits = helper_->ReadUInt32();
         int64_t value = helper_->ReadUInt32();
         value = (value << 32) | low_bits;
-        obj = Integer::New(value);
+        obj = Integer::New(value, Heap::kOld);
+        obj = H.Canonicalize(Integer::Cast(obj));
       } break;
       case ConstantPoolTag::kDouble: {
         uint32_t low_bits = helper_->ReadUInt32();
         uint64_t bits = helper_->ReadUInt32();
         bits = (bits << 32) | low_bits;
         double value = bit_cast<double, uint64_t>(bits);
-        obj = Double::New(value);
+        obj = Double::New(value, Heap::kOld);
+        obj = H.Canonicalize(Double::Cast(obj));
       } break;
       case ConstantPoolTag::kBool:
         if (helper_->ReadUInt() == 1) {
@@ -188,7 +206,10 @@
         }
       } break;
       case ConstantPoolTag::kICData: {
-        InvocationKind kind = static_cast<InvocationKind>(helper_->ReadByte());
+        intptr_t flags = helper_->ReadByte();
+        InvocationKind kind =
+            static_cast<InvocationKind>(flags & kInvocationKindMask);
+        bool isDynamic = (flags & kFlagDynamic) != 0;
         if (kind == InvocationKind::getter) {
           name = helper_->ReadNameAsGetterName().raw();
         } else if (kind == InvocationKind::setter) {
@@ -208,10 +229,22 @@
           ASSERT(argument_count <= 2);
           checked_argument_count = argument_count;
         }
-        obj = ICData::New(function, name,
-                          array,  // Arguments descriptor.
-                          DeoptId::kNone, checked_argument_count,
-                          ICData::RebindRule::kInstance);
+        // Do not mangle == or call:
+        //   * operator == takes an Object so its either not checked or checked
+        //     at the entry because the parameter is marked covariant, neither
+        //     of those cases require a dynamic invocation forwarder;
+        //   * we assume that all closures are entered in a checked way.
+        if (isDynamic && (kind != InvocationKind::getter) &&
+            !FLAG_precompiled_mode && I->should_emit_strong_mode_checks() &&
+            (name.raw() != Symbols::EqualOperator().raw()) &&
+            (name.raw() != Symbols::Call().raw())) {
+          name = Function::CreateDynamicInvocationForwarderName(name);
+        }
+        obj =
+            ICData::New(function, name,
+                        array,  // Arguments descriptor.
+                        H.thread()->compiler_state().GetNextDeoptId(),
+                        checked_argument_count, ICData::RebindRule::kInstance);
 #if defined(TAG_IC_DATA)
         ICData::Cast(obj).set_tag(ICData::Tag::kInstanceCall);
 #endif
@@ -254,8 +287,8 @@
         array ^= pool.ObjectAt(arg_desc_index);
         obj = ICData::New(function, name,
                           array,  // Arguments descriptor.
-                          DeoptId::kNone, num_args_checked,
-                          ICData::RebindRule::kStatic);
+                          H.thread()->compiler_state().GetNextDeoptId(),
+                          num_args_checked, ICData::RebindRule::kStatic);
         ICData::Cast(obj).AddTarget(Function::Cast(elem));
 #if defined(TAG_IC_DATA)
         ICData::Cast(obj).set_tag(ICData::Tag::kStaticCall);
@@ -402,8 +435,7 @@
         closure.SetParameterNameAt(pos, Symbols::ClosureParameter());
         pos++;
 
-        const Library& lib =
-            Library::Handle(helper_->zone_, active_class_->klass->library());
+        lib = active_class_->klass->library();
         for (intptr_t j = 0; j < positional_parameter_count; ++j, ++pos) {
           VariableDeclarationHelper helper(helper_);
           helper.ReadUntilExcluding(VariableDeclarationHelper::kType);
@@ -497,6 +529,30 @@
       case ConstantPoolTag::kEmptyTypeArguments:
         obj = Object::empty_type_arguments().raw();
         break;
+      case ConstantPoolTag::kSymbol: {
+        const NameIndex lib_index = helper_->ReadCanonicalNameReference();
+        lib = Library::null();
+        if (!H.IsRoot(lib_index)) {
+          lib = H.LookupLibraryByKernelLibrary(lib_index);
+        }
+        const String& symbol =
+            H.DartIdentifier(lib, helper_->ReadStringReference());
+        if (symbol_class == nullptr) {
+          elem = Library::InternalLibrary();
+          ASSERT(!elem.IsNull());
+          symbol_class = &Class::Handle(
+              helper_->zone_,
+              Library::Cast(elem).LookupClass(Symbols::Symbol()));
+          ASSERT(!symbol_class->IsNull());
+          symbol_name_field = &Field::Handle(
+              helper_->zone_,
+              symbol_class->LookupInstanceFieldAllowPrivate(Symbols::_name()));
+          ASSERT(!symbol_name_field->IsNull());
+        }
+        obj = Instance::New(*symbol_class, Heap::kOld);
+        Instance::Cast(obj).SetField(*symbol_name_field, symbol);
+        obj = H.Canonicalize(Instance::Cast(obj));
+      } break;
       default:
         UNREACHABLE();
     }
@@ -591,9 +647,8 @@
   }
 }
 
-RawNativeEntryData* BytecodeMetadataHelper::NativeEntry(
-    const Function& function,
-    const String& external_name) {
+RawTypedData* BytecodeMetadataHelper::NativeEntry(const Function& function,
+                                                  const String& external_name) {
   Zone* zone = helper_->zone_;
   MethodRecognizer::Kind kind = MethodRecognizer::RecognizeKind(function);
   // This list of recognized methods must be kept in sync with the list of
@@ -653,17 +708,10 @@
     }
     argc_tag = NativeArguments::ComputeArgcTag(function);
   }
-  const NativeEntryData& native_entry =
-      NativeEntryData::Handle(zone, NativeEntryData::New());
-  native_entry.set_kind(kind);
-  native_entry.set_trampoline(trampoline);
-  native_entry.set_native_function(native_function);
-  native_entry.set_argc_tag(argc_tag);
-  return native_entry.raw();
+  return NativeEntryData::New(kind, trampoline, native_function, argc_tag);
 }
 
 }  // namespace kernel
 }  // namespace dart
 
-#endif  // defined(DART_USE_INTERPRETER)
 #endif  // !defined(DART_PRECOMPILED_RUNTIME)
diff --git a/runtime/vm/compiler/frontend/bytecode_reader.h b/runtime/vm/compiler/frontend/bytecode_reader.h
index 6d3ed1f..769ad61 100644
--- a/runtime/vm/compiler/frontend/bytecode_reader.h
+++ b/runtime/vm/compiler/frontend/bytecode_reader.h
@@ -9,7 +9,6 @@
 #include "vm/object.h"
 
 #if !defined(DART_PRECOMPILED_RUNTIME)
-#if defined(DART_USE_INTERPRETER)
 
 namespace dart {
 namespace kernel {
@@ -33,8 +32,8 @@
                            intptr_t from_index);
   RawCode* ReadBytecode(const ObjectPool& pool);
   void ReadExceptionsTable(const Code& bytecode);
-  RawNativeEntryData* NativeEntry(const Function& function,
-                                  const String& external_name);
+  RawTypedData* NativeEntry(const Function& function,
+                            const String& external_name);
 
   TypeTranslator& type_translator_;
   ActiveClass* const active_class_;
@@ -45,6 +44,5 @@
 }  // namespace kernel
 }  // namespace dart
 
-#endif  // defined(DART_USE_INTERPRETER)
 #endif  // !defined(DART_PRECOMPILED_RUNTIME)
 #endif  // RUNTIME_VM_COMPILER_FRONTEND_BYTECODE_READER_H_
diff --git a/runtime/vm/compiler/frontend/constant_evaluator.cc b/runtime/vm/compiler/frontend/constant_evaluator.cc
index 90e5611..4daeb02 100644
--- a/runtime/vm/compiler/frontend/constant_evaluator.cc
+++ b/runtime/vm/compiler/frontend/constant_evaluator.cc
@@ -830,7 +830,7 @@
   // We use a kernel2kernel constant evaluator in Dart 2.0 AOT compilation, so
   // we should never end up evaluating constants using the VM's constant
   // evaluator.
-  if (I->strong() && FLAG_precompiled_mode) {
+  if (FLAG_strong && FLAG_precompiled_mode) {
     UNREACHABLE();
   }
 
@@ -912,7 +912,7 @@
   // We use a kernel2kernel constant evaluator in Dart 2.0 AOT compilation, so
   // we should never end up evaluating constants using the VM's constant
   // evaluator.
-  if (I->strong() && FLAG_precompiled_mode) {
+  if (FLAG_strong && FLAG_precompiled_mode) {
     UNREACHABLE();
   }
 
@@ -1050,24 +1050,38 @@
       const_evaluator_(helper, type_translator, active_class, nullptr),
       translation_helper_(helper->translation_helper_),
       skip_vmservice_library_(skip_vmservice_library),
+      symbol_class_(Class::Handle(zone)),
+      symbol_name_field_(Field::Handle(zone)),
       temp_type_(AbstractType::Handle(zone)),
       temp_type_arguments_(TypeArguments::Handle(zone)),
       temp_type_arguments2_(TypeArguments::Handle(zone)),
       temp_type_arguments3_(TypeArguments::Handle(zone)),
       temp_object_(Object::Handle(zone)),
+      temp_string_(String::Handle(zone)),
       temp_array_(Array::Handle(zone)),
       temp_instance_(Instance::Handle(zone)),
       temp_field_(Field::Handle(zone)),
       temp_class_(Class::Handle(zone)),
+      temp_library_(Library::Handle(zone)),
       temp_function_(Function::Handle(zone)),
       temp_closure_(Closure::Handle(zone)),
       temp_context_(Context::Handle(zone)),
-      temp_integer_(Integer::Handle(zone)) {}
+      temp_integer_(Integer::Handle(zone)) {
+  temp_library_ = Library::InternalLibrary();
+  ASSERT(!temp_library_.IsNull());
+
+  symbol_class_ = temp_library_.LookupClass(Symbols::Symbol());
+  ASSERT(!symbol_class_.IsNull());
+
+  symbol_name_field_ =
+      symbol_class_.LookupInstanceFieldAllowPrivate(Symbols::_name());
+  ASSERT(!symbol_name_field_.IsNull());
+}
 
 const Array& ConstantHelper::ReadConstantTable() {
   const intptr_t number_of_constants = helper_.ReadUInt();
   if (number_of_constants == 0) {
-    return Array::Handle(Z, Array::null());
+    return Array::empty_array();
   }
 
   const Library& corelib = Library::Handle(Z, Library::CoreLibrary());
@@ -1111,6 +1125,21 @@
             H.Canonicalize(H.DartString(helper_.ReadStringReference()));
         break;
       }
+      case kSymbolConstant: {
+        Tag initializer_tag = helper_.ReadTag();
+        if (initializer_tag == kSomething) {
+          const NameIndex index = helper_.ReadCanonicalNameReference();
+          temp_library_ = H.LookupLibraryByKernelLibrary(index);
+        } else {
+          temp_library_ = Library::null();
+        }
+        const String& symbol =
+            H.DartIdentifier(temp_library_, helper_.ReadStringReference());
+        temp_instance_ = Instance::New(symbol_class_, Heap::kOld);
+        temp_instance_.SetField(symbol_name_field_, symbol);
+        temp_instance_ = H.Canonicalize(temp_instance_);
+        break;
+      }
       case kListConstant: {
         temp_type_arguments_ = TypeArguments::New(1, Heap::kOld);
         const AbstractType& type = type_translator_.BuildType();
diff --git a/runtime/vm/compiler/frontend/constant_evaluator.h b/runtime/vm/compiler/frontend/constant_evaluator.h
index f7b3b61..f71e48f 100644
--- a/runtime/vm/compiler/frontend/constant_evaluator.h
+++ b/runtime/vm/compiler/frontend/constant_evaluator.h
@@ -166,15 +166,19 @@
   ConstantEvaluator const_evaluator_;
   TranslationHelper& translation_helper_;
   NameIndex skip_vmservice_library_;
+  Class& symbol_class_;
+  Field& symbol_name_field_;
   AbstractType& temp_type_;
   TypeArguments& temp_type_arguments_;
   TypeArguments& temp_type_arguments2_;
   TypeArguments& temp_type_arguments3_;
   Object& temp_object_;
+  String& temp_string_;
   Array& temp_array_;
   Instance& temp_instance_;
   Field& temp_field_;
   Class& temp_class_;
+  Library& temp_library_;
   Function& temp_function_;
   Closure& temp_closure_;
   Context& temp_context_;
diff --git a/runtime/vm/compiler/frontend/entrypoitns_pragma.md b/runtime/vm/compiler/frontend/entrypoints_pragma.md
similarity index 100%
rename from runtime/vm/compiler/frontend/entrypoitns_pragma.md
rename to runtime/vm/compiler/frontend/entrypoints_pragma.md
diff --git a/runtime/vm/compiler/frontend/flow_graph_builder.cc b/runtime/vm/compiler/frontend/flow_graph_builder.cc
index bba0ace..3e68c2e 100644
--- a/runtime/vm/compiler/frontend/flow_graph_builder.cc
+++ b/runtime/vm/compiler/frontend/flow_graph_builder.cc
@@ -36,10 +36,6 @@
 
 namespace dart {
 
-DEFINE_FLAG(bool,
-            eliminate_type_checks,
-            true,
-            "Eliminate type checks when allowed by static type analysis.");
 DEFINE_FLAG(bool, print_ast, false, "Print abstract syntax tree.");
 DEFINE_FLAG(bool, print_scopes, false, "Print scopes of local variables.");
 DEFINE_FLAG(bool,
@@ -945,7 +941,7 @@
 
 void TestGraphVisitor::ReturnValue(Value* value) {
   Isolate* isolate = Isolate::Current();
-  if (isolate->strong() || isolate->type_checks() || isolate->asserts()) {
+  if (FLAG_strong || isolate->type_checks() || isolate->asserts()) {
     value = Bind(new (Z) AssertBooleanInstr(condition_token_pos(), value,
                                             owner()->GetNextDeoptId()));
   }
@@ -1290,7 +1286,7 @@
     node->left()->Visit(&for_left);
     EffectGraphVisitor empty(owner());
     Isolate* isolate = Isolate::Current();
-    if (isolate->strong() || isolate->type_checks() || isolate->asserts()) {
+    if (FLAG_strong || isolate->type_checks() || isolate->asserts()) {
       ValueGraphVisitor for_right(owner());
       node->right()->Visit(&for_right);
       Value* right_value = for_right.value();
@@ -1354,7 +1350,7 @@
     node->right()->Visit(&for_right);
     Value* right_value = for_right.value();
     Isolate* isolate = Isolate::Current();
-    if (isolate->strong() || isolate->type_checks() || isolate->asserts()) {
+    if (FLAG_strong || isolate->type_checks() || isolate->asserts()) {
       right_value = for_right.Bind(new (Z) AssertBooleanInstr(
           node->right()->token_pos(), right_value, owner()->GetNextDeoptId()));
     }
@@ -1626,7 +1622,7 @@
         owner()->ic_data_array(), owner()->GetNextDeoptId());
     if (node->kind() == Token::kNE) {
       Isolate* isolate = Isolate::Current();
-      if (isolate->strong() || isolate->type_checks() || isolate->asserts()) {
+      if (FLAG_strong || isolate->type_checks() || isolate->asserts()) {
         Value* value = Bind(result);
         result = new (Z) AssertBooleanInstr(node->token_pos(), value,
                                             owner()->GetNextDeoptId());
@@ -1670,7 +1666,7 @@
     Append(for_value);
     Value* value = for_value.value();
     Isolate* isolate = Isolate::Current();
-    if (isolate->strong() || isolate->type_checks() || isolate->asserts()) {
+    if (FLAG_strong || isolate->type_checks() || isolate->asserts()) {
       value = Bind(new (Z) AssertBooleanInstr(
           node->operand()->token_pos(), value, owner()->GetNextDeoptId()));
     }
@@ -2748,7 +2744,7 @@
   LocalVariable* function_type_arguments_var =
       owner()->parsed_function().function_type_arguments();
   if (function_type_arguments_var == NULL) {
-    ASSERT(!owner()->isolate()->reify_generic_functions());
+    ASSERT(!FLAG_reify_generic_functions);
     return BuildNullValue(token_pos);
   }
   return Bind(BuildLoadLocal(*function_type_arguments_var, token_pos));
@@ -3387,7 +3383,7 @@
   const String& name = String::ZoneHandle(Z, function.native_name());
   const intptr_t num_params = function.NumParameters();
   ZoneGrowableArray<PushArgumentInstr*>* args = NULL;
-  if (function.IsGeneric() && owner()->isolate()->reify_generic_functions()) {
+  if (function.IsGeneric() && FLAG_reify_generic_functions) {
     args = new (Z) ZoneGrowableArray<PushArgumentInstr*>(1 + num_params);
     LocalVariable* type_args = pf.RawTypeArgumentsVariable();
     ASSERT(type_args != NULL);
@@ -3838,7 +3834,7 @@
   // Load the passed-in type argument vector from the temporary stack slot,
   // prepend the function type arguments of the generic parent function, and
   // store it to the final location, possibly in the context.
-  if (owner()->isolate()->reify_generic_functions() && is_top_level_sequence &&
+  if (FLAG_reify_generic_functions && is_top_level_sequence &&
       function.IsGeneric()) {
     const ParsedFunction& parsed_function = owner()->parsed_function();
     LocalVariable* type_args_var = parsed_function.function_type_arguments();
@@ -4171,8 +4167,8 @@
       catch_block->token_pos(), (node->token_pos() == TokenPosition::kNoSource),
       owner()->AllocateBlockId(), catch_handler_index, owner()->graph_entry(),
       catch_block->handler_types(), try_handler_index,
-      catch_block->exception_var(), catch_block->stacktrace_var(),
       catch_block->needs_stacktrace(), owner()->GetNextDeoptId(),
+      &catch_block->exception_var(), &catch_block->stacktrace_var(),
       &catch_block->exception_var(), &catch_block->stacktrace_var());
   owner()->AddCatchEntry(catch_entry);
   AppendFragment(catch_entry, for_catch);
@@ -4218,8 +4214,8 @@
         true,  // this is not a catch block from user code.
         owner()->AllocateBlockId(), original_handler_index,
         owner()->graph_entry(), types, catch_handler_index,
-        catch_block->exception_var(), catch_block->stacktrace_var(),
         catch_block->needs_stacktrace(), owner()->GetNextDeoptId(),
+        &catch_block->exception_var(), &catch_block->stacktrace_var(),
         &catch_block->exception_var(), &catch_block->stacktrace_var());
     owner()->AddCatchEntry(finally_entry);
     AppendFragment(finally_entry, for_finally);
diff --git a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
index ca6e29d..e8b948c 100644
--- a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
+++ b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
@@ -4,6 +4,7 @@
 
 #include "vm/compiler/frontend/kernel_binary_flowgraph.h"
 
+#include "vm/compiler/frontend/bytecode_flow_graph_builder.h"
 #include "vm/compiler/frontend/bytecode_reader.h"
 #include "vm/compiler/frontend/flow_graph_builder.h"  // For dart::FlowGraphBuilder::SimpleInstanceOfType.
 #include "vm/compiler/frontend/prologue_builder.h"
@@ -14,6 +15,9 @@
 #if !defined(DART_PRECOMPILED_RUNTIME)
 
 namespace dart {
+
+DECLARE_FLAG(bool, enable_interpreter);
+
 namespace kernel {
 
 #define Z (zone_)
@@ -425,7 +429,7 @@
 Fragment StreamingFlowGraphBuilder::BuildDefaultTypeHandling(
     const Function& function,
     intptr_t type_parameters_offset) {
-  if (function.IsGeneric() && I->reify_generic_functions()) {
+  if (function.IsGeneric() && FLAG_reify_generic_functions) {
     AlternativeReadingScope alt(&reader_);
     SetOffset(type_parameters_offset);
     intptr_t num_type_params = ReadListLength();
@@ -541,7 +545,7 @@
       FunctionNodeHelper::kPositionalParameters);
 
   intptr_t type_args_len = 0;
-  if (I->reify_generic_functions() && function.IsGeneric()) {
+  if (function.IsGeneric() && FLAG_reify_generic_functions) {
     type_args_len = function.NumTypeParameters();
     ASSERT(parsed_function()->function_type_arguments() != NULL);
     body += LoadLocal(parsed_function()->function_type_arguments());
@@ -662,7 +666,7 @@
   // If we are inside the tearoff wrapper function (implicit closure), we need
   // to extract the receiver from the context. We just replace it directly on
   // the stack to simplify the rest of the code.
-  if (is_implicit_closure_function) {
+  if (is_implicit_closure_function && !function.is_static()) {
     if (parsed_function()->has_arg_desc_var()) {
       body += B->LoadArgDescriptor();
       body += LoadField(ArgumentsDescriptor::count_offset());
@@ -700,7 +704,7 @@
   body += IntConstant(0);
   body += StoreLocal(TokenPosition::kNoSource, argument_count_var);
   body += Drop();
-  if (function.IsGeneric() && Isolate::Current()->reify_generic_functions()) {
+  if (function.IsGeneric() && FLAG_reify_generic_functions) {
     Fragment then;
     Fragment otherwise;
     otherwise += IntConstant(1);
@@ -749,7 +753,7 @@
     //   arguments[0] = function_type_arguments;
     //   i = 1;
     // }
-    if (function.IsGeneric() && Isolate::Current()->reify_generic_functions()) {
+    if (function.IsGeneric() && FLAG_reify_generic_functions) {
       Fragment store;
       store += LoadLocal(arguments);
       store += IntConstant(0);
@@ -962,9 +966,10 @@
   }
 
   const bool has_reified_type_arguments =
-      I->strong() && I->reify_generic_functions();
+      FLAG_strong && FLAG_reify_generic_functions;
 
   TypeParameter& forwarding_param = TypeParameter::Handle(Z);
+  Fragment check_bounds;
   for (intptr_t i = 0; i < num_type_params; ++i) {
     TypeParameterHelper helper(this);
     helper.ReadUntilExcludingAndSetJustRead(TypeParameterHelper::kBound);
@@ -1009,7 +1014,20 @@
       param ^= TypeArguments::Handle(dart_function.type_parameters()).TypeAt(i);
     }
     ASSERT(param.IsFinalized());
-    *implicit_checks += CheckTypeArgumentBound(param, bound, name);
+    check_bounds += CheckTypeArgumentBound(param, bound, name);
+  }
+
+  // Type arguments passed through partial instantiation are guaranteed to be
+  // bounds-checked at the point of partial instantiation, so we don't need to
+  // check them again at the call-site.
+  if (dart_function.IsClosureFunction() && !check_bounds.is_empty() &&
+      FLAG_eliminate_type_checks) {
+    LocalVariable* closure =
+        parsed_function()->node_sequence()->scope()->VariableAt(0);
+    *implicit_checks += B->TestDelayedTypeArgs(closure, /*present=*/{},
+                                               /*absent=*/check_bounds);
+  } else {
+    *implicit_checks += check_bounds;
   }
 
   function_node_helper.SetJustRead(FunctionNodeHelper::kTypeParameters);
@@ -1077,7 +1095,7 @@
 }
 
 Fragment StreamingFlowGraphBuilder::PushAllArguments(PushedArguments* pushed) {
-  ASSERT(I->strong());
+  ASSERT(FLAG_strong);
 
   FunctionNodeHelper function_node_helper(this);
   function_node_helper.SetNext(FunctionNodeHelper::kTypeParameters);
@@ -1092,7 +1110,7 @@
       helper.Finish();
     }
 
-    if (I->reify_generic_functions()) {
+    if (FLAG_reify_generic_functions) {
       body += LoadLocal(parsed_function()->function_type_arguments());
       body += PushArgument();
       pushed->type_args_len = num_type_params;
@@ -1172,6 +1190,7 @@
       first_parameter_offset = ReaderOffset() + data_program_offset_;
     }
   }
+  USE(first_parameter_offset);
   // Current position: About to read list of positionals.
 
   // Should never build a dynamic invocation forwarder for equality
@@ -1225,7 +1244,7 @@
   // entry and make graph entry jump to it instead of normal entry.
   // Catch entries are always considered reachable, even if they
   // become unreachable after OSR.
-  if (flow_graph_builder_->osr_id_ != Compiler::kNoOSRDeoptId) {
+  if (flow_graph_builder_->IsCompiledForOsr()) {
     graph_entry->RelinkToOsrEntry(Z,
                                   flow_graph_builder_->last_used_block_id_ + 1);
   }
@@ -1301,7 +1320,7 @@
 
   if (dart_function.IsClosureFunction() &&
       dart_function.NumParentTypeParameters() > 0 &&
-      I->reify_generic_functions()) {
+      FLAG_reify_generic_functions) {
     LocalVariable* closure =
         parsed_function()->node_sequence()->scope()->VariableAt(0);
 
@@ -1860,7 +1879,7 @@
   // entry and make graph entry jump to it instead of normal entry.
   // Catch entries are always considered reachable, even if they
   // become unreachable after OSR.
-  if (flow_graph_builder_->osr_id_ != Compiler::kNoOSRDeoptId) {
+  if (flow_graph_builder_->IsCompiledForOsr()) {
     graph_entry->RelinkToOsrEntry(Z,
                                   flow_graph_builder_->last_used_block_id_ + 1);
   }
@@ -1889,10 +1908,7 @@
 
   SetOffset(kernel_offset);
 
-#if defined(DART_USE_INTERPRETER)
-  // TODO(regis): Clean up this logic of when to compile.
-  // If the bytecode was previously loaded, we really want to compile.
-  if (!function.HasBytecode()) {
+  if (FLAG_enable_interpreter || FLAG_use_bytecode_compiler) {
     // TODO(regis): For now, we skip bytecode loading for functions that were
     // synthesized and that do not have bytecode. Since they inherited the
     // kernel offset of a concrete function, the wrong bytecode would be loaded.
@@ -1905,15 +1921,33 @@
       case RawFunction::kDynamicInvocationForwarder:
       case RawFunction::kImplicitClosureFunction:
         break;
+      case RawFunction::kImplicitStaticFinalGetter:
+        if (!IsFieldInitializer(function, Z)) {
+          break;
+        }
+        // Fallthrough.
       default: {
-        bytecode_metadata_helper_.ReadMetadata(function);
+        // TODO(regis): Clean up this logic of when to compile.
+        // If the bytecode was previously loaded, we really want to compile.
+        if (!function.HasBytecode()) {
+          bytecode_metadata_helper_.ReadMetadata(function);
+        }
         if (function.HasBytecode()) {
-          return NULL;
+          if (FLAG_use_bytecode_compiler) {
+            BytecodeFlowGraphBuilder bytecode_compiler(
+                flow_graph_builder_, parsed_function(),
+                &(flow_graph_builder_->ic_data_array_));
+            FlowGraph* flow_graph = bytecode_compiler.BuildGraph();
+            if (flow_graph != nullptr) {
+              return flow_graph;
+            }
+          } else {
+            return nullptr;
+          }
         }
       }
     }
   }
-#endif
 
   // Mark forwarding stubs.
   switch (function.kind()) {
@@ -2565,7 +2599,7 @@
   AlternativeReadingScope alt(&reader_);
 
   TryFinallyBlock* const saved_block = B->try_finally_block_;
-  TryCatchBlock* const saved_try_catch_block = B->try_catch_block_;
+  TryCatchBlock* const saved_try_catch_block = B->CurrentTryCatchBlock();
   const intptr_t saved_depth = B->context_depth_;
   const intptr_t saved_try_depth = B->try_depth_;
 
@@ -2586,7 +2620,7 @@
     bool changed_try_index = false;
     intptr_t target_try_index = B->try_finally_block_->try_index();
     while (B->CurrentTryIndex() != target_try_index) {
-      B->try_catch_block_ = B->try_catch_block_->outer();
+      B->SetCurrentTryCatchBlock(B->CurrentTryCatchBlock()->outer());
       changed_try_index = true;
     }
     if (changed_try_index) {
@@ -2613,7 +2647,7 @@
   }
 
   B->try_finally_block_ = saved_block;
-  B->try_catch_block_ = saved_try_catch_block;
+  B->SetCurrentTryCatchBlock(saved_try_catch_block);
   B->context_depth_ = saved_depth;
   B->try_depth_ = saved_try_depth;
 
@@ -2966,7 +3000,7 @@
   const Function* interface_target = &Function::null_function();
   const NameIndex itarget_name =
       ReadCanonicalNameReference();  // read interface_target_reference.
-  if (I->strong() && !H.IsRoot(itarget_name) &&
+  if (FLAG_strong && !H.IsRoot(itarget_name) &&
       (H.IsGetter(itarget_name) || H.IsField(itarget_name))) {
     interface_target = &Function::ZoneHandle(
         Z,
@@ -3046,7 +3080,7 @@
   const Function* interface_target = &Function::null_function();
   const NameIndex itarget_name =
       ReadCanonicalNameReference();  // read interface_target_reference.
-  if (I->strong() && !H.IsRoot(itarget_name)) {
+  if (FLAG_strong && !H.IsRoot(itarget_name)) {
     interface_target = &Function::ZoneHandle(
         Z,
         H.LookupMethodByMember(itarget_name, H.DartSetterName(itarget_name)));
@@ -3556,7 +3590,7 @@
 
   intptr_t type_args_len = 0;
   LocalVariable* type_arguments_temp = NULL;
-  if (I->reify_generic_functions()) {
+  if (FLAG_reify_generic_functions) {
     AlternativeReadingScope alt(&reader_);
     SkipExpression();                         // skip receiver
     SkipName();                               // skip method name
@@ -3644,7 +3678,7 @@
   const Function* interface_target = &Function::null_function();
   const NameIndex itarget_name =
       ReadCanonicalNameReference();  // read interface_target_reference.
-  if (I->strong() && !H.IsRoot(itarget_name) && !H.IsField(itarget_name)) {
+  if (FLAG_strong && !H.IsRoot(itarget_name) && !H.IsField(itarget_name)) {
     interface_target = &Function::ZoneHandle(
         Z, H.LookupMethodByMember(itarget_name,
                                   H.DartProcedureName(itarget_name)));
@@ -3735,7 +3769,7 @@
 
   Fragment instructions;
   intptr_t type_args_len = 0;
-  if (I->reify_generic_functions()) {
+  if (FLAG_reify_generic_functions) {
     AlternativeReadingScope alt(&reader_);
     SkipExpression();                         // skip receiver
     ReadCanonicalNameReference();             // skip target reference
@@ -3801,7 +3835,7 @@
       inferred_type_metadata_helper_.GetInferredType(offset);
 
   intptr_t type_args_len = 0;
-  if (I->reify_generic_functions()) {
+  if (FLAG_reify_generic_functions) {
     AlternativeReadingScope alt(&reader_);
     SkipName();                        // skip method name
     ReadUInt();                        // read argument count.
@@ -3905,7 +3939,7 @@
   } else {
     Fragment instructions;
 
-    if (I->reify_generic_functions()) {
+    if (FLAG_reify_generic_functions) {
       AlternativeReadingScope alt(&reader_);
       ReadUInt();                               // read argument count.
       intptr_t list_length = ReadListLength();  // read types list length.
@@ -4004,7 +4038,7 @@
     const TypeArguments& type_arguments = PeekArgumentsInstantiatedType(klass);
     instructions += TranslateInstantiatedTypeArguments(type_arguments);
     instructions += PushArgument();
-  } else if (!special_case && I->reify_generic_functions()) {
+  } else if (!special_case && FLAG_reify_generic_functions) {
     AlternativeReadingScope alt(&reader_);
     ReadUInt();                               // read argument count.
     intptr_t list_length = ReadListLength();  // read types list length.
@@ -4209,7 +4243,7 @@
     const bool is_bool = top->IsStrictCompare() || top->IsBooleanNegate();
     if (!is_bool) {
       right_value += CheckBoolean(position);
-      if (!I->strong()) {
+      if (!FLAG_strong) {
         right_value += Constant(Bool::True());
         right_value += StrictCompare(Token::kEQ_STRICT);
       }
@@ -4772,8 +4806,9 @@
 
   // Check the bounds.
   //
-  // TODO(sjindel): Only perform this check for instance tearoffs, not for
-  // tearoffs against local or top-level functions.
+  // TODO(sjindel): We should be able to skip this check in many cases, e.g.
+  // when the closure is coming from a tearoff of a top-level method or from a
+  // local closure.
   instructions += LoadLocal(original_closure);
   instructions += PushArgument();
   instructions += LoadLocal(type_args_vec);
diff --git a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h
index 3992163..c5449d6 100644
--- a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h
+++ b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h
@@ -39,9 +39,7 @@
                             &type_translator_,
                             active_class_,
                             flow_graph_builder),
-#if defined(DART_USE_INTERPRETER)
         bytecode_metadata_helper_(this, &type_translator_, active_class_),
-#endif  // defined(DART_USE_INTERPRETER)
         direct_call_metadata_helper_(this),
         inferred_type_metadata_helper_(this),
         procedure_attributes_metadata_helper_(this),
@@ -419,9 +417,7 @@
   ActiveClass* const active_class_;
   TypeTranslator type_translator_;
   ConstantEvaluator constant_evaluator_;
-#if defined(DART_USE_INTERPRETER)
   BytecodeMetadataHelper bytecode_metadata_helper_;
-#endif  // defined(DART_USE_INTERPRETER)
   DirectCallMetadataHelper direct_call_metadata_helper_;
   InferredTypeMetadataHelper inferred_type_metadata_helper_;
   ProcedureAttributesMetadataHelper procedure_attributes_metadata_helper_;
diff --git a/runtime/vm/compiler/frontend/kernel_fingerprints.cc b/runtime/vm/compiler/frontend/kernel_fingerprints.cc
index 0f88c25..1df89e8 100644
--- a/runtime/vm/compiler/frontend/kernel_fingerprints.cc
+++ b/runtime/vm/compiler/frontend/kernel_fingerprints.cc
@@ -297,14 +297,14 @@
 
 void KernelFingerprintHelper::CalculateGetterNameFingerprint() {
   const NameIndex name = ReadCanonicalNameReference();
-  if (I->strong() && !H.IsRoot(name) && (H.IsGetter(name) || H.IsField(name))) {
+  if (FLAG_strong && !H.IsRoot(name) && (H.IsGetter(name) || H.IsField(name))) {
     BuildHash(H.DartGetterName(name).Hash());
   }
 }
 
 void KernelFingerprintHelper::CalculateSetterNameFingerprint() {
   const NameIndex name = ReadCanonicalNameReference();
-  if (I->strong() && !H.IsRoot(name)) {
+  if (FLAG_strong && !H.IsRoot(name)) {
     BuildHash(H.DartSetterName(name).Hash());
   }
 }
@@ -312,7 +312,7 @@
 void KernelFingerprintHelper::CalculateMethodNameFingerprint() {
   const NameIndex name =
       ReadCanonicalNameReference();  // read interface_target_reference.
-  if (I->strong() && !H.IsRoot(name) && !H.IsField(name)) {
+  if (FLAG_strong && !H.IsRoot(name) && !H.IsField(name)) {
     BuildHash(H.DartProcedureName(name).Hash());
   }
 }
diff --git a/runtime/vm/compiler/frontend/kernel_to_il.cc b/runtime/vm/compiler/frontend/kernel_to_il.cc
index a68d9b9..fff48a9 100644
--- a/runtime/vm/compiler/frontend/kernel_to_il.cc
+++ b/runtime/vm/compiler/frontend/kernel_to_il.cc
@@ -30,7 +30,7 @@
 
 FlowGraphBuilder::FlowGraphBuilder(
     ParsedFunction* parsed_function,
-    const ZoneGrowableArray<const ICData*>& ic_data_array,
+    ZoneGrowableArray<const ICData*>* ic_data_array,
     ZoneGrowableArray<intptr_t>* context_level_array,
     InlineExitCollector* exit_collector,
     bool optimizing,
@@ -39,6 +39,7 @@
     bool inlining_unchecked_entry)
     : BaseFlowGraphBuilder(parsed_function,
                            first_block_id - 1,
+                           osr_id,
                            context_level_array,
                            exit_collector,
                            inlining_unchecked_entry),
@@ -47,8 +48,7 @@
       zone_(translation_helper_.zone()),
       parsed_function_(parsed_function),
       optimizing_(optimizing),
-      osr_id_(osr_id),
-      ic_data_array_(ic_data_array),
+      ic_data_array_(*ic_data_array),
       next_function_id_(0),
       try_depth_(0),
       catch_depth_(0),
@@ -57,6 +57,7 @@
       scopes_(NULL),
       breakable_block_(NULL),
       switch_block_(NULL),
+      try_catch_block_(NULL),
       try_finally_block_(NULL),
       catch_block_(NULL) {
   const Script& script =
@@ -152,7 +153,7 @@
 // arguments of the current function.
 Fragment FlowGraphBuilder::LoadFunctionTypeArguments() {
   Fragment instructions;
-  if (!Isolate::Current()->reify_generic_functions()) {
+  if (!FLAG_reify_generic_functions) {
     instructions += NullConstant();
     return instructions;
   }
@@ -245,8 +246,8 @@
       TokenPosition::kNoSource,  // Token position of catch block.
       is_synthesized,  // whether catch block was synthesized by FE compiler
       AllocateBlockId(), CurrentTryIndex(), graph_entry_, handler_types,
-      handler_index, *exception_var, *stacktrace_var, needs_stacktrace,
-      GetNextDeoptId(), raw_exception_var, raw_stacktrace_var);
+      handler_index, needs_stacktrace, GetNextDeoptId(), exception_var,
+      stacktrace_var, raw_exception_var, raw_stacktrace_var);
   graph_entry_->AddCatchEntry(entry);
 
   Fragment instructions(entry);
@@ -416,18 +417,6 @@
   return Fragment(load);
 }
 
-Fragment FlowGraphBuilder::LoadField(const Field& field) {
-  LoadFieldInstr* load = new (Z) LoadFieldInstr(
-      Pop(), &MayCloneField(field), AbstractType::ZoneHandle(Z, field.type()),
-      TokenPosition::kNoSource, parsed_function_);
-  Push(load);
-  return Fragment(load);
-}
-
-Fragment FlowGraphBuilder::LoadField(intptr_t offset, intptr_t class_id) {
-  return BaseFlowGraphBuilder::LoadField(offset, class_id);
-}
-
 Fragment FlowGraphBuilder::LoadLocal(LocalVariable* variable) {
   if (variable->is_captured()) {
     Fragment instructions;
@@ -451,9 +440,7 @@
   InlineBailout("kernel::FlowGraphBuilder::NativeCall");
   const intptr_t num_args =
       function->NumParameters() +
-      ((function->IsGeneric() && Isolate::Current()->reify_generic_functions())
-           ? 1
-           : 0);
+      ((function->IsGeneric() && FLAG_reify_generic_functions) ? 1 : 0);
   ArgumentArray arguments = GetArguments(num_args);
   NativeCallInstr* call =
       new (Z) NativeCallInstr(name, function, FLAG_link_natives_lazily,
@@ -470,7 +457,7 @@
   // Emit a type check of the return type in checked mode for all functions
   // and in strong mode for native functions.
   if (!omit_result_type_check &&
-      (I->type_checks() || (function.is_native() && I->strong()))) {
+      (I->type_checks() || (function.is_native() && FLAG_strong))) {
     const AbstractType& return_type =
         AbstractType::Handle(Z, function.result_type());
     instructions += CheckAssignable(return_type, Symbols::FunctionResult());
@@ -928,8 +915,7 @@
       break;
     default: {
       String& name = String::ZoneHandle(Z, function.native_name());
-      if (function.IsGeneric() &&
-          Isolate::Current()->reify_generic_functions()) {
+      if (function.IsGeneric() && FLAG_reify_generic_functions) {
         body += LoadLocal(parsed_function_->RawTypeArgumentsVariable());
         body += PushArgument();
       }
@@ -1046,7 +1032,7 @@
 
 Fragment FlowGraphBuilder::CheckBoolean(TokenPosition position) {
   Fragment instructions;
-  if (I->strong() || I->type_checks() || I->asserts()) {
+  if (FLAG_strong || I->type_checks() || I->asserts()) {
     LocalVariable* top_of_stack = MakeTemporary();
     instructions += LoadLocal(top_of_stack);
     instructions += AssertBool(position);
@@ -1384,6 +1370,13 @@
                            prologue_info);
 }
 
+void FlowGraphBuilder::SetCurrentTryCatchBlock(TryCatchBlock* try_catch_block) {
+  try_catch_block_ = try_catch_block;
+  SetCurrentTryIndex(try_catch_block == nullptr
+                         ? CatchClauseNode::kInvalidTryIndex
+                         : try_catch_block->try_index());
+}
+
 }  // namespace kernel
 }  // namespace dart
 
diff --git a/runtime/vm/compiler/frontend/kernel_to_il.h b/runtime/vm/compiler/frontend/kernel_to_il.h
index 9f6b524..eeecd74 100644
--- a/runtime/vm/compiler/frontend/kernel_to_il.h
+++ b/runtime/vm/compiler/frontend/kernel_to_il.h
@@ -22,13 +22,13 @@
 
 namespace kernel {
 
-class BaseFlowGraphBuilder;
 class StreamingFlowGraphBuilder;
 struct InferredTypeMetadata;
 class BreakableBlock;
 class CatchBlock;
 class FlowGraphBuilder;
 class SwitchBlock;
+class TryCatchBlock;
 class TryFinallyBlock;
 
 struct YieldContinuation {
@@ -45,7 +45,7 @@
 class FlowGraphBuilder : public BaseFlowGraphBuilder {
  public:
   FlowGraphBuilder(ParsedFunction* parsed_function,
-                   const ZoneGrowableArray<const ICData*>& ic_data_array,
+                   ZoneGrowableArray<const ICData*>* ic_data_array,
                    ZoneGrowableArray<intptr_t>* context_level_array,
                    InlineExitCollector* exit_collector,
                    bool optimizing,
@@ -114,8 +114,6 @@
 
   Fragment RethrowException(TokenPosition position, int catch_try_index);
   Fragment LoadClassId();
-  Fragment LoadField(intptr_t offset, intptr_t class_id = kDynamicCid);
-  Fragment LoadField(const Field& field);
   Fragment LoadLocal(LocalVariable* variable);
   Fragment InitStaticField(const Field& field);
   Fragment NativeCall(const String* name, const Function* function);
@@ -172,16 +170,13 @@
 
   LocalVariable* LookupVariable(intptr_t kernel_offset);
 
-  bool IsCompiledForOsr() { return osr_id_ != DeoptId::kNone; }
-
   TranslationHelper translation_helper_;
   Thread* thread_;
   Zone* zone_;
 
   ParsedFunction* parsed_function_;
   const bool optimizing_;
-  intptr_t osr_id_;
-  const ZoneGrowableArray<const ICData*>& ic_data_array_;
+  ZoneGrowableArray<const ICData*>& ic_data_array_;
 
   intptr_t next_function_id_;
   intptr_t AllocateFunctionId() { return next_function_id_++; }
@@ -212,6 +207,10 @@
     return scopes_->catch_context_variables[try_depth_];
   }
 
+  TryCatchBlock* CurrentTryCatchBlock() const { return try_catch_block_; }
+
+  void SetCurrentTryCatchBlock(TryCatchBlock* try_catch_block);
+
   // A chained list of breakable blocks. Chaining and lookup is done by the
   // [BreakableBlock] class.
   BreakableBlock* breakable_block_;
@@ -220,6 +219,10 @@
   // [SwitchBlock] class.
   SwitchBlock* switch_block_;
 
+  // A chained list of try-catch blocks. Chaining and lookup is done by the
+  // [TryCatchBlock] class.
+  TryCatchBlock* try_catch_block_;
+
   // A chained list of try-finally blocks. Chaining and lookup is done by the
   // [TryFinallyBlock] class.
   TryFinallyBlock* try_finally_block_;
@@ -235,6 +238,7 @@
   friend class ConstantEvaluator;
   friend class StreamingFlowGraphBuilder;
   friend class SwitchBlock;
+  friend class TryCatchBlock;
   friend class TryFinallyBlock;
 
   DISALLOW_COPY_AND_ASSIGN(FlowGraphBuilder);
@@ -321,6 +325,30 @@
   intptr_t try_index_;
 };
 
+class TryCatchBlock {
+ public:
+  explicit TryCatchBlock(FlowGraphBuilder* builder,
+                         intptr_t try_handler_index = -1)
+      : builder_(builder),
+        outer_(builder->CurrentTryCatchBlock()),
+        try_index_(try_handler_index == -1 ? builder->AllocateTryIndex()
+                                           : try_handler_index) {
+    builder->SetCurrentTryCatchBlock(this);
+  }
+
+  ~TryCatchBlock() { builder_->SetCurrentTryCatchBlock(outer_); }
+
+  intptr_t try_index() { return try_index_; }
+  TryCatchBlock* outer() const { return outer_; }
+
+ private:
+  FlowGraphBuilder* const builder_;
+  TryCatchBlock* const outer_;
+  intptr_t const try_index_;
+
+  DISALLOW_COPY_AND_ASSIGN(TryCatchBlock);
+};
+
 class TryFinallyBlock {
  public:
   TryFinallyBlock(FlowGraphBuilder* builder, intptr_t finalizer_kernel_offset)
diff --git a/runtime/vm/compiler/frontend/kernel_translation_helper.cc b/runtime/vm/compiler/frontend/kernel_translation_helper.cc
index 14a60fe..b75b3d6 100644
--- a/runtime/vm/compiler/frontend/kernel_translation_helper.cc
+++ b/runtime/vm/compiler/frontend/kernel_translation_helper.cc
@@ -2696,16 +2696,18 @@
   NameIndex klass_name =
       helper_->ReadCanonicalNameReference();  // read klass_name.
 
-  intptr_t length;
+  const Class& klass = Class::Handle(Z, H.LookupClassByKernelClass(klass_name));
   if (simple) {
-    length = 0;
-  } else {
-    length = helper_->ReadListLength();  // read type_arguments list length.
+    // Fast path for non-generic types: retrieve or populate the class's only
+    // canonical type.
+    result_ = H.GetCanonicalType(klass).raw();
+    return;
   }
+
+  intptr_t length =
+      helper_->ReadListLength();  // read type_arguments list length.
   const TypeArguments& type_arguments =
       BuildTypeArguments(length);  // read type arguments.
-
-  Object& klass = Object::Handle(Z, H.LookupClassByKernelClass(klass_name));
   result_ = Type::New(klass, type_arguments, TokenPosition::kNoSource);
   if (finalize_) {
     ASSERT(active_class_->klass != NULL);
@@ -2865,7 +2867,7 @@
             : 0;
     if (procedure_type_parameter_count > 0) {
       if (procedure_type_parameter_count > parameter_index) {
-        if (I->reify_generic_functions()) {
+        if (FLAG_reify_generic_functions) {
           result_ ^=
               TypeArguments::Handle(Z, active_class_->member->type_parameters())
                   .TypeAt(parameter_index);
@@ -2884,7 +2886,7 @@
 
   if (active_class_->local_type_parameters != NULL) {
     if (parameter_index < active_class_->local_type_parameters->Length()) {
-      if (I->reify_generic_functions()) {
+      if (FLAG_reify_generic_functions) {
         result_ ^=
             active_class_->local_type_parameters->TypeAt(parameter_index);
       } else {
diff --git a/runtime/vm/compiler/frontend/kernel_translation_helper.h b/runtime/vm/compiler/frontend/kernel_translation_helper.h
index 3dd63b8..0d1e40d 100644
--- a/runtime/vm/compiler/frontend/kernel_translation_helper.h
+++ b/runtime/vm/compiler/frontend/kernel_translation_helper.h
@@ -1042,6 +1042,7 @@
   // kernel program.
   intptr_t data_program_offset_;
 
+  friend class BytecodeMetadataHelper;
   friend class ClassHelper;
   friend class CallSiteAttributesMetadataHelper;
   friend class ConstantEvaluator;
@@ -1064,10 +1065,6 @@
   friend class VariableDeclarationHelper;
   friend bool NeedsDynamicInvocationForwarder(const Function& function);
 
-#if defined(DART_USE_INTERPRETER)
-  friend class BytecodeMetadataHelper;
-#endif  // defined(DART_USE_INTERPRETER)
-
  private:
   DISALLOW_COPY_AND_ASSIGN(KernelReaderHelper);
 };
diff --git a/runtime/vm/compiler/frontend/prologue_builder.cc b/runtime/vm/compiler/frontend/prologue_builder.cc
index 0ab2315..a63ae30 100644
--- a/runtime/vm/compiler/frontend/prologue_builder.cc
+++ b/runtime/vm/compiler/frontend/prologue_builder.cc
@@ -34,9 +34,6 @@
 
 BlockEntryInstr* PrologueBuilder::BuildPrologue(BlockEntryInstr* entry,
                                                 PrologueInfo* prologue_info) {
-  Isolate* isolate = Isolate::Current();
-  const bool strong = isolate->strong();
-
   // We always have to build the graph, but we only link it sometimes.
   const bool link = !is_inlining_ && !compiling_for_osr_;
 
@@ -44,7 +41,7 @@
 
   const bool load_optional_arguments = function_.HasOptionalParameters();
   const bool expect_type_args =
-      function_.IsGeneric() && isolate->reify_generic_functions();
+      function_.IsGeneric() && FLAG_reify_generic_functions;
   const bool check_arguments = function_.IsClosureFunction();
 
   Fragment prologue = Fragment(entry);
@@ -53,14 +50,15 @@
     nsm = BuildThrowNoSuchMethod();
   }
   if (check_arguments) {
-    Fragment f = BuildTypeArgumentsLengthCheck(strong, nsm, expect_type_args);
+    Fragment f = BuildTypeArgumentsLengthCheck(nsm, expect_type_args);
     if (link) prologue += f;
   }
   if (load_optional_arguments) {
-    Fragment f = BuildOptionalParameterHandling(strong, nsm);
+    Fragment f = BuildOptionalParameterHandling(
+        nsm, parsed_function_->expression_temp_var());
     if (link) prologue += f;
   } else if (check_arguments) {
-    Fragment f = BuildFixedParameterLengthChecks(strong, nsm);
+    Fragment f = BuildFixedParameterLengthChecks(nsm);
     if (link) prologue += f;
   }
   if (function_.IsClosureFunction()) {
@@ -88,8 +86,7 @@
   }
 }
 
-Fragment PrologueBuilder::BuildTypeArgumentsLengthCheck(bool strong,
-                                                        JoinEntryInstr* nsm,
+Fragment PrologueBuilder::BuildTypeArgumentsLengthCheck(JoinEntryInstr* nsm,
                                                         bool expect_type_args) {
   Fragment check_type_args;
   JoinEntryInstr* done = BuildJoinEntry();
@@ -131,8 +128,9 @@
   return Fragment(check_type_args.entry, done);
 }
 
-Fragment PrologueBuilder::BuildOptionalParameterHandling(bool strong,
-                                                         JoinEntryInstr* nsm) {
+Fragment PrologueBuilder::BuildOptionalParameterHandling(
+    JoinEntryInstr* nsm,
+    LocalVariable* temp_var) {
   Fragment copy_args_prologue;
   const int num_fixed_params = function_.num_fixed_parameters();
   const int num_opt_pos_params = function_.NumOptionalPositionalParameters();
@@ -245,13 +243,12 @@
         ArgumentsDescriptor::first_named_entry_offset() - Array::data_offset();
 
     // Start by alphabetically sorting the names of the optional parameters.
-    LocalVariable** opt_param = new LocalVariable*[num_opt_named_params];
-    int* opt_param_position = new int[num_opt_named_params];
-    SortOptionalNamedParametersInto(opt_param, opt_param_position,
-                                    num_fixed_params, num_params);
+    int* opt_param_position = Z->Alloc<int>(num_opt_named_params);
+    SortOptionalNamedParametersInto(opt_param_position, num_fixed_params,
+                                    num_params);
 
-    LocalVariable* optional_count_vars_processed =
-        parsed_function_->expression_temp_var();
+    ASSERT(temp_var != nullptr);
+    LocalVariable* optional_count_vars_processed = temp_var;
     copy_args_prologue += IntConstant(0);
     copy_args_prologue +=
         StoreLocalRaw(TokenPosition::kNoSource, optional_count_vars_processed);
@@ -275,8 +272,10 @@
       copy_args_prologue += LoadIndexed(/* index_scale = */ kWordSize);
 
       // first name in sorted list of all names
-      ASSERT(opt_param[i]->name().IsSymbol());
-      copy_args_prologue += Constant(opt_param[i]->name());
+      const String& param_name = String::ZoneHandle(
+          Z, function_.ParameterNameAt(opt_param_position[i]));
+      ASSERT(param_name.IsSymbol());
+      copy_args_prologue += Constant(param_name);
 
       // Compare the two names: Note that the ArgumentDescriptor array always
       // terminates with a "null" name (i.e. kNullCid), which will prevent us
@@ -338,9 +337,6 @@
       copy_args_prologue += Drop();  // tuple_diff
     }
 
-    delete[] opt_param;
-    delete[] opt_param_position;
-
     // If there are more arguments from the caller we haven't processed, go
     // NSM.
     TargetEntryInstr *done, *unknown_named_arg_passed;
@@ -362,8 +358,7 @@
   return copy_args_prologue;
 }
 
-Fragment PrologueBuilder::BuildFixedParameterLengthChecks(bool strong,
-                                                          JoinEntryInstr* nsm) {
+Fragment PrologueBuilder::BuildFixedParameterLengthChecks(JoinEntryInstr* nsm) {
   Fragment check_args;
   JoinEntryInstr* done = BuildJoinEntry();
 
@@ -449,24 +444,21 @@
   return handling;
 }
 
-void PrologueBuilder::SortOptionalNamedParametersInto(LocalVariable** opt_param,
-                                                      int* opt_param_position,
+void PrologueBuilder::SortOptionalNamedParametersInto(int* opt_param_position,
                                                       int num_fixed_params,
                                                       int num_params) {
-  LocalScope* scope = parsed_function_->node_sequence()->scope();
+  String& name = String::Handle(Z);
+  String& name_i = String::Handle(Z);
   for (int pos = num_fixed_params; pos < num_params; pos++) {
-    LocalVariable* parameter = scope->VariableAt(pos);
-    const String& opt_param_name = parameter->name();
+    name = function_.ParameterNameAt(pos);
     int i = pos - num_fixed_params;
     while (--i >= 0) {
-      LocalVariable* param_i = opt_param[i];
-      const intptr_t result = opt_param_name.CompareTo(param_i->name());
+      name_i = function_.ParameterNameAt(opt_param_position[i]);
+      const intptr_t result = name.CompareTo(name_i);
       ASSERT(result != 0);
       if (result > 0) break;
-      opt_param[i + 1] = opt_param[i];
       opt_param_position[i + 1] = opt_param_position[i];
     }
-    opt_param[i + 1] = parameter;
     opt_param_position[i + 1] = pos;
   }
 }
diff --git a/runtime/vm/compiler/frontend/prologue_builder.h b/runtime/vm/compiler/frontend/prologue_builder.h
index 30623d8..3f58e13 100644
--- a/runtime/vm/compiler/frontend/prologue_builder.h
+++ b/runtime/vm/compiler/frontend/prologue_builder.h
@@ -47,19 +47,19 @@
   BlockEntryInstr* BuildPrologue(BlockEntryInstr* entry,
                                  PrologueInfo* prologue_info);
 
+  Fragment BuildOptionalParameterHandling(JoinEntryInstr* nsm,
+                                          LocalVariable* temp_var);
+
   static bool HasEmptyPrologue(const Function& function);
   static bool PrologueSkippableOnUncheckedEntry(const Function& function);
 
   intptr_t last_used_block_id() const { return last_used_block_id_; }
 
  private:
-  Fragment BuildTypeArgumentsLengthCheck(bool strong,
-                                         JoinEntryInstr* nsm,
+  Fragment BuildTypeArgumentsLengthCheck(JoinEntryInstr* nsm,
                                          bool expect_type_args);
 
-  Fragment BuildOptionalParameterHandling(bool strong, JoinEntryInstr* nsm);
-
-  Fragment BuildFixedParameterLengthChecks(bool strong, JoinEntryInstr* nsm);
+  Fragment BuildFixedParameterLengthChecks(JoinEntryInstr* nsm);
 
   Fragment BuildClosureContextHandling();
 
@@ -79,8 +79,7 @@
     return Instance::null_instance();
   }
 
-  void SortOptionalNamedParametersInto(LocalVariable** opt_param,
-                                       int* opt_param_position,
+  void SortOptionalNamedParametersInto(int* opt_param_position,
                                        int num_fixed_params,
                                        int num_params);
 
diff --git a/runtime/vm/compiler/frontend/scope_builder.cc b/runtime/vm/compiler/frontend/scope_builder.cc
index 4baa72b..da11764 100644
--- a/runtime/vm/compiler/frontend/scope_builder.cc
+++ b/runtime/vm/compiler/frontend/scope_builder.cc
@@ -116,7 +116,7 @@
   scope_->set_end_token_pos(function.end_token_pos());
 
   // Add function type arguments variable before current context variable.
-  if (I->reify_generic_functions() &&
+  if (FLAG_reify_generic_functions &&
       (function.IsGeneric() || function.HasGenericParent())) {
     LocalVariable* type_args_var = MakeVariable(
         TokenPosition::kNoSource, TokenPosition::kNoSource,
diff --git a/runtime/vm/compiler/intrinsifier.cc b/runtime/vm/compiler/intrinsifier.cc
index 0d8fb526..fc1da04 100644
--- a/runtime/vm/compiler/intrinsifier.cc
+++ b/runtime/vm/compiler/intrinsifier.cc
@@ -293,11 +293,26 @@
   }
 #endif
 
+#if !defined(PRODUCT) && !defined(TARGET_ARCH_DBC)
+#define EMIT_BREAKPOINT() compiler->assembler()->Breakpoint()
+#else
+#define EMIT_BREAKPOINT()
+#endif
+
 #define EMIT_CASE(class_name, function_name, enum_name, type, fp)              \
-  case MethodRecognizer::k##enum_name:                                         \
+  case MethodRecognizer::k##enum_name: {                                       \
     compiler->assembler()->Comment("Intrinsic");                               \
-    enum_name(compiler->assembler());                                          \
-    break;
+    Label normal_ir_body;                                                      \
+    const auto size_before = compiler->assembler()->CodeSize();                \
+    enum_name(compiler->assembler(), &normal_ir_body);                         \
+    const auto size_after = compiler->assembler()->CodeSize();                 \
+    if (size_before == size_after) return false;                               \
+    if (!normal_ir_body.IsBound()) {                                           \
+      EMIT_BREAKPOINT();                                                       \
+      return true;                                                             \
+    }                                                                          \
+    return false;                                                              \
+  }
 
   switch (function.recognized_kind()) {
     ALL_INTRINSICS_NO_INTEGER_LIB_LIST(EMIT_CASE);
@@ -320,6 +335,8 @@
   }
 #endif
 
+#undef EMIT_BREAKPOINT
+
 #undef EMIT_INTRINSIC
   return false;
 }
@@ -960,12 +977,13 @@
   return true;
 }
 
-void Intrinsifier::ObjectArraySetIndexed(Assembler* assembler) {
+void Intrinsifier::ObjectArraySetIndexed(Assembler* assembler,
+                                         Label* normal_ir_body) {
   if (Isolate::Current()->argument_type_checks()) {
     return;
   }
 
-  ObjectArraySetIndexedUnchecked(assembler);
+  ObjectArraySetIndexedUnchecked(assembler, normal_ir_body);
 }
 
 bool Intrinsifier::Build_GrowableArraySetIndexed(FlowGraph* flow_graph) {
@@ -1222,20 +1240,24 @@
   return BuildInvokeMathCFunction(&builder, MethodRecognizer::kDoubleRound);
 }
 
-void Intrinsifier::String_identityHash(Assembler* assembler) {
-  String_getHashCode(assembler);
+void Intrinsifier::String_identityHash(Assembler* assembler,
+                                       Label* normal_ir_body) {
+  String_getHashCode(assembler, normal_ir_body);
 }
 
-void Intrinsifier::Double_identityHash(Assembler* assembler) {
-  Double_hashCode(assembler);
+void Intrinsifier::Double_identityHash(Assembler* assembler,
+                                       Label* normal_ir_body) {
+  Double_hashCode(assembler, normal_ir_body);
 }
 
-void Intrinsifier::RegExp_ExecuteMatch(Assembler* assembler) {
-  IntrinsifyRegExpExecuteMatch(assembler, /*sticky=*/false);
+void Intrinsifier::RegExp_ExecuteMatch(Assembler* assembler,
+                                       Label* normal_ir_body) {
+  IntrinsifyRegExpExecuteMatch(assembler, normal_ir_body, /*sticky=*/false);
 }
 
-void Intrinsifier::RegExp_ExecuteMatchSticky(Assembler* assembler) {
-  IntrinsifyRegExpExecuteMatch(assembler, /*sticky=*/true);
+void Intrinsifier::RegExp_ExecuteMatchSticky(Assembler* assembler,
+                                             Label* normal_ir_body) {
+  IntrinsifyRegExpExecuteMatch(assembler, normal_ir_body, /*sticky=*/true);
 }
 #endif  // !defined(TARGET_ARCH_DBC)
 
diff --git a/runtime/vm/compiler/intrinsifier.h b/runtime/vm/compiler/intrinsifier.h
index bf2ec2a..be8a563 100644
--- a/runtime/vm/compiler/intrinsifier.h
+++ b/runtime/vm/compiler/intrinsifier.h
@@ -13,6 +13,7 @@
 
 // Forward declarations.
 class Assembler;
+class Label;
 class FlowGraphCompiler;
 class Function;
 class TargetEntryInstr;
@@ -43,7 +44,7 @@
   static bool CanIntrinsify(const Function& function);
 
 #define DECLARE_FUNCTION(class_name, function_name, enum_name, type, fp)       \
-  static void enum_name(Assembler* assembler);
+  static void enum_name(Assembler* assembler, Label* normal_ir_body);
 
   ALL_INTRINSICS_LIST(DECLARE_FUNCTION)
 #if defined(TARGET_ARCH_DBC)
@@ -61,7 +62,9 @@
 
 #undef DECLARE_FUNCTION
 
-  static void IntrinsifyRegExpExecuteMatch(Assembler* assembler, bool sticky);
+  static void IntrinsifyRegExpExecuteMatch(Assembler* assembler,
+                                           Label* normal_ir_body,
+                                           bool sticky);
 #endif
 };
 
diff --git a/runtime/vm/compiler/intrinsifier_arm.cc b/runtime/vm/compiler/intrinsifier_arm.cc
index 7c0ff38..76c4593 100644
--- a/runtime/vm/compiler/intrinsifier_arm.cc
+++ b/runtime/vm/compiler/intrinsifier_arm.cc
@@ -54,19 +54,19 @@
 }
 
 // Intrinsify only for Smi index.
-void Intrinsifier::ObjectArraySetIndexedUnchecked(Assembler* assembler) {
-  Label fall_through;
+void Intrinsifier::ObjectArraySetIndexedUnchecked(Assembler* assembler,
+                                                  Label* normal_ir_body) {
   __ ldr(R1, Address(SP, 1 * kWordSize));  // Index.
   __ tst(R1, Operand(kSmiTagMask));
   // Index not Smi.
-  __ b(&fall_through, NE);
+  __ b(normal_ir_body, NE);
   __ ldr(R0, Address(SP, 2 * kWordSize));  // Array.
 
   // Range check.
   __ ldr(R3, FieldAddress(R0, Array::length_offset()));  // Array length.
   __ cmp(R1, Operand(R3));
   // Runtime throws exception.
-  __ b(&fall_through, CS);
+  __ b(normal_ir_body, CS);
 
   // Note that R1 is Smi, i.e, times 2.
   ASSERT(kSmiTagShift == 1);
@@ -75,21 +75,21 @@
   __ StoreIntoObject(R0, FieldAddress(R1, Array::data_offset()), R2);
   // Caller is responsible for preserving the value if necessary.
   __ Ret();
-  __ Bind(&fall_through);
+  __ Bind(normal_ir_body);
 }
 
 // Allocate a GrowableObjectArray using the backing array specified.
 // On stack: type argument (+1), data (+0).
-void Intrinsifier::GrowableArray_Allocate(Assembler* assembler) {
+void Intrinsifier::GrowableArray_Allocate(Assembler* assembler,
+                                          Label* normal_ir_body) {
   // The newly allocated object is returned in R0.
   const intptr_t kTypeArgumentsOffset = 1 * kWordSize;
   const intptr_t kArrayOffset = 0 * kWordSize;
-  Label fall_through;
 
   // Try allocating in new space.
   const Class& cls = Class::Handle(
       Isolate::Current()->object_store()->growable_object_array_class());
-  __ TryAllocate(cls, &fall_through, R0, R1);
+  __ TryAllocate(cls, normal_ir_body, R0, R1);
 
   // Store backing array object in growable array object.
   __ ldr(R1, Address(SP, kArrayOffset));  // Data argument.
@@ -109,18 +109,18 @@
       R0, FieldAddress(R0, GrowableObjectArray::length_offset()), R1);
   __ Ret();  // Returns the newly allocated object in R0.
 
-  __ Bind(&fall_through);
+  __ Bind(normal_ir_body);
 }
 
 // Add an element to growable array if it doesn't need to grow, otherwise
 // call into regular code.
 // On stack: growable array (+1), value (+0).
-void Intrinsifier::GrowableArray_add(Assembler* assembler) {
+void Intrinsifier::GrowableArray_add(Assembler* assembler,
+                                     Label* normal_ir_body) {
   // In checked mode we need to type-check the incoming argument.
   if (Isolate::Current()->argument_type_checks()) {
     return;
   }
-  Label fall_through;
   // R0: Array.
   __ ldr(R0, Address(SP, 1 * kWordSize));
   // R1: length.
@@ -131,7 +131,7 @@
   __ ldr(R3, FieldAddress(R2, Array::length_offset()));
   // Compare length with capacity.
   __ cmp(R1, Operand(R3));
-  __ b(&fall_through, EQ);  // Must grow data.
+  __ b(normal_ir_body, EQ);  // Must grow data.
   const int32_t value_one = reinterpret_cast<int32_t>(Smi::New(1));
   // len = len + 1;
   __ add(R3, R1, Operand(value_one));
@@ -143,26 +143,26 @@
   __ StoreIntoObject(R2, FieldAddress(R1, Array::data_offset()), R0);
   __ LoadObject(R0, Object::null_object());
   __ Ret();
-  __ Bind(&fall_through);
+  __ Bind(normal_ir_body);
 }
 
 #define TYPED_ARRAY_ALLOCATION(type_name, cid, max_len, scale_shift)           \
   Label fall_through;                                                          \
   const intptr_t kArrayLengthStackOffset = 0 * kWordSize;                      \
   NOT_IN_PRODUCT(__ LoadAllocationStatsAddress(R2, cid));                      \
-  NOT_IN_PRODUCT(__ MaybeTraceAllocation(R2, &fall_through));                  \
+  NOT_IN_PRODUCT(__ MaybeTraceAllocation(R2, normal_ir_body));                 \
   __ ldr(R2, Address(SP, kArrayLengthStackOffset)); /* Array length. */        \
   /* Check that length is a positive Smi. */                                   \
   /* R2: requested array length argument. */                                   \
   __ tst(R2, Operand(kSmiTagMask));                                            \
-  __ b(&fall_through, NE);                                                     \
+  __ b(normal_ir_body, NE);                                                    \
   __ CompareImmediate(R2, 0);                                                  \
-  __ b(&fall_through, LT);                                                     \
+  __ b(normal_ir_body, LT);                                                    \
   __ SmiUntag(R2);                                                             \
   /* Check for maximum allowed length. */                                      \
   /* R2: untagged array length. */                                             \
   __ CompareImmediate(R2, max_len);                                            \
-  __ b(&fall_through, GT);                                                     \
+  __ b(normal_ir_body, GT);                                                    \
   __ mov(R2, Operand(R2, LSL, scale_shift));                                   \
   const intptr_t fixed_size_plus_alignment_padding =                           \
       sizeof(Raw##type_name) + kObjectAlignment - 1;                           \
@@ -173,7 +173,7 @@
                                                                                \
   /* R2: allocation size. */                                                   \
   __ adds(R1, R0, Operand(R2));                                                \
-  __ b(&fall_through, CS); /* Fail on unsigned overflow. */                    \
+  __ b(normal_ir_body, CS); /* Fail on unsigned overflow. */                   \
                                                                                \
   /* Check if the allocation fits into the remaining space. */                 \
   /* R0: potential new object start. */                                        \
@@ -181,7 +181,7 @@
   /* R2: allocation size. */                                                   \
   __ ldr(IP, Address(THR, Thread::end_offset()));                              \
   __ cmp(R1, Operand(IP));                                                     \
-  __ b(&fall_through, CS);                                                     \
+  __ b(normal_ir_body, CS);                                                    \
                                                                                \
   /* Successfully allocated the object(s), now update top to point to */       \
   /* next object start and initialize the object. */                           \
@@ -237,7 +237,7 @@
                                                                                \
   NOT_IN_PRODUCT(__ IncrementAllocationStatsWithSize(R4, R2, space));          \
   __ Ret();                                                                    \
-  __ Bind(&fall_through);
+  __ Bind(normal_ir_body);
 
 static int GetScaleFactor(intptr_t size) {
   switch (size) {
@@ -257,7 +257,8 @@
 }
 
 #define TYPED_DATA_ALLOCATOR(clazz)                                            \
-  void Intrinsifier::TypedData_##clazz##_factory(Assembler* assembler) {       \
+  void Intrinsifier::TypedData_##clazz##_factory(Assembler* assembler,         \
+                                                 Label* normal_ir_body) {      \
     intptr_t size = TypedData::ElementSizeInBytes(kTypedData##clazz##Cid);     \
     intptr_t max_len = TypedData::MaxNewSpaceElements(kTypedData##clazz##Cid); \
     int shift = GetScaleFactor(size);                                          \
@@ -274,52 +275,50 @@
   __ orr(TMP, R0, Operand(R1));
   __ tst(TMP, Operand(kSmiTagMask));
   __ b(not_smi, NE);
-  return;
 }
 
-void Intrinsifier::Integer_addFromInteger(Assembler* assembler) {
-  Label fall_through;
-  TestBothArgumentsSmis(assembler, &fall_through);  // Checks two smis.
+void Intrinsifier::Integer_addFromInteger(Assembler* assembler,
+                                          Label* normal_ir_body) {
+  TestBothArgumentsSmis(assembler, normal_ir_body);  // Checks two smis.
   __ adds(R0, R0, Operand(R1));                     // Adds.
   __ bx(LR, VC);                                    // Return if no overflow.
   // Otherwise fall through.
-  __ Bind(&fall_through);
+  __ Bind(normal_ir_body);
 }
 
-void Intrinsifier::Integer_add(Assembler* assembler) {
-  Integer_addFromInteger(assembler);
+void Intrinsifier::Integer_add(Assembler* assembler, Label* normal_ir_body) {
+  Integer_addFromInteger(assembler, normal_ir_body);
 }
 
-void Intrinsifier::Integer_subFromInteger(Assembler* assembler) {
-  Label fall_through;
-  TestBothArgumentsSmis(assembler, &fall_through);
+void Intrinsifier::Integer_subFromInteger(Assembler* assembler,
+                                          Label* normal_ir_body) {
+  TestBothArgumentsSmis(assembler, normal_ir_body);
   __ subs(R0, R0, Operand(R1));  // Subtract.
   __ bx(LR, VC);                 // Return if no overflow.
   // Otherwise fall through.
-  __ Bind(&fall_through);
+  __ Bind(normal_ir_body);
 }
 
-void Intrinsifier::Integer_sub(Assembler* assembler) {
-  Label fall_through;
-  TestBothArgumentsSmis(assembler, &fall_through);
+void Intrinsifier::Integer_sub(Assembler* assembler, Label* normal_ir_body) {
+  TestBothArgumentsSmis(assembler, normal_ir_body);
   __ subs(R0, R1, Operand(R0));  // Subtract.
   __ bx(LR, VC);                 // Return if no overflow.
   // Otherwise fall through.
-  __ Bind(&fall_through);
+  __ Bind(normal_ir_body);
 }
 
-void Intrinsifier::Integer_mulFromInteger(Assembler* assembler) {
-  Label fall_through;
-  TestBothArgumentsSmis(assembler, &fall_through);  // checks two smis
+void Intrinsifier::Integer_mulFromInteger(Assembler* assembler,
+                                          Label* normal_ir_body) {
+  TestBothArgumentsSmis(assembler, normal_ir_body);  // checks two smis
   __ SmiUntag(R0);           // Untags R0. We only want result shifted by one.
   __ smull(R0, IP, R0, R1);  // IP:R0 <- R0 * R1.
   __ cmp(IP, Operand(R0, ASR, 31));
   __ bx(LR, EQ);
-  __ Bind(&fall_through);  // Fall through on overflow.
+  __ Bind(normal_ir_body);  // Fall through on overflow.
 }
 
-void Intrinsifier::Integer_mul(Assembler* assembler) {
-  Integer_mulFromInteger(assembler);
+void Intrinsifier::Integer_mul(Assembler* assembler, Label* normal_ir_body) {
+  Integer_mulFromInteger(assembler, normal_ir_body);
 }
 
 // Optimizations:
@@ -366,7 +365,6 @@
   __ IntegerDivide(tmp, left, right, D1, D0);
 
   __ mls(result, right, tmp, left);  // result <- left - right * TMP
-  return;
 }
 
 // Implementation:
@@ -378,22 +376,22 @@
 //      res = res + right;
 //    }
 //  }
-void Intrinsifier::Integer_moduloFromInteger(Assembler* assembler) {
+void Intrinsifier::Integer_moduloFromInteger(Assembler* assembler,
+                                             Label* normal_ir_body) {
   if (!TargetCPUFeatures::can_divide()) {
     return;
   }
   // Check to see if we have integer division
-  Label fall_through;
   __ ldr(R1, Address(SP, +0 * kWordSize));
   __ ldr(R0, Address(SP, +1 * kWordSize));
   __ orr(TMP, R0, Operand(R1));
   __ tst(TMP, Operand(kSmiTagMask));
-  __ b(&fall_through, NE);
+  __ b(normal_ir_body, NE);
   // R1: Tagged left (dividend).
   // R0: Tagged right (divisor).
   // Check if modulo by zero -> exception thrown in main function.
   __ cmp(R0, Operand(0));
-  __ b(&fall_through, EQ);
+  __ b(normal_ir_body, EQ);
   EmitRemainderOperation(assembler);
   // Untagged right in R0. Untagged remainder result in R1.
 
@@ -408,19 +406,19 @@
   __ SmiTag(R0);
   __ Ret();
 
-  __ Bind(&fall_through);
+  __ Bind(normal_ir_body);
 }
 
-void Intrinsifier::Integer_truncDivide(Assembler* assembler) {
+void Intrinsifier::Integer_truncDivide(Assembler* assembler,
+                                       Label* normal_ir_body) {
   if (!TargetCPUFeatures::can_divide()) {
     return;
   }
   // Check to see if we have integer division
-  Label fall_through;
 
-  TestBothArgumentsSmis(assembler, &fall_through);
+  TestBothArgumentsSmis(assembler, normal_ir_body);
   __ cmp(R0, Operand(0));
-  __ b(&fall_through, EQ);  // If b is 0, fall through.
+  __ b(normal_ir_body, EQ);  // If b is 0, fall through.
 
   __ SmiUntag(R0);
   __ SmiUntag(R1);
@@ -432,69 +430,64 @@
   __ CompareImmediate(R0, 0x40000000);
   __ SmiTag(R0, NE);  // Not equal. Okay to tag and return.
   __ bx(LR, NE);      // Return.
-  __ Bind(&fall_through);
+  __ Bind(normal_ir_body);
 }
 
-void Intrinsifier::Integer_negate(Assembler* assembler) {
-  Label fall_through;
+void Intrinsifier::Integer_negate(Assembler* assembler, Label* normal_ir_body) {
   __ ldr(R0, Address(SP, +0 * kWordSize));  // Grab first argument.
   __ tst(R0, Operand(kSmiTagMask));         // Test for Smi.
-  __ b(&fall_through, NE);
+  __ b(normal_ir_body, NE);
   __ rsbs(R0, R0, Operand(0));  // R0 is a Smi. R0 <- 0 - R0.
   __ bx(LR, VC);  // Return if there wasn't overflow, fall through otherwise.
   // R0 is not a Smi. Fall through.
-  __ Bind(&fall_through);
+  __ Bind(normal_ir_body);
 }
 
-void Intrinsifier::Integer_bitAndFromInteger(Assembler* assembler) {
-  Label fall_through;
-
-  TestBothArgumentsSmis(assembler, &fall_through);  // checks two smis
+void Intrinsifier::Integer_bitAndFromInteger(Assembler* assembler,
+                                             Label* normal_ir_body) {
+  TestBothArgumentsSmis(assembler, normal_ir_body);  // checks two smis
   __ and_(R0, R0, Operand(R1));
 
   __ Ret();
-  __ Bind(&fall_through);
+  __ Bind(normal_ir_body);
 }
 
-void Intrinsifier::Integer_bitAnd(Assembler* assembler) {
-  Integer_bitAndFromInteger(assembler);
+void Intrinsifier::Integer_bitAnd(Assembler* assembler, Label* normal_ir_body) {
+  Integer_bitAndFromInteger(assembler, normal_ir_body);
 }
 
-void Intrinsifier::Integer_bitOrFromInteger(Assembler* assembler) {
-  Label fall_through;
-
-  TestBothArgumentsSmis(assembler, &fall_through);  // checks two smis
+void Intrinsifier::Integer_bitOrFromInteger(Assembler* assembler,
+                                            Label* normal_ir_body) {
+  TestBothArgumentsSmis(assembler, normal_ir_body);  // checks two smis
   __ orr(R0, R0, Operand(R1));
 
   __ Ret();
-  __ Bind(&fall_through);
+  __ Bind(normal_ir_body);
 }
 
-void Intrinsifier::Integer_bitOr(Assembler* assembler) {
-  Integer_bitOrFromInteger(assembler);
+void Intrinsifier::Integer_bitOr(Assembler* assembler, Label* normal_ir_body) {
+  Integer_bitOrFromInteger(assembler, normal_ir_body);
 }
 
-void Intrinsifier::Integer_bitXorFromInteger(Assembler* assembler) {
-  Label fall_through;
-
-  TestBothArgumentsSmis(assembler, &fall_through);  // checks two smis
+void Intrinsifier::Integer_bitXorFromInteger(Assembler* assembler,
+                                             Label* normal_ir_body) {
+  TestBothArgumentsSmis(assembler, normal_ir_body);  // checks two smis
   __ eor(R0, R0, Operand(R1));
 
   __ Ret();
-  __ Bind(&fall_through);
+  __ Bind(normal_ir_body);
 }
 
-void Intrinsifier::Integer_bitXor(Assembler* assembler) {
-  Integer_bitXorFromInteger(assembler);
+void Intrinsifier::Integer_bitXor(Assembler* assembler, Label* normal_ir_body) {
+  Integer_bitXorFromInteger(assembler, normal_ir_body);
 }
 
-void Intrinsifier::Integer_shl(Assembler* assembler) {
+void Intrinsifier::Integer_shl(Assembler* assembler, Label* normal_ir_body) {
   ASSERT(kSmiTagShift == 1);
   ASSERT(kSmiTag == 0);
-  Label fall_through;
-  TestBothArgumentsSmis(assembler, &fall_through);
+  TestBothArgumentsSmis(assembler, normal_ir_body);
   __ CompareImmediate(R0, Smi::RawValue(Smi::kBits));
-  __ b(&fall_through, HI);
+  __ b(normal_ir_body, HI);
 
   __ SmiUntag(R0);
 
@@ -509,7 +502,7 @@
 
   // Arguments are Smi but the shift produced an overflow to Mint.
   __ CompareImmediate(R1, 0);
-  __ b(&fall_through, LT);
+  __ b(normal_ir_body, LT);
   __ SmiUntag(R1);
 
   // Pull off high bits that will be shifted off of R1 by making a mask
@@ -528,12 +521,12 @@
 
   const Class& mint_class =
       Class::Handle(Isolate::Current()->object_store()->mint_class());
-  __ TryAllocate(mint_class, &fall_through, R0, R2);
+  __ TryAllocate(mint_class, normal_ir_body, R0, R2);
 
   __ str(R1, FieldAddress(R0, Mint::value_offset()));
   __ str(NOTFP, FieldAddress(R0, Mint::value_offset() + kWordSize));
   __ Ret();
-  __ Bind(&fall_through);
+  __ Bind(normal_ir_body);
 }
 
 static void Get64SmiOrMint(Assembler* assembler,
@@ -559,10 +552,11 @@
   __ ldr(res_lo, FieldAddress(reg, Mint::value_offset()));
   __ ldr(res_hi, FieldAddress(reg, Mint::value_offset() + kWordSize));
   __ Bind(&done);
-  return;
 }
 
-static void CompareIntegers(Assembler* assembler, Condition true_condition) {
+static void CompareIntegers(Assembler* assembler,
+                            Label* normal_ir_body,
+                            Condition true_condition) {
   Label try_mint_smi, is_true, is_false, drop_two_fall_through, fall_through;
   TestBothArgumentsSmis(assembler, &try_mint_smi);
   // R0 contains the right argument. R1 contains left argument
@@ -598,9 +592,9 @@
 
   __ Bind(&try_mint_smi);
   // Get left as 64 bit integer.
-  Get64SmiOrMint(assembler, R3, R2, R1, &fall_through);
+  Get64SmiOrMint(assembler, R3, R2, R1, normal_ir_body);
   // Get right as 64 bit integer.
-  Get64SmiOrMint(assembler, NOTFP, R8, R0, &fall_through);
+  Get64SmiOrMint(assembler, NOTFP, R8, R0, normal_ir_body);
   // R3: left high.
   // R2: left low.
   // NOTFP: right high.
@@ -614,33 +608,39 @@
   // Else is true.
   __ b(&is_true);
 
-  __ Bind(&fall_through);
+  __ Bind(normal_ir_body);
 }
 
-void Intrinsifier::Integer_greaterThanFromInt(Assembler* assembler) {
-  CompareIntegers(assembler, LT);
+void Intrinsifier::Integer_greaterThanFromInt(Assembler* assembler,
+                                              Label* normal_ir_body) {
+  CompareIntegers(assembler, normal_ir_body, LT);
 }
 
-void Intrinsifier::Integer_lessThan(Assembler* assembler) {
-  Integer_greaterThanFromInt(assembler);
+void Intrinsifier::Integer_lessThan(Assembler* assembler,
+                                    Label* normal_ir_body) {
+  Integer_greaterThanFromInt(assembler, normal_ir_body);
 }
 
-void Intrinsifier::Integer_greaterThan(Assembler* assembler) {
-  CompareIntegers(assembler, GT);
+void Intrinsifier::Integer_greaterThan(Assembler* assembler,
+                                       Label* normal_ir_body) {
+  CompareIntegers(assembler, normal_ir_body, GT);
 }
 
-void Intrinsifier::Integer_lessEqualThan(Assembler* assembler) {
-  CompareIntegers(assembler, LE);
+void Intrinsifier::Integer_lessEqualThan(Assembler* assembler,
+                                         Label* normal_ir_body) {
+  CompareIntegers(assembler, normal_ir_body, LE);
 }
 
-void Intrinsifier::Integer_greaterEqualThan(Assembler* assembler) {
-  CompareIntegers(assembler, GE);
+void Intrinsifier::Integer_greaterEqualThan(Assembler* assembler,
+                                            Label* normal_ir_body) {
+  CompareIntegers(assembler, normal_ir_body, GE);
 }
 
 // This is called for Smi and Mint receivers. The right argument
 // can be Smi, Mint or double.
-void Intrinsifier::Integer_equalToInteger(Assembler* assembler) {
-  Label fall_through, true_label, check_for_mint;
+void Intrinsifier::Integer_equalToInteger(Assembler* assembler,
+                                          Label* normal_ir_body) {
+  Label true_label, check_for_mint;
   // For integer receiver '===' check first.
   __ ldr(R0, Address(SP, 0 * kWordSize));
   __ ldr(R1, Address(SP, 1 * kWordSize));
@@ -670,7 +670,7 @@
   // represented by Smi.
 
   __ CompareClassId(R0, kDoubleCid, R2);
-  __ b(&fall_through, EQ);
+  __ b(normal_ir_body, EQ);
   __ LoadObject(R0, Bool::False());  // Smi == Mint -> false.
   __ Ret();
 
@@ -678,30 +678,28 @@
   // R1:: receiver.
 
   __ CompareClassId(R1, kMintCid, R2);
-  __ b(&fall_through, NE);
+  __ b(normal_ir_body, NE);
   // Receiver is Mint, return false if right is Smi.
   __ tst(R0, Operand(kSmiTagMask));
   __ LoadObject(R0, Bool::False(), EQ);
   __ bx(LR, EQ);
   // TODO(srdjan): Implement Mint == Mint comparison.
 
-  __ Bind(&fall_through);
+  __ Bind(normal_ir_body);
 }
 
-void Intrinsifier::Integer_equal(Assembler* assembler) {
-  Integer_equalToInteger(assembler);
+void Intrinsifier::Integer_equal(Assembler* assembler, Label* normal_ir_body) {
+  Integer_equalToInteger(assembler, normal_ir_body);
 }
 
-void Intrinsifier::Integer_sar(Assembler* assembler) {
-  Label fall_through;
-
-  TestBothArgumentsSmis(assembler, &fall_through);
+void Intrinsifier::Integer_sar(Assembler* assembler, Label* normal_ir_body) {
+  TestBothArgumentsSmis(assembler, normal_ir_body);
   // Shift amount in R0. Value to shift in R1.
 
   // Fall through if shift amount is negative.
   __ SmiUntag(R0);
   __ CompareImmediate(R0, 0);
-  __ b(&fall_through, LT);
+  __ b(normal_ir_body, LT);
 
   // If shift amount is bigger than 31, set to 31.
   __ CompareImmediate(R0, 0x1F);
@@ -710,17 +708,17 @@
   __ mov(R0, Operand(R1, ASR, R0));
   __ SmiTag(R0);
   __ Ret();
-  __ Bind(&fall_through);
+  __ Bind(normal_ir_body);
 }
 
-void Intrinsifier::Smi_bitNegate(Assembler* assembler) {
+void Intrinsifier::Smi_bitNegate(Assembler* assembler, Label* normal_ir_body) {
   __ ldr(R0, Address(SP, 0 * kWordSize));
   __ mvn(R0, Operand(R0));
   __ bic(R0, R0, Operand(kSmiTagMask));  // Remove inverted smi-tag.
   __ Ret();
 }
 
-void Intrinsifier::Smi_bitLength(Assembler* assembler) {
+void Intrinsifier::Smi_bitLength(Assembler* assembler, Label* normal_ir_body) {
   __ ldr(R0, Address(SP, 0 * kWordSize));
   __ SmiUntag(R0);
   // XOR with sign bit to complement bits if value is negative.
@@ -731,11 +729,12 @@
   __ Ret();
 }
 
-void Intrinsifier::Smi_bitAndFromSmi(Assembler* assembler) {
-  Integer_bitAndFromInteger(assembler);
+void Intrinsifier::Smi_bitAndFromSmi(Assembler* assembler,
+                                     Label* normal_ir_body) {
+  Integer_bitAndFromInteger(assembler, normal_ir_body);
 }
 
-void Intrinsifier::Bigint_lsh(Assembler* assembler) {
+void Intrinsifier::Bigint_lsh(Assembler* assembler, Label* normal_ir_body) {
   // static void _lsh(Uint32List x_digits, int x_used, int n,
   //                  Uint32List r_digits)
 
@@ -775,7 +774,7 @@
   __ Ret();
 }
 
-void Intrinsifier::Bigint_rsh(Assembler* assembler) {
+void Intrinsifier::Bigint_rsh(Assembler* assembler, Label* normal_ir_body) {
   // static void _lsh(Uint32List x_digits, int x_used, int n,
   //                  Uint32List r_digits)
 
@@ -818,7 +817,7 @@
   __ Ret();
 }
 
-void Intrinsifier::Bigint_absAdd(Assembler* assembler) {
+void Intrinsifier::Bigint_absAdd(Assembler* assembler, Label* normal_ir_body) {
   // static void _absAdd(Uint32List digits, int used,
   //                     Uint32List a_digits, int a_used,
   //                     Uint32List r_digits)
@@ -877,7 +876,7 @@
   __ Ret();
 }
 
-void Intrinsifier::Bigint_absSub(Assembler* assembler) {
+void Intrinsifier::Bigint_absSub(Assembler* assembler, Label* normal_ir_body) {
   // static void _absSub(Uint32List digits, int used,
   //                     Uint32List a_digits, int a_used,
   //                     Uint32List r_digits)
@@ -932,7 +931,7 @@
   __ Ret();
 }
 
-void Intrinsifier::Bigint_mulAdd(Assembler* assembler) {
+void Intrinsifier::Bigint_mulAdd(Assembler* assembler, Label* normal_ir_body) {
   // Pseudo code:
   // static int _mulAdd(Uint32List x_digits, int xi,
   //                    Uint32List m_digits, int i,
@@ -1033,7 +1032,7 @@
   __ Ret();
 }
 
-void Intrinsifier::Bigint_sqrAdd(Assembler* assembler) {
+void Intrinsifier::Bigint_sqrAdd(Assembler* assembler, Label* normal_ir_body) {
   // Pseudo code:
   // static int _sqrAdd(Uint32List x_digits, int i,
   //                    Uint32List a_digits, int used) {
@@ -1146,11 +1145,13 @@
   __ Ret();
 }
 
-void Intrinsifier::Bigint_estimateQuotientDigit(Assembler* assembler) {
+void Intrinsifier::Bigint_estimateQuotientDigit(Assembler* assembler,
+                                                Label* normal_ir_body) {
   // No unsigned 64-bit / 32-bit divide instruction.
 }
 
-void Intrinsifier::Montgomery_mulMod(Assembler* assembler) {
+void Intrinsifier::Montgomery_mulMod(Assembler* assembler,
+                                     Label* normal_ir_body) {
   // Pseudo code:
   // static int _mulMod(Uint32List args, Uint32List digits, int i) {
   //   uint32_t rho = args[_RHO];  // _RHO == 2.
@@ -1201,11 +1202,13 @@
 // type. Return true or false object in the register R0. Any NaN argument
 // returns false. Any non-double arg1 causes control flow to fall through to the
 // slow case (compiled method body).
-static void CompareDoubles(Assembler* assembler, Condition true_condition) {
+static void CompareDoubles(Assembler* assembler,
+                           Label* normal_ir_body,
+                           Condition true_condition) {
   if (TargetCPUFeatures::vfp_supported()) {
-    Label fall_through, is_smi, double_op;
+    Label is_smi, double_op;
 
-    TestLastArgumentIsDouble(assembler, &is_smi, &fall_through);
+    TestLastArgumentIsDouble(assembler, &is_smi, normal_ir_body);
     // Both arguments are double, right operand is in R0.
 
     __ LoadDFromOffset(D1, R0, Double::value_offset() - kHeapObjectTag);
@@ -1226,37 +1229,43 @@
     __ vmovsr(S0, R0);
     __ vcvtdi(D1, S0);
     __ b(&double_op);  // Then do the comparison.
-    __ Bind(&fall_through);
+    __ Bind(normal_ir_body);
   }
 }
 
-void Intrinsifier::Double_greaterThan(Assembler* assembler) {
-  CompareDoubles(assembler, HI);
+void Intrinsifier::Double_greaterThan(Assembler* assembler,
+                                      Label* normal_ir_body) {
+  CompareDoubles(assembler, normal_ir_body, HI);
 }
 
-void Intrinsifier::Double_greaterEqualThan(Assembler* assembler) {
-  CompareDoubles(assembler, CS);
+void Intrinsifier::Double_greaterEqualThan(Assembler* assembler,
+                                           Label* normal_ir_body) {
+  CompareDoubles(assembler, normal_ir_body, CS);
 }
 
-void Intrinsifier::Double_lessThan(Assembler* assembler) {
-  CompareDoubles(assembler, CC);
+void Intrinsifier::Double_lessThan(Assembler* assembler,
+                                   Label* normal_ir_body) {
+  CompareDoubles(assembler, normal_ir_body, CC);
 }
 
-void Intrinsifier::Double_equal(Assembler* assembler) {
-  CompareDoubles(assembler, EQ);
+void Intrinsifier::Double_equal(Assembler* assembler, Label* normal_ir_body) {
+  CompareDoubles(assembler, normal_ir_body, EQ);
 }
 
-void Intrinsifier::Double_lessEqualThan(Assembler* assembler) {
-  CompareDoubles(assembler, LS);
+void Intrinsifier::Double_lessEqualThan(Assembler* assembler,
+                                        Label* normal_ir_body) {
+  CompareDoubles(assembler, normal_ir_body, LS);
 }
 
 // Expects left argument to be double (receiver). Right argument is unknown.
 // Both arguments are on stack.
-static void DoubleArithmeticOperations(Assembler* assembler, Token::Kind kind) {
+static void DoubleArithmeticOperations(Assembler* assembler,
+                                       Label* normal_ir_body,
+                                       Token::Kind kind) {
   if (TargetCPUFeatures::vfp_supported()) {
-    Label fall_through, is_smi, double_op;
+    Label is_smi, double_op;
 
-    TestLastArgumentIsDouble(assembler, &is_smi, &fall_through);
+    TestLastArgumentIsDouble(assembler, &is_smi, normal_ir_body);
     // Both arguments are double, right operand is in R0.
     __ LoadDFromOffset(D1, R0, Double::value_offset() - kHeapObjectTag);
     __ Bind(&double_op);
@@ -1280,7 +1289,8 @@
     }
     const Class& double_class =
         Class::Handle(Isolate::Current()->object_store()->double_class());
-    __ TryAllocate(double_class, &fall_through, R0, R1);  // Result register.
+    __ TryAllocate(double_class, normal_ir_body, R0,
+                   R1);  // Result register.
     __ StoreDToOffset(D0, R0, Double::value_offset() - kHeapObjectTag);
     __ Ret();
     __ Bind(&is_smi);  // Convert R0 to a double.
@@ -1288,34 +1298,35 @@
     __ vmovsr(S0, R0);
     __ vcvtdi(D1, S0);
     __ b(&double_op);
-    __ Bind(&fall_through);
+    __ Bind(normal_ir_body);
   }
 }
 
-void Intrinsifier::Double_add(Assembler* assembler) {
-  DoubleArithmeticOperations(assembler, Token::kADD);
+void Intrinsifier::Double_add(Assembler* assembler, Label* normal_ir_body) {
+  DoubleArithmeticOperations(assembler, normal_ir_body, Token::kADD);
 }
 
-void Intrinsifier::Double_mul(Assembler* assembler) {
-  DoubleArithmeticOperations(assembler, Token::kMUL);
+void Intrinsifier::Double_mul(Assembler* assembler, Label* normal_ir_body) {
+  DoubleArithmeticOperations(assembler, normal_ir_body, Token::kMUL);
 }
 
-void Intrinsifier::Double_sub(Assembler* assembler) {
-  DoubleArithmeticOperations(assembler, Token::kSUB);
+void Intrinsifier::Double_sub(Assembler* assembler, Label* normal_ir_body) {
+  DoubleArithmeticOperations(assembler, normal_ir_body, Token::kSUB);
 }
 
-void Intrinsifier::Double_div(Assembler* assembler) {
-  DoubleArithmeticOperations(assembler, Token::kDIV);
+void Intrinsifier::Double_div(Assembler* assembler, Label* normal_ir_body) {
+  DoubleArithmeticOperations(assembler, normal_ir_body, Token::kDIV);
 }
 
 // Left is double, right is integer (Mint or Smi)
-void Intrinsifier::Double_mulFromInteger(Assembler* assembler) {
+void Intrinsifier::Double_mulFromInteger(Assembler* assembler,
+                                         Label* normal_ir_body) {
   if (TargetCPUFeatures::vfp_supported()) {
     Label fall_through;
     // Only smis allowed.
     __ ldr(R0, Address(SP, 0 * kWordSize));
     __ tst(R0, Operand(kSmiTagMask));
-    __ b(&fall_through, NE);
+    __ b(normal_ir_body, NE);
     // Is Smi.
     __ SmiUntag(R0);
     __ vmovsr(S0, R0);
@@ -1325,36 +1336,39 @@
     __ vmuld(D0, D0, D1);
     const Class& double_class =
         Class::Handle(Isolate::Current()->object_store()->double_class());
-    __ TryAllocate(double_class, &fall_through, R0, R1);  // Result register.
+    __ TryAllocate(double_class, normal_ir_body, R0,
+                   R1);  // Result register.
     __ StoreDToOffset(D0, R0, Double::value_offset() - kHeapObjectTag);
     __ Ret();
-    __ Bind(&fall_through);
+    __ Bind(normal_ir_body);
   }
 }
 
-void Intrinsifier::DoubleFromInteger(Assembler* assembler) {
+void Intrinsifier::DoubleFromInteger(Assembler* assembler,
+                                     Label* normal_ir_body) {
   if (TargetCPUFeatures::vfp_supported()) {
     Label fall_through;
 
     __ ldr(R0, Address(SP, 0 * kWordSize));
     __ tst(R0, Operand(kSmiTagMask));
-    __ b(&fall_through, NE);
+    __ b(normal_ir_body, NE);
     // Is Smi.
     __ SmiUntag(R0);
     __ vmovsr(S0, R0);
     __ vcvtdi(D0, S0);
     const Class& double_class =
         Class::Handle(Isolate::Current()->object_store()->double_class());
-    __ TryAllocate(double_class, &fall_through, R0, R1);  // Result register.
+    __ TryAllocate(double_class, normal_ir_body, R0,
+                   R1);  // Result register.
     __ StoreDToOffset(D0, R0, Double::value_offset() - kHeapObjectTag);
     __ Ret();
-    __ Bind(&fall_through);
+    __ Bind(normal_ir_body);
   }
 }
 
-void Intrinsifier::Double_getIsNaN(Assembler* assembler) {
+void Intrinsifier::Double_getIsNaN(Assembler* assembler,
+                                   Label* normal_ir_body) {
   if (TargetCPUFeatures::vfp_supported()) {
-    Label is_true;
     __ ldr(R0, Address(SP, 0 * kWordSize));
     __ LoadDFromOffset(D0, R0, Double::value_offset() - kHeapObjectTag);
     __ vcmpd(D0, D0);
@@ -1365,7 +1379,8 @@
   }
 }
 
-void Intrinsifier::Double_getIsInfinite(Assembler* assembler) {
+void Intrinsifier::Double_getIsInfinite(Assembler* assembler,
+                                        Label* normal_ir_body) {
   if (TargetCPUFeatures::vfp_supported()) {
     __ ldr(R0, Address(SP, 0 * kWordSize));
     // R1 <- value[0:31], R2 <- value[32:63]
@@ -1389,7 +1404,8 @@
   }
 }
 
-void Intrinsifier::Double_getIsNegative(Assembler* assembler) {
+void Intrinsifier::Double_getIsNegative(Assembler* assembler,
+                                        Label* normal_ir_body) {
   if (TargetCPUFeatures::vfp_supported()) {
     Label is_false, is_true, is_zero;
     __ ldr(R0, Address(SP, 0 * kWordSize));
@@ -1418,7 +1434,8 @@
   }
 }
 
-void Intrinsifier::DoubleToInteger(Assembler* assembler) {
+void Intrinsifier::DoubleToInteger(Assembler* assembler,
+                                   Label* normal_ir_body) {
   if (TargetCPUFeatures::vfp_supported()) {
     Label fall_through;
 
@@ -1429,7 +1446,7 @@
     // convert NaN to an int.
     __ vcmpd(D0, D0);
     __ vmstat();
-    __ b(&fall_through, VS);
+    __ b(normal_ir_body, VS);
 
     __ vcvtid(S0, D0);
     __ vmovrs(R0, S0);
@@ -1438,11 +1455,12 @@
     __ CompareImmediate(R0, 0xC0000000);
     __ SmiTag(R0, PL);
     __ bx(LR, PL);
-    __ Bind(&fall_through);
+    __ Bind(normal_ir_body);
   }
 }
 
-void Intrinsifier::Double_hashCode(Assembler* assembler) {
+void Intrinsifier::Double_hashCode(Assembler* assembler,
+                                   Label* normal_ir_body) {
   // TODO(dartbug.com/31174): Convert this to a graph intrinsic.
 
   if (!TargetCPUFeatures::vfp_supported()) return;
@@ -1464,10 +1482,9 @@
   // overflow in the conversion from double to int. Conversion
   // overflow is signalled by vcvt through clamping R0 to either
   // INT32_MAX or INT32_MIN (saturation).
-  Label fall_through;
   ASSERT(kSmiTag == 0 && kSmiTagShift == 1);
   __ adds(R0, R0, Operand(R0));
-  __ b(&fall_through, VS);
+  __ b(normal_ir_body, VS);
 
   // Compare the two double values. If they are equal, we return the
   // Smi tagged result immediately as the hash code.
@@ -1486,20 +1503,21 @@
   __ Ret();
 
   // Fall into the native C++ implementation.
-  __ Bind(&fall_through);
+  __ Bind(normal_ir_body);
 }
 
-void Intrinsifier::MathSqrt(Assembler* assembler) {
+void Intrinsifier::MathSqrt(Assembler* assembler, Label* normal_ir_body) {
   if (TargetCPUFeatures::vfp_supported()) {
-    Label fall_through, is_smi, double_op;
-    TestLastArgumentIsDouble(assembler, &is_smi, &fall_through);
+    Label is_smi, double_op;
+    TestLastArgumentIsDouble(assembler, &is_smi, normal_ir_body);
     // Argument is double and is in R0.
     __ LoadDFromOffset(D1, R0, Double::value_offset() - kHeapObjectTag);
     __ Bind(&double_op);
     __ vsqrtd(D0, D1);
     const Class& double_class =
         Class::Handle(Isolate::Current()->object_store()->double_class());
-    __ TryAllocate(double_class, &fall_through, R0, R1);  // Result register.
+    __ TryAllocate(double_class, normal_ir_body, R0,
+                   R1);  // Result register.
     __ StoreDToOffset(D0, R0, Double::value_offset() - kHeapObjectTag);
     __ Ret();
     __ Bind(&is_smi);
@@ -1507,14 +1525,15 @@
     __ vmovsr(S0, R0);
     __ vcvtdi(D1, S0);
     __ b(&double_op);
-    __ Bind(&fall_through);
+    __ Bind(normal_ir_body);
   }
 }
 
 //    var state = ((_A * (_state[kSTATE_LO])) + _state[kSTATE_HI]) & _MASK_64;
 //    _state[kSTATE_LO] = state & _MASK_32;
 //    _state[kSTATE_HI] = state >> 32;
-void Intrinsifier::Random_nextState(Assembler* assembler) {
+void Intrinsifier::Random_nextState(Assembler* assembler,
+                                    Label* normal_ir_body) {
   const Library& math_lib = Library::Handle(Library::MathLibrary());
   ASSERT(!math_lib.IsNull());
   const Class& random_class =
@@ -1551,7 +1570,7 @@
   __ Ret();
 }
 
-void Intrinsifier::ObjectEquals(Assembler* assembler) {
+void Intrinsifier::ObjectEquals(Assembler* assembler, Label* normal_ir_body) {
   __ ldr(R0, Address(SP, 0 * kWordSize));
   __ ldr(R1, Address(SP, 1 * kWordSize));
   __ cmp(R0, Operand(R1));
@@ -1606,13 +1625,14 @@
 }
 
 // Return type quickly for simple types (not parameterized and not signature).
-void Intrinsifier::ObjectRuntimeType(Assembler* assembler) {
-  Label fall_through, use_canonical_type, not_double, not_integer;
+void Intrinsifier::ObjectRuntimeType(Assembler* assembler,
+                                     Label* normal_ir_body) {
+  Label use_canonical_type, not_double, not_integer;
   __ ldr(R0, Address(SP, 0 * kWordSize));
   __ LoadClassIdMayBeSmi(R1, R0);
 
   __ CompareImmediate(R1, kClosureCid);
-  __ b(&fall_through, EQ);  // Instance is a closure.
+  __ b(normal_ir_body, EQ);  // Instance is a closure.
 
   __ CompareImmediate(R1, kNumPredefinedCids);
   __ b(&use_canonical_type, HI);
@@ -1643,24 +1663,25 @@
   __ LoadClassById(R2, R1);  // Overwrites R1.
   __ ldrh(R3, FieldAddress(R2, Class::num_type_arguments_offset()));
   __ CompareImmediate(R3, 0);
-  __ b(&fall_through, NE);
+  __ b(normal_ir_body, NE);
 
   __ ldr(R0, FieldAddress(R2, Class::canonical_type_offset()));
   __ CompareObject(R0, Object::null_object());
-  __ b(&fall_through, EQ);
+  __ b(normal_ir_body, EQ);
   __ Ret();
 
-  __ Bind(&fall_through);
+  __ Bind(normal_ir_body);
 }
 
-void Intrinsifier::ObjectHaveSameRuntimeType(Assembler* assembler) {
-  Label fall_through, different_cids, equal, not_equal, not_integer;
+void Intrinsifier::ObjectHaveSameRuntimeType(Assembler* assembler,
+                                             Label* normal_ir_body) {
+  Label different_cids, equal, not_equal, not_integer;
   __ ldr(R0, Address(SP, 0 * kWordSize));
   __ LoadClassIdMayBeSmi(R1, R0);
 
   // Check if left hand size is a closure. Closures are handled in the runtime.
   __ CompareImmediate(R1, kClosureCid);
-  __ b(&fall_through, EQ);
+  __ b(normal_ir_body, EQ);
 
   __ ldr(R0, Address(SP, 1 * kWordSize));
   __ LoadClassIdMayBeSmi(R2, R0);
@@ -1677,7 +1698,7 @@
   __ LoadClassById(R3, R1);
   __ ldrh(R3, FieldAddress(R3, Class::num_type_arguments_offset()));
   __ CompareImmediate(R3, 0);
-  __ b(&fall_through, NE);
+  __ b(normal_ir_body, NE);
 
   __ Bind(&equal);
   __ LoadObject(R0, Bool::True());
@@ -1704,21 +1725,27 @@
   __ LoadObject(R0, Bool::False());
   __ Ret();
 
-  __ Bind(&fall_through);
+  __ Bind(normal_ir_body);
 }
 
-void Intrinsifier::String_getHashCode(Assembler* assembler) {
+void Intrinsifier::String_getHashCode(Assembler* assembler,
+                                      Label* normal_ir_body) {
   __ ldr(R0, Address(SP, 0 * kWordSize));
   __ ldr(R0, FieldAddress(R0, String::hash_offset()));
   __ cmp(R0, Operand(0));
-  __ bx(LR, NE);  // Hash not yet computed.
+  __ bx(LR, NE);
+  // Hash not yet computed.
+  __ Bind(normal_ir_body);
 }
 
-void Intrinsifier::Type_getHashCode(Assembler* assembler) {
+void Intrinsifier::Type_getHashCode(Assembler* assembler,
+                                    Label* normal_ir_body) {
   __ ldr(R0, Address(SP, 0 * kWordSize));
   __ ldr(R0, FieldAddress(R0, Type::hash_offset()));
   __ cmp(R0, Operand(0));
-  __ bx(LR, NE);  // Hash not yet computed.
+  __ bx(LR, NE);
+  // Hash not yet computed.
+  __ Bind(normal_ir_body);
 }
 
 void GenerateSubstringMatchesSpecialization(Assembler* assembler,
@@ -1794,18 +1821,19 @@
 // bool _substringMatches(int start, String other)
 // This intrinsic handles a OneByteString or TwoByteString receiver with a
 // OneByteString other.
-void Intrinsifier::StringBaseSubstringMatches(Assembler* assembler) {
-  Label fall_through, return_true, return_false, try_two_byte;
+void Intrinsifier::StringBaseSubstringMatches(Assembler* assembler,
+                                              Label* normal_ir_body) {
+  Label return_true, return_false, try_two_byte;
   __ ldr(R0, Address(SP, 2 * kWordSize));  // this
   __ ldr(R1, Address(SP, 1 * kWordSize));  // start
   __ ldr(R2, Address(SP, 0 * kWordSize));  // other
   __ Push(R4);                             // Make ARGS_DESC_REG available.
 
   __ tst(R1, Operand(kSmiTagMask));
-  __ b(&fall_through, NE);  // 'start' is not a Smi.
+  __ b(normal_ir_body, NE);  // 'start' is not a Smi.
 
   __ CompareClassId(R2, kOneByteStringCid, R3);
-  __ b(&fall_through, NE);
+  __ b(normal_ir_body, NE);
 
   __ CompareClassId(R0, kOneByteStringCid, R3);
   __ b(&try_two_byte, NE);
@@ -1816,7 +1844,7 @@
 
   __ Bind(&try_two_byte);
   __ CompareClassId(R0, kTwoByteStringCid, R3);
-  __ b(&fall_through, NE);
+  __ b(normal_ir_body, NE);
 
   GenerateSubstringMatchesSpecialization(assembler, kTwoByteStringCid,
                                          kOneByteStringCid, &return_true,
@@ -1832,29 +1860,30 @@
   __ LoadObject(R0, Bool::False());
   __ Ret();
 
-  __ Bind(&fall_through);
+  __ Bind(normal_ir_body);
   __ Pop(R4);
 }
 
-void Intrinsifier::Object_getHash(Assembler* assembler) {
+void Intrinsifier::Object_getHash(Assembler* assembler, Label* normal_ir_body) {
   UNREACHABLE();
 }
 
-void Intrinsifier::Object_setHash(Assembler* assembler) {
+void Intrinsifier::Object_setHash(Assembler* assembler, Label* normal_ir_body) {
   UNREACHABLE();
 }
 
-void Intrinsifier::StringBaseCharAt(Assembler* assembler) {
-  Label fall_through, try_two_byte_string;
+void Intrinsifier::StringBaseCharAt(Assembler* assembler,
+                                    Label* normal_ir_body) {
+  Label try_two_byte_string;
 
   __ ldr(R1, Address(SP, 0 * kWordSize));  // Index.
   __ ldr(R0, Address(SP, 1 * kWordSize));  // String.
   __ tst(R1, Operand(kSmiTagMask));
-  __ b(&fall_through, NE);  // Index is not a Smi.
+  __ b(normal_ir_body, NE);  // Index is not a Smi.
   // Range check.
   __ ldr(R2, FieldAddress(R0, String::length_offset()));
   __ cmp(R1, Operand(R2));
-  __ b(&fall_through, CS);  // Runtime throws exception.
+  __ b(normal_ir_body, CS);  // Runtime throws exception.
 
   __ CompareClassId(R0, kOneByteStringCid, R3);
   __ b(&try_two_byte_string, NE);
@@ -1862,7 +1891,7 @@
   __ AddImmediate(R0, OneByteString::data_offset() - kHeapObjectTag);
   __ ldrb(R1, Address(R0, R1));
   __ CompareImmediate(R1, Symbols::kNumberOfOneCharCodeSymbols);
-  __ b(&fall_through, GE);
+  __ b(normal_ir_body, GE);
   __ ldr(R0, Address(THR, Thread::predefined_symbols_address_offset()));
   __ AddImmediate(R0, Symbols::kNullCharCodeSymbolOffset * kWordSize);
   __ ldr(R0, Address(R0, R1, LSL, 2));
@@ -1870,21 +1899,22 @@
 
   __ Bind(&try_two_byte_string);
   __ CompareClassId(R0, kTwoByteStringCid, R3);
-  __ b(&fall_through, NE);
+  __ b(normal_ir_body, NE);
   ASSERT(kSmiTagShift == 1);
   __ AddImmediate(R0, TwoByteString::data_offset() - kHeapObjectTag);
   __ ldrh(R1, Address(R0, R1));
   __ CompareImmediate(R1, Symbols::kNumberOfOneCharCodeSymbols);
-  __ b(&fall_through, GE);
+  __ b(normal_ir_body, GE);
   __ ldr(R0, Address(THR, Thread::predefined_symbols_address_offset()));
   __ AddImmediate(R0, Symbols::kNullCharCodeSymbolOffset * kWordSize);
   __ ldr(R0, Address(R0, R1, LSL, 2));
   __ Ret();
 
-  __ Bind(&fall_through);
+  __ Bind(normal_ir_body);
 }
 
-void Intrinsifier::StringBaseIsEmpty(Assembler* assembler) {
+void Intrinsifier::StringBaseIsEmpty(Assembler* assembler,
+                                     Label* normal_ir_body) {
   __ ldr(R0, Address(SP, 0 * kWordSize));
   __ ldr(R0, FieldAddress(R0, String::length_offset()));
   __ cmp(R0, Operand(Smi::RawValue(0)));
@@ -1893,7 +1923,8 @@
   __ Ret();
 }
 
-void Intrinsifier::OneByteString_getHashCode(Assembler* assembler) {
+void Intrinsifier::OneByteString_getHashCode(Assembler* assembler,
+                                             Label* normal_ir_body) {
   __ ldr(R1, Address(SP, 0 * kWordSize));
   __ ldr(R0, FieldAddress(R1, String::hash_offset()));
   __ cmp(R0, Operand(0));
@@ -2032,20 +2063,21 @@
 // Arg1: Start index as Smi.
 // Arg2: End index as Smi.
 // The indexes must be valid.
-void Intrinsifier::OneByteString_substringUnchecked(Assembler* assembler) {
+void Intrinsifier::OneByteString_substringUnchecked(Assembler* assembler,
+                                                    Label* normal_ir_body) {
   const intptr_t kStringOffset = 2 * kWordSize;
   const intptr_t kStartIndexOffset = 1 * kWordSize;
   const intptr_t kEndIndexOffset = 0 * kWordSize;
-  Label fall_through, ok;
+  Label ok;
 
   __ ldr(R2, Address(SP, kEndIndexOffset));
   __ ldr(TMP, Address(SP, kStartIndexOffset));
   __ orr(R3, R2, Operand(TMP));
   __ tst(R3, Operand(kSmiTagMask));
-  __ b(&fall_through, NE);  // 'start', 'end' not Smi.
+  __ b(normal_ir_body, NE);  // 'start', 'end' not Smi.
 
   __ sub(R2, R2, Operand(TMP));
-  TryAllocateOnebyteString(assembler, &ok, &fall_through);
+  TryAllocateOnebyteString(assembler, &ok, normal_ir_body);
   __ Bind(&ok);
   // R0: new string as tagged pointer.
   // Copy string.
@@ -2084,10 +2116,11 @@
 
   __ Bind(&done);
   __ Ret();
-  __ Bind(&fall_through);
+  __ Bind(normal_ir_body);
 }
 
-void Intrinsifier::OneByteStringSetAt(Assembler* assembler) {
+void Intrinsifier::OneByteStringSetAt(Assembler* assembler,
+                                      Label* normal_ir_body) {
   __ ldr(R2, Address(SP, 0 * kWordSize));  // Value.
   __ ldr(R1, Address(SP, 1 * kWordSize));  // Index.
   __ ldr(R0, Address(SP, 2 * kWordSize));  // OneByteString.
@@ -2098,20 +2131,23 @@
   __ Ret();
 }
 
-void Intrinsifier::OneByteString_allocate(Assembler* assembler) {
+void Intrinsifier::OneByteString_allocate(Assembler* assembler,
+                                          Label* normal_ir_body) {
   __ ldr(R2, Address(SP, 0 * kWordSize));  // Length.
-  Label fall_through, ok;
-  TryAllocateOnebyteString(assembler, &ok, &fall_through);
+  Label ok;
+  TryAllocateOnebyteString(assembler, &ok, normal_ir_body);
 
   __ Bind(&ok);
   __ Ret();
 
-  __ Bind(&fall_through);
+  __ Bind(normal_ir_body);
 }
 
 // TODO(srdjan): Add combinations (one-byte/two-byte/external strings).
-static void StringEquality(Assembler* assembler, intptr_t string_cid) {
-  Label fall_through, is_true, is_false, loop;
+static void StringEquality(Assembler* assembler,
+                           Label* normal_ir_body,
+                           intptr_t string_cid) {
+  Label is_true, is_false, loop;
   __ ldr(R0, Address(SP, 1 * kWordSize));  // This.
   __ ldr(R1, Address(SP, 0 * kWordSize));  // Other.
 
@@ -2121,9 +2157,9 @@
 
   // Is other OneByteString?
   __ tst(R1, Operand(kSmiTagMask));
-  __ b(&fall_through, EQ);
+  __ b(normal_ir_body, EQ);
   __ CompareClassId(R1, string_cid, R2);
-  __ b(&fall_through, NE);
+  __ b(normal_ir_body, NE);
 
   // Have same length?
   __ ldr(R2, FieldAddress(R0, String::length_offset()));
@@ -2170,18 +2206,21 @@
   __ LoadObject(R0, Bool::False());
   __ Ret();
 
-  __ Bind(&fall_through);
+  __ Bind(normal_ir_body);
 }
 
-void Intrinsifier::OneByteString_equality(Assembler* assembler) {
-  StringEquality(assembler, kOneByteStringCid);
+void Intrinsifier::OneByteString_equality(Assembler* assembler,
+                                          Label* normal_ir_body) {
+  StringEquality(assembler, normal_ir_body, kOneByteStringCid);
 }
 
-void Intrinsifier::TwoByteString_equality(Assembler* assembler) {
-  StringEquality(assembler, kTwoByteStringCid);
+void Intrinsifier::TwoByteString_equality(Assembler* assembler,
+                                          Label* normal_ir_body) {
+  StringEquality(assembler, normal_ir_body, kTwoByteStringCid);
 }
 
 void Intrinsifier::IntrinsifyRegExpExecuteMatch(Assembler* assembler,
+                                                Label* normal_ir_body,
                                                 bool sticky) {
   if (FLAG_interpret_irregexp) return;
 
@@ -2210,12 +2249,12 @@
 
   // Tail-call the function.
   __ ldr(CODE_REG, FieldAddress(R0, Function::code_offset()));
-  __ ldr(R1, FieldAddress(R0, Function::entry_point_offset()));
-  __ bx(R1);
+  __ Branch(FieldAddress(R0, Function::entry_point_offset()));
 }
 
 // On stack: user tag (+0).
-void Intrinsifier::UserTag_makeCurrent(Assembler* assembler) {
+void Intrinsifier::UserTag_makeCurrent(Assembler* assembler,
+                                       Label* normal_ir_body) {
   // R1: Isolate.
   __ LoadIsolate(R1);
   // R0: Current user tag.
@@ -2231,23 +2270,25 @@
   __ Ret();
 }
 
-void Intrinsifier::UserTag_defaultTag(Assembler* assembler) {
+void Intrinsifier::UserTag_defaultTag(Assembler* assembler,
+                                      Label* normal_ir_body) {
   __ LoadIsolate(R0);
   __ ldr(R0, Address(R0, Isolate::default_tag_offset()));
   __ Ret();
 }
 
-void Intrinsifier::Profiler_getCurrentTag(Assembler* assembler) {
+void Intrinsifier::Profiler_getCurrentTag(Assembler* assembler,
+                                          Label* normal_ir_body) {
   __ LoadIsolate(R0);
   __ ldr(R0, Address(R0, Isolate::current_tag_offset()));
   __ Ret();
 }
 
-void Intrinsifier::Timeline_isDartStreamEnabled(Assembler* assembler) {
+void Intrinsifier::Timeline_isDartStreamEnabled(Assembler* assembler,
+                                                Label* normal_ir_body) {
   if (!FLAG_support_timeline) {
     __ LoadObject(R0, Bool::False());
     __ Ret();
-    return;
   }
   // Load TimelineStream*.
   __ ldr(R0, Address(THR, Thread::dart_stream_offset()));
@@ -2259,13 +2300,15 @@
   __ Ret();
 }
 
-void Intrinsifier::ClearAsyncThreadStackTrace(Assembler* assembler) {
+void Intrinsifier::ClearAsyncThreadStackTrace(Assembler* assembler,
+                                              Label* normal_ir_body) {
   __ LoadObject(R0, Object::null_object());
   __ str(R0, Address(THR, Thread::async_stack_trace_offset()));
   __ Ret();
 }
 
-void Intrinsifier::SetAsyncThreadStackTrace(Assembler* assembler) {
+void Intrinsifier::SetAsyncThreadStackTrace(Assembler* assembler,
+                                            Label* normal_ir_body) {
   __ ldr(R0, Address(THR, Thread::async_stack_trace_offset()));
   __ LoadObject(R0, Object::null_object());
   __ Ret();
diff --git a/runtime/vm/compiler/intrinsifier_arm64.cc b/runtime/vm/compiler/intrinsifier_arm64.cc
index 79b3412..7709bac 100644
--- a/runtime/vm/compiler/intrinsifier_arm64.cc
+++ b/runtime/vm/compiler/intrinsifier_arm64.cc
@@ -58,17 +58,17 @@
 }
 
 // Intrinsify only for Smi index.
-void Intrinsifier::ObjectArraySetIndexedUnchecked(Assembler* assembler) {
-  Label fall_through;
+void Intrinsifier::ObjectArraySetIndexedUnchecked(Assembler* assembler,
+                                                  Label* normal_ir_body) {
   __ ldr(R1, Address(SP, 1 * kWordSize));  // Index.
-  __ BranchIfNotSmi(R1, &fall_through);
+  __ BranchIfNotSmi(R1, normal_ir_body);
   __ ldr(R0, Address(SP, 2 * kWordSize));  // Array.
 
   // Range check.
   __ ldr(R3, FieldAddress(R0, Array::length_offset()));  // Array length.
   __ cmp(R1, Operand(R3));
   // Runtime throws exception.
-  __ b(&fall_through, CS);
+  __ b(normal_ir_body, CS);
 
   // Note that R1 is Smi, i.e, times 2.
   ASSERT(kSmiTagShift == 1);
@@ -77,21 +77,21 @@
   __ StoreIntoObject(R0, FieldAddress(R1, Array::data_offset()), R2);
   // Caller is responsible for preserving the value if necessary.
   __ ret();
-  __ Bind(&fall_through);
+  __ Bind(normal_ir_body);
 }
 
 // Allocate a GrowableObjectArray using the backing array specified.
 // On stack: type argument (+1), data (+0).
-void Intrinsifier::GrowableArray_Allocate(Assembler* assembler) {
+void Intrinsifier::GrowableArray_Allocate(Assembler* assembler,
+                                          Label* normal_ir_body) {
   // The newly allocated object is returned in R0.
   const intptr_t kTypeArgumentsOffset = 1 * kWordSize;
   const intptr_t kArrayOffset = 0 * kWordSize;
-  Label fall_through;
 
   // Try allocating in new space.
   const Class& cls = Class::Handle(
       Isolate::Current()->object_store()->growable_object_array_class());
-  __ TryAllocate(cls, &fall_through, R0, R1);
+  __ TryAllocate(cls, normal_ir_body, R0, R1);
 
   // Store backing array object in growable array object.
   __ ldr(R1, Address(SP, kArrayOffset));  // Data argument.
@@ -110,18 +110,18 @@
   __ str(R1, FieldAddress(R0, GrowableObjectArray::length_offset()));
   __ ret();  // Returns the newly allocated object in R0.
 
-  __ Bind(&fall_through);
+  __ Bind(normal_ir_body);
 }
 
 // Add an element to growable array if it doesn't need to grow, otherwise
 // call into regular code.
 // On stack: growable array (+1), value (+0).
-void Intrinsifier::GrowableArray_add(Assembler* assembler) {
+void Intrinsifier::GrowableArray_add(Assembler* assembler,
+                                     Label* normal_ir_body) {
   // In checked mode we need to type-check the incoming argument.
   if (Isolate::Current()->argument_type_checks()) {
     return;
   }
-  Label fall_through;
   // R0: Array.
   __ ldr(R0, Address(SP, 1 * kWordSize));
   // R1: length.
@@ -132,7 +132,7 @@
   __ ldr(R3, FieldAddress(R2, Array::length_offset()));
   // Compare length with capacity.
   __ cmp(R1, Operand(R3));
-  __ b(&fall_through, EQ);  // Must grow data.
+  __ b(normal_ir_body, EQ);  // Must grow data.
   const int64_t value_one = reinterpret_cast<int64_t>(Smi::New(1));
   // len = len + 1;
   __ add(R3, R1, Operand(value_one));
@@ -143,7 +143,7 @@
   __ StoreIntoObject(R2, FieldAddress(R1, Array::data_offset()), R0);
   __ LoadObject(R0, Object::null_object());
   __ ret();
-  __ Bind(&fall_through);
+  __ Bind(normal_ir_body);
 }
 
 static int GetScaleFactor(intptr_t size) {
@@ -166,18 +166,18 @@
 #define TYPED_ARRAY_ALLOCATION(type_name, cid, max_len, scale_shift)           \
   Label fall_through;                                                          \
   const intptr_t kArrayLengthStackOffset = 0 * kWordSize;                      \
-  NOT_IN_PRODUCT(__ MaybeTraceAllocation(cid, R2, &fall_through));             \
+  NOT_IN_PRODUCT(__ MaybeTraceAllocation(cid, R2, normal_ir_body));            \
   __ ldr(R2, Address(SP, kArrayLengthStackOffset)); /* Array length. */        \
   /* Check that length is a positive Smi. */                                   \
   /* R2: requested array length argument. */                                   \
-  __ BranchIfNotSmi(R2, &fall_through);                                        \
+  __ BranchIfNotSmi(R2, normal_ir_body);                                       \
   __ CompareRegisters(R2, ZR);                                                 \
-  __ b(&fall_through, LT);                                                     \
+  __ b(normal_ir_body, LT);                                                    \
   __ SmiUntag(R2);                                                             \
   /* Check for maximum allowed length. */                                      \
   /* R2: untagged array length. */                                             \
   __ CompareImmediate(R2, max_len);                                            \
-  __ b(&fall_through, GT);                                                     \
+  __ b(normal_ir_body, GT);                                                    \
   __ LslImmediate(R2, R2, scale_shift);                                        \
   const intptr_t fixed_size_plus_alignment_padding =                           \
       sizeof(Raw##type_name) + kObjectAlignment - 1;                           \
@@ -188,7 +188,7 @@
                                                                                \
   /* R2: allocation size. */                                                   \
   __ adds(R1, R0, Operand(R2));                                                \
-  __ b(&fall_through, CS); /* Fail on unsigned overflow. */                    \
+  __ b(normal_ir_body, CS); /* Fail on unsigned overflow. */                   \
                                                                                \
   /* Check if the allocation fits into the remaining space. */                 \
   /* R0: potential new object start. */                                        \
@@ -196,7 +196,7 @@
   /* R2: allocation size. */                                                   \
   __ ldr(R6, Address(THR, Thread::end_offset()));                              \
   __ cmp(R1, Operand(R6));                                                     \
-  __ b(&fall_through, CS);                                                     \
+  __ b(normal_ir_body, CS);                                                    \
                                                                                \
   /* Successfully allocated the object(s), now update top to point to */       \
   /* next object start and initialize the object. */                           \
@@ -244,10 +244,11 @@
   __ Bind(&done);                                                              \
                                                                                \
   __ ret();                                                                    \
-  __ Bind(&fall_through);
+  __ Bind(normal_ir_body);
 
 #define TYPED_DATA_ALLOCATOR(clazz)                                            \
-  void Intrinsifier::TypedData_##clazz##_factory(Assembler* assembler) {       \
+  void Intrinsifier::TypedData_##clazz##_factory(Assembler* assembler,         \
+                                                 Label* normal_ir_body) {      \
     intptr_t size = TypedData::ElementSizeInBytes(kTypedData##clazz##Cid);     \
     intptr_t max_len = TypedData::MaxNewSpaceElements(kTypedData##clazz##Cid); \
     int shift = GetScaleFactor(size);                                          \
@@ -265,55 +266,53 @@
   __ BranchIfNotSmi(TMP, not_smi);
 }
 
-void Intrinsifier::Integer_addFromInteger(Assembler* assembler) {
-  Label fall_through;
-  TestBothArgumentsSmis(assembler, &fall_through);  // Checks two smis.
+void Intrinsifier::Integer_addFromInteger(Assembler* assembler,
+                                          Label* normal_ir_body) {
+  TestBothArgumentsSmis(assembler, normal_ir_body);  // Checks two smis.
   __ adds(R0, R0, Operand(R1));                     // Adds.
-  __ b(&fall_through, VS);                          // Fall-through on overflow.
+  __ b(normal_ir_body, VS);                         // Fall-through on overflow.
   __ ret();
-  __ Bind(&fall_through);
+  __ Bind(normal_ir_body);
 }
 
-void Intrinsifier::Integer_add(Assembler* assembler) {
-  Integer_addFromInteger(assembler);
+void Intrinsifier::Integer_add(Assembler* assembler, Label* normal_ir_body) {
+  Integer_addFromInteger(assembler, normal_ir_body);
 }
 
-void Intrinsifier::Integer_subFromInteger(Assembler* assembler) {
-  Label fall_through;
-  TestBothArgumentsSmis(assembler, &fall_through);
+void Intrinsifier::Integer_subFromInteger(Assembler* assembler,
+                                          Label* normal_ir_body) {
+  TestBothArgumentsSmis(assembler, normal_ir_body);
   __ subs(R0, R0, Operand(R1));  // Subtract.
-  __ b(&fall_through, VS);       // Fall-through on overflow.
+  __ b(normal_ir_body, VS);      // Fall-through on overflow.
   __ ret();
-  __ Bind(&fall_through);
+  __ Bind(normal_ir_body);
 }
 
-void Intrinsifier::Integer_sub(Assembler* assembler) {
-  Label fall_through;
-  TestBothArgumentsSmis(assembler, &fall_through);
+void Intrinsifier::Integer_sub(Assembler* assembler, Label* normal_ir_body) {
+  TestBothArgumentsSmis(assembler, normal_ir_body);
   __ subs(R0, R1, Operand(R0));  // Subtract.
-  __ b(&fall_through, VS);       // Fall-through on overflow.
+  __ b(normal_ir_body, VS);      // Fall-through on overflow.
   __ ret();
-  __ Bind(&fall_through);
+  __ Bind(normal_ir_body);
 }
 
-void Intrinsifier::Integer_mulFromInteger(Assembler* assembler) {
-  Label fall_through;
-
-  TestBothArgumentsSmis(assembler, &fall_through);  // checks two smis
+void Intrinsifier::Integer_mulFromInteger(Assembler* assembler,
+                                          Label* normal_ir_body) {
+  TestBothArgumentsSmis(assembler, normal_ir_body);  // checks two smis
   __ SmiUntag(R0);  // Untags R6. We only want result shifted by one.
 
   __ mul(TMP, R0, R1);
   __ smulh(TMP2, R0, R1);
   // TMP: result bits 64..127.
   __ cmp(TMP2, Operand(TMP, ASR, 63));
-  __ b(&fall_through, NE);
+  __ b(normal_ir_body, NE);
   __ mov(R0, TMP);
   __ ret();
-  __ Bind(&fall_through);
+  __ Bind(normal_ir_body);
 }
 
-void Intrinsifier::Integer_mul(Assembler* assembler) {
-  Integer_mulFromInteger(assembler);
+void Intrinsifier::Integer_mul(Assembler* assembler, Label* normal_ir_body) {
+  Integer_mulFromInteger(assembler, normal_ir_body);
 }
 
 // Optimizations:
@@ -373,18 +372,19 @@
 //      res = res + right;
 //    }
 //  }
-void Intrinsifier::Integer_moduloFromInteger(Assembler* assembler) {
+void Intrinsifier::Integer_moduloFromInteger(Assembler* assembler,
+                                             Label* normal_ir_body) {
   // Check to see if we have integer division
   Label neg_remainder, fall_through;
   __ ldr(R1, Address(SP, +0 * kWordSize));
   __ ldr(R0, Address(SP, +1 * kWordSize));
   __ orr(TMP, R0, Operand(R1));
-  __ BranchIfNotSmi(TMP, &fall_through);
+  __ BranchIfNotSmi(TMP, normal_ir_body);
   // R1: Tagged left (dividend).
   // R0: Tagged right (divisor).
   // Check if modulo by zero -> exception thrown in main function.
   __ CompareRegisters(R0, ZR);
-  __ b(&fall_through, EQ);
+  __ b(normal_ir_body, EQ);
   EmitRemainderOperation(assembler);
   // Untagged right in R0. Untagged remainder result in R1.
 
@@ -402,16 +402,16 @@
   __ SmiTag(R0);
   __ ret();
 
-  __ Bind(&fall_through);
+  __ Bind(normal_ir_body);
 }
 
-void Intrinsifier::Integer_truncDivide(Assembler* assembler) {
+void Intrinsifier::Integer_truncDivide(Assembler* assembler,
+                                       Label* normal_ir_body) {
   // Check to see if we have integer division
-  Label fall_through;
 
-  TestBothArgumentsSmis(assembler, &fall_through);
+  TestBothArgumentsSmis(assembler, normal_ir_body);
   __ CompareRegisters(R0, ZR);
-  __ b(&fall_through, EQ);  // If b is 0, fall through.
+  __ b(normal_ir_body, EQ);  // If b is 0, fall through.
 
   __ SmiUntag(R0);
   __ SmiUntag(R1);
@@ -421,71 +421,68 @@
   // Check the corner case of dividing the 'MIN_SMI' with -1, in which case we
   // cannot tag the result.
   __ CompareImmediate(R0, 0x4000000000000000);
-  __ b(&fall_through, EQ);
+  __ b(normal_ir_body, EQ);
   __ SmiTag(R0);  // Not equal. Okay to tag and return.
   __ ret();       // Return.
-  __ Bind(&fall_through);
+  __ Bind(normal_ir_body);
 }
 
-void Intrinsifier::Integer_negate(Assembler* assembler) {
-  Label fall_through;
+void Intrinsifier::Integer_negate(Assembler* assembler, Label* normal_ir_body) {
   __ ldr(R0, Address(SP, +0 * kWordSize));  // Grab first argument.
-  __ BranchIfNotSmi(R0, &fall_through);
+  __ BranchIfNotSmi(R0, normal_ir_body);
   __ negs(R0, R0);
-  __ b(&fall_through, VS);
+  __ b(normal_ir_body, VS);
   __ ret();
-  __ Bind(&fall_through);
+  __ Bind(normal_ir_body);
 }
 
-void Intrinsifier::Integer_bitAndFromInteger(Assembler* assembler) {
-  Label fall_through;
-  TestBothArgumentsSmis(assembler, &fall_through);  // Checks two smis.
+void Intrinsifier::Integer_bitAndFromInteger(Assembler* assembler,
+                                             Label* normal_ir_body) {
+  TestBothArgumentsSmis(assembler, normal_ir_body);  // Checks two smis.
   __ and_(R0, R0, Operand(R1));
   __ ret();
-  __ Bind(&fall_through);
+  __ Bind(normal_ir_body);
 }
 
-void Intrinsifier::Integer_bitAnd(Assembler* assembler) {
-  Integer_bitAndFromInteger(assembler);
+void Intrinsifier::Integer_bitAnd(Assembler* assembler, Label* normal_ir_body) {
+  Integer_bitAndFromInteger(assembler, normal_ir_body);
 }
 
-void Intrinsifier::Integer_bitOrFromInteger(Assembler* assembler) {
-  Label fall_through;
-  TestBothArgumentsSmis(assembler, &fall_through);  // Checks two smis.
+void Intrinsifier::Integer_bitOrFromInteger(Assembler* assembler,
+                                            Label* normal_ir_body) {
+  TestBothArgumentsSmis(assembler, normal_ir_body);  // Checks two smis.
   __ orr(R0, R0, Operand(R1));
   __ ret();
-  __ Bind(&fall_through);
+  __ Bind(normal_ir_body);
 }
 
-void Intrinsifier::Integer_bitOr(Assembler* assembler) {
-  Integer_bitOrFromInteger(assembler);
+void Intrinsifier::Integer_bitOr(Assembler* assembler, Label* normal_ir_body) {
+  Integer_bitOrFromInteger(assembler, normal_ir_body);
 }
 
-void Intrinsifier::Integer_bitXorFromInteger(Assembler* assembler) {
-  Label fall_through;
-
-  TestBothArgumentsSmis(assembler, &fall_through);  // Checks two smis.
+void Intrinsifier::Integer_bitXorFromInteger(Assembler* assembler,
+                                             Label* normal_ir_body) {
+  TestBothArgumentsSmis(assembler, normal_ir_body);  // Checks two smis.
   __ eor(R0, R0, Operand(R1));
   __ ret();
-  __ Bind(&fall_through);
+  __ Bind(normal_ir_body);
 }
 
-void Intrinsifier::Integer_bitXor(Assembler* assembler) {
-  Integer_bitXorFromInteger(assembler);
+void Intrinsifier::Integer_bitXor(Assembler* assembler, Label* normal_ir_body) {
+  Integer_bitXorFromInteger(assembler, normal_ir_body);
 }
 
-void Intrinsifier::Integer_shl(Assembler* assembler) {
+void Intrinsifier::Integer_shl(Assembler* assembler, Label* normal_ir_body) {
   ASSERT(kSmiTagShift == 1);
   ASSERT(kSmiTag == 0);
   const Register right = R0;
   const Register left = R1;
   const Register temp = R2;
   const Register result = R0;
-  Label fall_through;
 
-  TestBothArgumentsSmis(assembler, &fall_through);
+  TestBothArgumentsSmis(assembler, normal_ir_body);
   __ CompareImmediate(right, reinterpret_cast<int64_t>(Smi::New(Smi::kBits)));
-  __ b(&fall_through, CS);
+  __ b(normal_ir_body, CS);
 
   // Left is not a constant.
   // Check if count too large for handling it inlined.
@@ -494,49 +491,57 @@
   __ lslv(temp, left, TMP);
   __ asrv(TMP2, temp, TMP);
   __ CompareRegisters(left, TMP2);
-  __ b(&fall_through, NE);  // Overflow.
+  __ b(normal_ir_body, NE);  // Overflow.
   // Shift for result now we know there is no overflow.
   __ lslv(result, left, TMP);
   __ ret();
-  __ Bind(&fall_through);
+  __ Bind(normal_ir_body);
 }
 
-static void CompareIntegers(Assembler* assembler, Condition true_condition) {
-  Label fall_through, true_label;
-  TestBothArgumentsSmis(assembler, &fall_through);
+static void CompareIntegers(Assembler* assembler,
+                            Label* normal_ir_body,
+                            Condition true_condition) {
+  Label true_label;
+  TestBothArgumentsSmis(assembler, normal_ir_body);
   // R0 contains the right argument, R1 the left.
   __ CompareRegisters(R1, R0);
   __ LoadObject(R0, Bool::False());
   __ LoadObject(TMP, Bool::True());
   __ csel(R0, TMP, R0, true_condition);
   __ ret();
-  __ Bind(&fall_through);
+  __ Bind(normal_ir_body);
 }
 
-void Intrinsifier::Integer_greaterThanFromInt(Assembler* assembler) {
-  CompareIntegers(assembler, LT);
+void Intrinsifier::Integer_greaterThanFromInt(Assembler* assembler,
+                                              Label* normal_ir_body) {
+  CompareIntegers(assembler, normal_ir_body, LT);
 }
 
-void Intrinsifier::Integer_lessThan(Assembler* assembler) {
-  Integer_greaterThanFromInt(assembler);
+void Intrinsifier::Integer_lessThan(Assembler* assembler,
+                                    Label* normal_ir_body) {
+  Integer_greaterThanFromInt(assembler, normal_ir_body);
 }
 
-void Intrinsifier::Integer_greaterThan(Assembler* assembler) {
-  CompareIntegers(assembler, GT);
+void Intrinsifier::Integer_greaterThan(Assembler* assembler,
+                                       Label* normal_ir_body) {
+  CompareIntegers(assembler, normal_ir_body, GT);
 }
 
-void Intrinsifier::Integer_lessEqualThan(Assembler* assembler) {
-  CompareIntegers(assembler, LE);
+void Intrinsifier::Integer_lessEqualThan(Assembler* assembler,
+                                         Label* normal_ir_body) {
+  CompareIntegers(assembler, normal_ir_body, LE);
 }
 
-void Intrinsifier::Integer_greaterEqualThan(Assembler* assembler) {
-  CompareIntegers(assembler, GE);
+void Intrinsifier::Integer_greaterEqualThan(Assembler* assembler,
+                                            Label* normal_ir_body) {
+  CompareIntegers(assembler, normal_ir_body, GE);
 }
 
 // This is called for Smi and Mint receivers. The right argument
 // can be Smi, Mint or double.
-void Intrinsifier::Integer_equalToInteger(Assembler* assembler) {
-  Label fall_through, true_label, check_for_mint;
+void Intrinsifier::Integer_equalToInteger(Assembler* assembler,
+                                          Label* normal_ir_body) {
+  Label true_label, check_for_mint;
   // For integer receiver '===' check first.
   __ ldr(R0, Address(SP, 0 * kWordSize));
   __ ldr(R1, Address(SP, 1 * kWordSize));
@@ -565,7 +570,7 @@
   // represented by Smi.
 
   __ CompareClassId(R0, kDoubleCid);
-  __ b(&fall_through, EQ);
+  __ b(normal_ir_body, EQ);
   __ LoadObject(R0, Bool::False());  // Smi == Mint -> false.
   __ ret();
 
@@ -573,30 +578,28 @@
   // R1: receiver.
 
   __ CompareClassId(R1, kMintCid);
-  __ b(&fall_through, NE);
+  __ b(normal_ir_body, NE);
   // Receiver is Mint, return false if right is Smi.
-  __ BranchIfNotSmi(R0, &fall_through);
+  __ BranchIfNotSmi(R0, normal_ir_body);
   __ LoadObject(R0, Bool::False());
   __ ret();
   // TODO(srdjan): Implement Mint == Mint comparison.
 
-  __ Bind(&fall_through);
+  __ Bind(normal_ir_body);
 }
 
-void Intrinsifier::Integer_equal(Assembler* assembler) {
-  Integer_equalToInteger(assembler);
+void Intrinsifier::Integer_equal(Assembler* assembler, Label* normal_ir_body) {
+  Integer_equalToInteger(assembler, normal_ir_body);
 }
 
-void Intrinsifier::Integer_sar(Assembler* assembler) {
-  Label fall_through;
-
-  TestBothArgumentsSmis(assembler, &fall_through);
+void Intrinsifier::Integer_sar(Assembler* assembler, Label* normal_ir_body) {
+  TestBothArgumentsSmis(assembler, normal_ir_body);
   // Shift amount in R0. Value to shift in R1.
 
   // Fall through if shift amount is negative.
   __ SmiUntag(R0);
   __ CompareRegisters(R0, ZR);
-  __ b(&fall_through, LT);
+  __ b(normal_ir_body, LT);
 
   // If shift amount is bigger than 63, set to 63.
   __ LoadImmediate(TMP, 0x3F);
@@ -606,17 +609,17 @@
   __ asrv(R0, R1, R0);
   __ SmiTag(R0);
   __ ret();
-  __ Bind(&fall_through);
+  __ Bind(normal_ir_body);
 }
 
-void Intrinsifier::Smi_bitNegate(Assembler* assembler) {
+void Intrinsifier::Smi_bitNegate(Assembler* assembler, Label* normal_ir_body) {
   __ ldr(R0, Address(SP, 0 * kWordSize));
   __ mvn(R0, R0);
   __ andi(R0, R0, Immediate(~kSmiTagMask));  // Remove inverted smi-tag.
   __ ret();
 }
 
-void Intrinsifier::Smi_bitLength(Assembler* assembler) {
+void Intrinsifier::Smi_bitLength(Assembler* assembler, Label* normal_ir_body) {
   __ ldr(R0, Address(SP, 0 * kWordSize));
   __ SmiUntag(R0);
   // XOR with sign bit to complement bits if value is negative.
@@ -628,11 +631,12 @@
   __ ret();
 }
 
-void Intrinsifier::Smi_bitAndFromSmi(Assembler* assembler) {
-  Integer_bitAndFromInteger(assembler);
+void Intrinsifier::Smi_bitAndFromSmi(Assembler* assembler,
+                                     Label* normal_ir_body) {
+  Integer_bitAndFromInteger(assembler, normal_ir_body);
 }
 
-void Intrinsifier::Bigint_lsh(Assembler* assembler) {
+void Intrinsifier::Bigint_lsh(Assembler* assembler, Label* normal_ir_body) {
   // static void _lsh(Uint32List x_digits, int x_used, int n,
   //                  Uint32List r_digits)
 
@@ -676,7 +680,7 @@
   __ ret();
 }
 
-void Intrinsifier::Bigint_rsh(Assembler* assembler) {
+void Intrinsifier::Bigint_rsh(Assembler* assembler, Label* normal_ir_body) {
   // static void _lsh(Uint32List x_digits, int x_used, int n,
   //                  Uint32List r_digits)
 
@@ -723,7 +727,7 @@
   __ ret();
 }
 
-void Intrinsifier::Bigint_absAdd(Assembler* assembler) {
+void Intrinsifier::Bigint_absAdd(Assembler* assembler, Label* normal_ir_body) {
   // static void _absAdd(Uint32List digits, int used,
   //                     Uint32List a_digits, int a_used,
   //                     Uint32List r_digits)
@@ -788,7 +792,7 @@
   __ ret();
 }
 
-void Intrinsifier::Bigint_absSub(Assembler* assembler) {
+void Intrinsifier::Bigint_absSub(Assembler* assembler, Label* normal_ir_body) {
   // static void _absSub(Uint32List digits, int used,
   //                     Uint32List a_digits, int a_used,
   //                     Uint32List r_digits)
@@ -847,7 +851,7 @@
   __ ret();
 }
 
-void Intrinsifier::Bigint_mulAdd(Assembler* assembler) {
+void Intrinsifier::Bigint_mulAdd(Assembler* assembler, Label* normal_ir_body) {
   // Pseudo code:
   // static int _mulAdd(Uint32List x_digits, int xi,
   //                    Uint32List m_digits, int i,
@@ -957,7 +961,7 @@
   __ ret();
 }
 
-void Intrinsifier::Bigint_sqrAdd(Assembler* assembler) {
+void Intrinsifier::Bigint_sqrAdd(Assembler* assembler, Label* normal_ir_body) {
   // Pseudo code:
   // static int _sqrAdd(Uint32List x_digits, int i,
   //                    Uint32List a_digits, int used) {
@@ -1071,7 +1075,8 @@
   __ ret();
 }
 
-void Intrinsifier::Bigint_estimateQuotientDigit(Assembler* assembler) {
+void Intrinsifier::Bigint_estimateQuotientDigit(Assembler* assembler,
+                                                Label* normal_ir_body) {
   // There is no 128-bit by 64-bit division instruction on arm64, so we use two
   // 64-bit by 32-bit divisions and two 64-bit by 64-bit multiplications to
   // adjust the two 32-bit digits of the estimated quotient.
@@ -1249,7 +1254,8 @@
   __ ret();
 }
 
-void Intrinsifier::Montgomery_mulMod(Assembler* assembler) {
+void Intrinsifier::Montgomery_mulMod(Assembler* assembler,
+                                     Label* normal_ir_body) {
   // Pseudo code:
   // static int _mulMod(Uint32List args, Uint32List digits, int i) {
   //   uint64_t rho = args[_RHO .. _RHO_HI];  // _RHO == 2, _RHO_HI == 3.
@@ -1300,10 +1306,12 @@
 // type. Return true or false object in the register R0. Any NaN argument
 // returns false. Any non-double arg1 causes control flow to fall through to the
 // slow case (compiled method body).
-static void CompareDoubles(Assembler* assembler, Condition true_condition) {
-  Label fall_through, is_smi, double_op, not_nan;
+static void CompareDoubles(Assembler* assembler,
+                           Label* normal_ir_body,
+                           Condition true_condition) {
+  Label is_smi, double_op, not_nan;
 
-  TestLastArgumentIsDouble(assembler, &is_smi, &fall_through);
+  TestLastArgumentIsDouble(assembler, &is_smi, normal_ir_body);
   // Both arguments are double, right operand is in R0.
 
   __ LoadDFieldFromOffset(V1, R0, Double::value_offset());
@@ -1325,35 +1333,41 @@
   __ SmiUntag(R0);
   __ scvtfdx(V1, R0);
   __ b(&double_op);  // Then do the comparison.
-  __ Bind(&fall_through);
+  __ Bind(normal_ir_body);
 }
 
-void Intrinsifier::Double_greaterThan(Assembler* assembler) {
-  CompareDoubles(assembler, HI);
+void Intrinsifier::Double_greaterThan(Assembler* assembler,
+                                      Label* normal_ir_body) {
+  CompareDoubles(assembler, normal_ir_body, HI);
 }
 
-void Intrinsifier::Double_greaterEqualThan(Assembler* assembler) {
-  CompareDoubles(assembler, CS);
+void Intrinsifier::Double_greaterEqualThan(Assembler* assembler,
+                                           Label* normal_ir_body) {
+  CompareDoubles(assembler, normal_ir_body, CS);
 }
 
-void Intrinsifier::Double_lessThan(Assembler* assembler) {
-  CompareDoubles(assembler, CC);
+void Intrinsifier::Double_lessThan(Assembler* assembler,
+                                   Label* normal_ir_body) {
+  CompareDoubles(assembler, normal_ir_body, CC);
 }
 
-void Intrinsifier::Double_equal(Assembler* assembler) {
-  CompareDoubles(assembler, EQ);
+void Intrinsifier::Double_equal(Assembler* assembler, Label* normal_ir_body) {
+  CompareDoubles(assembler, normal_ir_body, EQ);
 }
 
-void Intrinsifier::Double_lessEqualThan(Assembler* assembler) {
-  CompareDoubles(assembler, LS);
+void Intrinsifier::Double_lessEqualThan(Assembler* assembler,
+                                        Label* normal_ir_body) {
+  CompareDoubles(assembler, normal_ir_body, LS);
 }
 
 // Expects left argument to be double (receiver). Right argument is unknown.
 // Both arguments are on stack.
-static void DoubleArithmeticOperations(Assembler* assembler, Token::Kind kind) {
-  Label fall_through, is_smi, double_op;
+static void DoubleArithmeticOperations(Assembler* assembler,
+                                       Label* normal_ir_body,
+                                       Token::Kind kind) {
+  Label is_smi, double_op;
 
-  TestLastArgumentIsDouble(assembler, &is_smi, &fall_through);
+  TestLastArgumentIsDouble(assembler, &is_smi, normal_ir_body);
   // Both arguments are double, right operand is in R0.
   __ LoadDFieldFromOffset(V1, R0, Double::value_offset());
   __ Bind(&double_op);
@@ -1377,7 +1391,7 @@
   }
   const Class& double_class =
       Class::Handle(Isolate::Current()->object_store()->double_class());
-  __ TryAllocate(double_class, &fall_through, R0, R1);
+  __ TryAllocate(double_class, normal_ir_body, R0, R1);
   __ StoreDFieldToOffset(V0, R0, Double::value_offset());
   __ ret();
 
@@ -1386,31 +1400,31 @@
   __ scvtfdx(V1, R0);
   __ b(&double_op);
 
-  __ Bind(&fall_through);
+  __ Bind(normal_ir_body);
 }
 
-void Intrinsifier::Double_add(Assembler* assembler) {
-  DoubleArithmeticOperations(assembler, Token::kADD);
+void Intrinsifier::Double_add(Assembler* assembler, Label* normal_ir_body) {
+  DoubleArithmeticOperations(assembler, normal_ir_body, Token::kADD);
 }
 
-void Intrinsifier::Double_mul(Assembler* assembler) {
-  DoubleArithmeticOperations(assembler, Token::kMUL);
+void Intrinsifier::Double_mul(Assembler* assembler, Label* normal_ir_body) {
+  DoubleArithmeticOperations(assembler, normal_ir_body, Token::kMUL);
 }
 
-void Intrinsifier::Double_sub(Assembler* assembler) {
-  DoubleArithmeticOperations(assembler, Token::kSUB);
+void Intrinsifier::Double_sub(Assembler* assembler, Label* normal_ir_body) {
+  DoubleArithmeticOperations(assembler, normal_ir_body, Token::kSUB);
 }
 
-void Intrinsifier::Double_div(Assembler* assembler) {
-  DoubleArithmeticOperations(assembler, Token::kDIV);
+void Intrinsifier::Double_div(Assembler* assembler, Label* normal_ir_body) {
+  DoubleArithmeticOperations(assembler, normal_ir_body, Token::kDIV);
 }
 
 // Left is double, right is integer (Mint or Smi)
-void Intrinsifier::Double_mulFromInteger(Assembler* assembler) {
-  Label fall_through;
+void Intrinsifier::Double_mulFromInteger(Assembler* assembler,
+                                         Label* normal_ir_body) {
   // Only smis allowed.
   __ ldr(R0, Address(SP, 0 * kWordSize));
-  __ BranchIfNotSmi(R0, &fall_through);
+  __ BranchIfNotSmi(R0, normal_ir_body);
   // Is Smi.
   __ SmiUntag(R0);
   __ scvtfdx(V1, R0);
@@ -1419,29 +1433,29 @@
   __ fmuld(V0, V0, V1);
   const Class& double_class =
       Class::Handle(Isolate::Current()->object_store()->double_class());
-  __ TryAllocate(double_class, &fall_through, R0, R1);
+  __ TryAllocate(double_class, normal_ir_body, R0, R1);
   __ StoreDFieldToOffset(V0, R0, Double::value_offset());
   __ ret();
-  __ Bind(&fall_through);
+  __ Bind(normal_ir_body);
 }
 
-void Intrinsifier::DoubleFromInteger(Assembler* assembler) {
-  Label fall_through;
-
+void Intrinsifier::DoubleFromInteger(Assembler* assembler,
+                                     Label* normal_ir_body) {
   __ ldr(R0, Address(SP, 0 * kWordSize));
-  __ BranchIfNotSmi(R0, &fall_through);
+  __ BranchIfNotSmi(R0, normal_ir_body);
   // Is Smi.
   __ SmiUntag(R0);
   __ scvtfdx(V0, R0);
   const Class& double_class =
       Class::Handle(Isolate::Current()->object_store()->double_class());
-  __ TryAllocate(double_class, &fall_through, R0, R1);
+  __ TryAllocate(double_class, normal_ir_body, R0, R1);
   __ StoreDFieldToOffset(V0, R0, Double::value_offset());
   __ ret();
-  __ Bind(&fall_through);
+  __ Bind(normal_ir_body);
 }
 
-void Intrinsifier::Double_getIsNaN(Assembler* assembler) {
+void Intrinsifier::Double_getIsNaN(Assembler* assembler,
+                                   Label* normal_ir_body) {
   __ ldr(R0, Address(SP, 0 * kWordSize));
   __ LoadDFieldFromOffset(V0, R0, Double::value_offset());
   __ fcmpd(V0, V0);
@@ -1451,7 +1465,8 @@
   __ ret();
 }
 
-void Intrinsifier::Double_getIsInfinite(Assembler* assembler) {
+void Intrinsifier::Double_getIsInfinite(Assembler* assembler,
+                                        Label* normal_ir_body) {
   __ ldr(R0, Address(SP, 0 * kWordSize));
   __ LoadFieldFromOffset(R0, R0, Double::value_offset());
   // Mask off the sign.
@@ -1464,7 +1479,8 @@
   __ ret();
 }
 
-void Intrinsifier::Double_getIsNegative(Assembler* assembler) {
+void Intrinsifier::Double_getIsNegative(Assembler* assembler,
+                                        Label* normal_ir_body) {
   const Register false_reg = R0;
   const Register true_reg = R2;
   Label is_false, is_true, is_zero;
@@ -1493,28 +1509,28 @@
   __ ret();
 }
 
-void Intrinsifier::DoubleToInteger(Assembler* assembler) {
-  Label fall_through;
-
+void Intrinsifier::DoubleToInteger(Assembler* assembler,
+                                   Label* normal_ir_body) {
   __ ldr(R0, Address(SP, 0 * kWordSize));
   __ LoadDFieldFromOffset(V0, R0, Double::value_offset());
 
   // Explicit NaN check, since ARM gives an FPU exception if you try to
   // convert NaN to an int.
   __ fcmpd(V0, V0);
-  __ b(&fall_through, VS);
+  __ b(normal_ir_body, VS);
 
   __ fcvtzds(R0, V0);
   // Overflow is signaled with minint.
   // Check for overflow and that it fits into Smi.
   __ CompareImmediate(R0, 0xC000000000000000);
-  __ b(&fall_through, MI);
+  __ b(normal_ir_body, MI);
   __ SmiTag(R0);
   __ ret();
-  __ Bind(&fall_through);
+  __ Bind(normal_ir_body);
 }
 
-void Intrinsifier::Double_hashCode(Assembler* assembler) {
+void Intrinsifier::Double_hashCode(Assembler* assembler,
+                                   Label* normal_ir_body) {
   // TODO(dartbug.com/31174): Convert this to a graph intrinsic.
 
   // Load double value and check that it isn't NaN, since ARM gives an
@@ -1534,10 +1550,9 @@
   // overflow in the conversion from double to int. Conversion
   // overflow is signalled by fcvt through clamping R0 to either
   // INT64_MAX or INT64_MIN (saturation).
-  Label fall_through;
   ASSERT(kSmiTag == 0 && kSmiTagShift == 1);
   __ adds(R0, R0, Operand(R0));
-  __ b(&fall_through, VS);
+  __ b(normal_ir_body, VS);
 
   // Compare the two double values. If they are equal, we return the
   // Smi tagged result immediately as the hash code.
@@ -1554,32 +1569,33 @@
   __ ret();
 
   // Fall into the native C++ implementation.
-  __ Bind(&fall_through);
+  __ Bind(normal_ir_body);
 }
 
-void Intrinsifier::MathSqrt(Assembler* assembler) {
-  Label fall_through, is_smi, double_op;
-  TestLastArgumentIsDouble(assembler, &is_smi, &fall_through);
+void Intrinsifier::MathSqrt(Assembler* assembler, Label* normal_ir_body) {
+  Label is_smi, double_op;
+  TestLastArgumentIsDouble(assembler, &is_smi, normal_ir_body);
   // Argument is double and is in R0.
   __ LoadDFieldFromOffset(V1, R0, Double::value_offset());
   __ Bind(&double_op);
   __ fsqrtd(V0, V1);
   const Class& double_class =
       Class::Handle(Isolate::Current()->object_store()->double_class());
-  __ TryAllocate(double_class, &fall_through, R0, R1);
+  __ TryAllocate(double_class, normal_ir_body, R0, R1);
   __ StoreDFieldToOffset(V0, R0, Double::value_offset());
   __ ret();
   __ Bind(&is_smi);
   __ SmiUntag(R0);
   __ scvtfdx(V1, R0);
   __ b(&double_op);
-  __ Bind(&fall_through);
+  __ Bind(normal_ir_body);
 }
 
 //    var state = ((_A * (_state[kSTATE_LO])) + _state[kSTATE_HI]) & _MASK_64;
 //    _state[kSTATE_LO] = state & _MASK_32;
 //    _state[kSTATE_HI] = state >> 32;
-void Intrinsifier::Random_nextState(Assembler* assembler) {
+void Intrinsifier::Random_nextState(Assembler* assembler,
+                                    Label* normal_ir_body) {
   const Library& math_lib = Library::Handle(Library::MathLibrary());
   ASSERT(!math_lib.IsNull());
   const Class& random_class =
@@ -1611,7 +1627,7 @@
   __ ret();
 }
 
-void Intrinsifier::ObjectEquals(Assembler* assembler) {
+void Intrinsifier::ObjectEquals(Assembler* assembler, Label* normal_ir_body) {
   __ ldr(R0, Address(SP, 0 * kWordSize));
   __ ldr(R1, Address(SP, 1 * kWordSize));
   __ cmp(R0, Operand(R1));
@@ -1667,13 +1683,14 @@
 }
 
 // Return type quickly for simple types (not parameterized and not signature).
-void Intrinsifier::ObjectRuntimeType(Assembler* assembler) {
-  Label fall_through, use_canonical_type, not_double, not_integer;
+void Intrinsifier::ObjectRuntimeType(Assembler* assembler,
+                                     Label* normal_ir_body) {
+  Label use_canonical_type, not_double, not_integer;
   __ ldr(R0, Address(SP, 0 * kWordSize));
   __ LoadClassIdMayBeSmi(R1, R0);
 
   __ CompareImmediate(R1, kClosureCid);
-  __ b(&fall_through, EQ);  // Instance is a closure.
+  __ b(normal_ir_body, EQ);  // Instance is a closure.
 
   __ CompareImmediate(R1, kNumPredefinedCids);
   __ b(&use_canonical_type, HI);
@@ -1704,24 +1721,25 @@
   __ LoadClassById(R2, R1);  // Overwrites R1.
   __ ldr(R3, FieldAddress(R2, Class::num_type_arguments_offset()), kHalfword);
   __ CompareImmediate(R3, 0);
-  __ b(&fall_through, NE);
+  __ b(normal_ir_body, NE);
 
   __ ldr(R0, FieldAddress(R2, Class::canonical_type_offset()));
   __ CompareObject(R0, Object::null_object());
-  __ b(&fall_through, EQ);
+  __ b(normal_ir_body, EQ);
   __ ret();
 
-  __ Bind(&fall_through);
+  __ Bind(normal_ir_body);
 }
 
-void Intrinsifier::ObjectHaveSameRuntimeType(Assembler* assembler) {
-  Label fall_through, different_cids, equal, not_equal, not_integer;
+void Intrinsifier::ObjectHaveSameRuntimeType(Assembler* assembler,
+                                             Label* normal_ir_body) {
+  Label different_cids, equal, not_equal, not_integer;
   __ ldr(R0, Address(SP, 0 * kWordSize));
   __ LoadClassIdMayBeSmi(R1, R0);
 
   // Check if left hand size is a closure. Closures are handled in the runtime.
   __ CompareImmediate(R1, kClosureCid);
-  __ b(&fall_through, EQ);
+  __ b(normal_ir_body, EQ);
 
   __ ldr(R0, Address(SP, 1 * kWordSize));
   __ LoadClassIdMayBeSmi(R2, R0);
@@ -1738,7 +1756,7 @@
   __ LoadClassById(R3, R1);  // Overwrites R1.
   __ ldr(R3, FieldAddress(R3, Class::num_type_arguments_offset()), kHalfword);
   __ CompareImmediate(R3, 0);
-  __ b(&fall_through, NE);
+  __ b(normal_ir_body, NE);
 
   __ Bind(&equal);
   __ LoadObject(R0, Bool::True());
@@ -1765,38 +1783,38 @@
   __ LoadObject(R0, Bool::False());
   __ ret();
 
-  __ Bind(&fall_through);
+  __ Bind(normal_ir_body);
 }
 
-void Intrinsifier::String_getHashCode(Assembler* assembler) {
-  Label fall_through;
+void Intrinsifier::String_getHashCode(Assembler* assembler,
+                                      Label* normal_ir_body) {
   __ ldr(R0, Address(SP, 0 * kWordSize));
   __ ldr(R0, FieldAddress(R0, String::hash_offset()), kUnsignedWord);
   __ adds(R0, R0, Operand(R0));  // Smi tag the hash code, setting Z flag.
-  __ b(&fall_through, EQ);
+  __ b(normal_ir_body, EQ);
   __ ret();
   // Hash not yet computed.
-  __ Bind(&fall_through);
+  __ Bind(normal_ir_body);
 }
 
-void Intrinsifier::Type_getHashCode(Assembler* assembler) {
-  Label fall_through;
+void Intrinsifier::Type_getHashCode(Assembler* assembler,
+                                    Label* normal_ir_body) {
   __ ldr(R0, Address(SP, 0 * kWordSize));
   __ ldr(R0, FieldAddress(R0, Type::hash_offset()));
-  __ cbz(&fall_through, R0);
+  __ cbz(normal_ir_body, R0);
   __ ret();
   // Hash not yet computed.
-  __ Bind(&fall_through);
+  __ Bind(normal_ir_body);
 }
 
-void Intrinsifier::Object_getHash(Assembler* assembler) {
+void Intrinsifier::Object_getHash(Assembler* assembler, Label* normal_ir_body) {
   __ ldr(R0, Address(SP, 0 * kWordSize));
   __ ldr(R0, FieldAddress(R0, String::hash_offset()), kUnsignedWord);
   __ SmiTag(R0);
   __ ret();
 }
 
-void Intrinsifier::Object_setHash(Assembler* assembler) {
+void Intrinsifier::Object_setHash(Assembler* assembler, Label* normal_ir_body) {
   __ ldr(R0, Address(SP, 1 * kWordSize));  // Object.
   __ ldr(R1, Address(SP, 0 * kWordSize));  // Value.
   __ SmiUntag(R1);
@@ -1873,19 +1891,20 @@
 // bool _substringMatches(int start, String other)
 // This intrinsic handles a OneByteString or TwoByteString receiver with a
 // OneByteString other.
-void Intrinsifier::StringBaseSubstringMatches(Assembler* assembler) {
-  Label fall_through, return_true, return_false, try_two_byte;
+void Intrinsifier::StringBaseSubstringMatches(Assembler* assembler,
+                                              Label* normal_ir_body) {
+  Label return_true, return_false, try_two_byte;
   __ ldr(R0, Address(SP, 2 * kWordSize));  // this
   __ ldr(R1, Address(SP, 1 * kWordSize));  // start
   __ ldr(R2, Address(SP, 0 * kWordSize));  // other
 
-  __ BranchIfNotSmi(R1, &fall_through);
+  __ BranchIfNotSmi(R1, normal_ir_body);
 
   __ CompareClassId(R2, kOneByteStringCid);
-  __ b(&fall_through, NE);
+  __ b(normal_ir_body, NE);
 
   __ CompareClassId(R0, kOneByteStringCid);
-  __ b(&fall_through, NE);
+  __ b(normal_ir_body, NE);
 
   GenerateSubstringMatchesSpecialization(assembler, kOneByteStringCid,
                                          kOneByteStringCid, &return_true,
@@ -1893,7 +1912,7 @@
 
   __ Bind(&try_two_byte);
   __ CompareClassId(R0, kTwoByteStringCid);
-  __ b(&fall_through, NE);
+  __ b(normal_ir_body, NE);
 
   GenerateSubstringMatchesSpecialization(assembler, kTwoByteStringCid,
                                          kOneByteStringCid, &return_true,
@@ -1907,19 +1926,20 @@
   __ LoadObject(R0, Bool::False());
   __ ret();
 
-  __ Bind(&fall_through);
+  __ Bind(normal_ir_body);
 }
 
-void Intrinsifier::StringBaseCharAt(Assembler* assembler) {
-  Label fall_through, try_two_byte_string;
+void Intrinsifier::StringBaseCharAt(Assembler* assembler,
+                                    Label* normal_ir_body) {
+  Label try_two_byte_string;
 
   __ ldr(R1, Address(SP, 0 * kWordSize));  // Index.
   __ ldr(R0, Address(SP, 1 * kWordSize));  // String.
-  __ BranchIfNotSmi(R1, &fall_through);    // Index is not a Smi.
+  __ BranchIfNotSmi(R1, normal_ir_body);   // Index is not a Smi.
   // Range check.
   __ ldr(R2, FieldAddress(R0, String::length_offset()));
   __ cmp(R1, Operand(R2));
-  __ b(&fall_through, CS);  // Runtime throws exception.
+  __ b(normal_ir_body, CS);  // Runtime throws exception.
 
   __ CompareClassId(R0, kOneByteStringCid);
   __ b(&try_two_byte_string, NE);
@@ -1927,7 +1947,7 @@
   __ AddImmediate(R0, OneByteString::data_offset() - kHeapObjectTag);
   __ ldr(R1, Address(R0, R1), kUnsignedByte);
   __ CompareImmediate(R1, Symbols::kNumberOfOneCharCodeSymbols);
-  __ b(&fall_through, GE);
+  __ b(normal_ir_body, GE);
   __ ldr(R0, Address(THR, Thread::predefined_symbols_address_offset()));
   __ AddImmediate(R0, Symbols::kNullCharCodeSymbolOffset * kWordSize);
   __ ldr(R0, Address(R0, R1, UXTX, Address::Scaled));
@@ -1935,21 +1955,22 @@
 
   __ Bind(&try_two_byte_string);
   __ CompareClassId(R0, kTwoByteStringCid);
-  __ b(&fall_through, NE);
+  __ b(normal_ir_body, NE);
   ASSERT(kSmiTagShift == 1);
   __ AddImmediate(R0, TwoByteString::data_offset() - kHeapObjectTag);
   __ ldr(R1, Address(R0, R1), kUnsignedHalfword);
   __ CompareImmediate(R1, Symbols::kNumberOfOneCharCodeSymbols);
-  __ b(&fall_through, GE);
+  __ b(normal_ir_body, GE);
   __ ldr(R0, Address(THR, Thread::predefined_symbols_address_offset()));
   __ AddImmediate(R0, Symbols::kNullCharCodeSymbolOffset * kWordSize);
   __ ldr(R0, Address(R0, R1, UXTX, Address::Scaled));
   __ ret();
 
-  __ Bind(&fall_through);
+  __ Bind(normal_ir_body);
 }
 
-void Intrinsifier::StringBaseIsEmpty(Assembler* assembler) {
+void Intrinsifier::StringBaseIsEmpty(Assembler* assembler,
+                                     Label* normal_ir_body) {
   __ ldr(R0, Address(SP, 0 * kWordSize));
   __ ldr(R0, FieldAddress(R0, String::length_offset()));
   __ cmp(R0, Operand(Smi::RawValue(0)));
@@ -1959,7 +1980,8 @@
   __ ret();
 }
 
-void Intrinsifier::OneByteString_getHashCode(Assembler* assembler) {
+void Intrinsifier::OneByteString_getHashCode(Assembler* assembler,
+                                             Label* normal_ir_body) {
   Label compute_hash;
   __ ldr(R1, Address(SP, 0 * kWordSize));  // OneByteString object.
   __ ldr(R0, FieldAddress(R1, String::hash_offset()), kUnsignedWord);
@@ -2099,19 +2121,20 @@
 // Arg1: Start index as Smi.
 // Arg2: End index as Smi.
 // The indexes must be valid.
-void Intrinsifier::OneByteString_substringUnchecked(Assembler* assembler) {
+void Intrinsifier::OneByteString_substringUnchecked(Assembler* assembler,
+                                                    Label* normal_ir_body) {
   const intptr_t kStringOffset = 2 * kWordSize;
   const intptr_t kStartIndexOffset = 1 * kWordSize;
   const intptr_t kEndIndexOffset = 0 * kWordSize;
-  Label fall_through, ok;
+  Label ok;
 
   __ ldr(R2, Address(SP, kEndIndexOffset));
   __ ldr(TMP, Address(SP, kStartIndexOffset));
   __ orr(R3, R2, Operand(TMP));
-  __ BranchIfNotSmi(R3, &fall_through);  // 'start', 'end' not Smi.
+  __ BranchIfNotSmi(R3, normal_ir_body);  // 'start', 'end' not Smi.
 
   __ sub(R2, R2, Operand(TMP));
-  TryAllocateOnebyteString(assembler, &ok, &fall_through);
+  TryAllocateOnebyteString(assembler, &ok, normal_ir_body);
   __ Bind(&ok);
   // R0: new string as tagged pointer.
   // Copy string.
@@ -2150,10 +2173,11 @@
 
   __ Bind(&done);
   __ ret();
-  __ Bind(&fall_through);
+  __ Bind(normal_ir_body);
 }
 
-void Intrinsifier::OneByteStringSetAt(Assembler* assembler) {
+void Intrinsifier::OneByteStringSetAt(Assembler* assembler,
+                                      Label* normal_ir_body) {
   __ ldr(R2, Address(SP, 0 * kWordSize));  // Value.
   __ ldr(R1, Address(SP, 1 * kWordSize));  // Index.
   __ ldr(R0, Address(SP, 2 * kWordSize));  // OneByteString.
@@ -2164,21 +2188,24 @@
   __ ret();
 }
 
-void Intrinsifier::OneByteString_allocate(Assembler* assembler) {
-  Label fall_through, ok;
+void Intrinsifier::OneByteString_allocate(Assembler* assembler,
+                                          Label* normal_ir_body) {
+  Label ok;
 
   __ ldr(R2, Address(SP, 0 * kWordSize));  // Length.
-  TryAllocateOnebyteString(assembler, &ok, &fall_through);
+  TryAllocateOnebyteString(assembler, &ok, normal_ir_body);
 
   __ Bind(&ok);
   __ ret();
 
-  __ Bind(&fall_through);
+  __ Bind(normal_ir_body);
 }
 
 // TODO(srdjan): Add combinations (one-byte/two-byte/external strings).
-static void StringEquality(Assembler* assembler, intptr_t string_cid) {
-  Label fall_through, is_true, is_false, loop;
+static void StringEquality(Assembler* assembler,
+                           Label* normal_ir_body,
+                           intptr_t string_cid) {
+  Label is_true, is_false, loop;
   __ ldr(R0, Address(SP, 1 * kWordSize));  // This.
   __ ldr(R1, Address(SP, 0 * kWordSize));  // Other.
 
@@ -2187,9 +2214,9 @@
   __ b(&is_true, EQ);
 
   // Is other OneByteString?
-  __ BranchIfSmi(R1, &fall_through);
+  __ BranchIfSmi(R1, normal_ir_body);
   __ CompareClassId(R1, string_cid);
-  __ b(&fall_through, NE);
+  __ b(normal_ir_body, NE);
 
   // Have same length?
   __ ldr(R2, FieldAddress(R0, String::length_offset()));
@@ -2236,18 +2263,21 @@
   __ LoadObject(R0, Bool::False());
   __ ret();
 
-  __ Bind(&fall_through);
+  __ Bind(normal_ir_body);
 }
 
-void Intrinsifier::OneByteString_equality(Assembler* assembler) {
-  StringEquality(assembler, kOneByteStringCid);
+void Intrinsifier::OneByteString_equality(Assembler* assembler,
+                                          Label* normal_ir_body) {
+  StringEquality(assembler, normal_ir_body, kOneByteStringCid);
 }
 
-void Intrinsifier::TwoByteString_equality(Assembler* assembler) {
-  StringEquality(assembler, kTwoByteStringCid);
+void Intrinsifier::TwoByteString_equality(Assembler* assembler,
+                                          Label* normal_ir_body) {
+  StringEquality(assembler, normal_ir_body, kTwoByteStringCid);
 }
 
 void Intrinsifier::IntrinsifyRegExpExecuteMatch(Assembler* assembler,
+                                                Label* normal_ir_body,
                                                 bool sticky) {
   if (FLAG_interpret_irregexp) return;
 
@@ -2281,7 +2311,8 @@
 }
 
 // On stack: user tag (+0).
-void Intrinsifier::UserTag_makeCurrent(Assembler* assembler) {
+void Intrinsifier::UserTag_makeCurrent(Assembler* assembler,
+                                       Label* normal_ir_body) {
   // R1: Isolate.
   __ LoadIsolate(R1);
   // R0: Current user tag.
@@ -2297,23 +2328,25 @@
   __ ret();
 }
 
-void Intrinsifier::UserTag_defaultTag(Assembler* assembler) {
+void Intrinsifier::UserTag_defaultTag(Assembler* assembler,
+                                      Label* normal_ir_body) {
   __ LoadIsolate(R0);
   __ ldr(R0, Address(R0, Isolate::default_tag_offset()));
   __ ret();
 }
 
-void Intrinsifier::Profiler_getCurrentTag(Assembler* assembler) {
+void Intrinsifier::Profiler_getCurrentTag(Assembler* assembler,
+                                          Label* normal_ir_body) {
   __ LoadIsolate(R0);
   __ ldr(R0, Address(R0, Isolate::current_tag_offset()));
   __ ret();
 }
 
-void Intrinsifier::Timeline_isDartStreamEnabled(Assembler* assembler) {
+void Intrinsifier::Timeline_isDartStreamEnabled(Assembler* assembler,
+                                                Label* normal_ir_body) {
   if (!FLAG_support_timeline) {
     __ LoadObject(R0, Bool::False());
     __ ret();
-    return;
   }
   // Load TimelineStream*.
   __ ldr(R0, Address(THR, Thread::dart_stream_offset()));
@@ -2326,13 +2359,15 @@
   __ ret();
 }
 
-void Intrinsifier::ClearAsyncThreadStackTrace(Assembler* assembler) {
+void Intrinsifier::ClearAsyncThreadStackTrace(Assembler* assembler,
+                                              Label* normal_ir_body) {
   __ LoadObject(R0, Object::null_object());
   __ str(R0, Address(THR, Thread::async_stack_trace_offset()));
   __ ret();
 }
 
-void Intrinsifier::SetAsyncThreadStackTrace(Assembler* assembler) {
+void Intrinsifier::SetAsyncThreadStackTrace(Assembler* assembler,
+                                            Label* normal_ir_body) {
   __ ldr(R0, Address(THR, Thread::async_stack_trace_offset()));
   __ LoadObject(R0, Object::null_object());
   __ ret();
diff --git a/runtime/vm/compiler/intrinsifier_dbc.cc b/runtime/vm/compiler/intrinsifier_dbc.cc
index 77bd035..0cad04a 100644
--- a/runtime/vm/compiler/intrinsifier_dbc.cc
+++ b/runtime/vm/compiler/intrinsifier_dbc.cc
@@ -26,10 +26,11 @@
 }
 
 #define DEFINE_FUNCTION(class_name, test_function_name, enum_name, type, fp)   \
-  void Intrinsifier::enum_name(Assembler* assembler) {                         \
+  void Intrinsifier::enum_name(Assembler* assembler, Label* normal_ir_body) {  \
     if (Simulator::IsSupportedIntrinsic(Simulator::k##enum_name##Intrinsic)) { \
       assembler->Intrinsic(Simulator::k##enum_name##Intrinsic);                \
     }                                                                          \
+    assembler->Bind(normal_ir_body);                                           \
   }
 
 ALL_INTRINSICS_LIST(DEFINE_FUNCTION)
diff --git a/runtime/vm/compiler/intrinsifier_ia32.cc b/runtime/vm/compiler/intrinsifier_ia32.cc
index 0e6e8cc..864d9db 100644
--- a/runtime/vm/compiler/intrinsifier_ia32.cc
+++ b/runtime/vm/compiler/intrinsifier_ia32.cc
@@ -53,17 +53,17 @@
 }
 
 // Intrinsify only for Smi index.
-void Intrinsifier::ObjectArraySetIndexedUnchecked(Assembler* assembler) {
-  Label fall_through;
+void Intrinsifier::ObjectArraySetIndexedUnchecked(Assembler* assembler,
+                                                  Label* normal_ir_body) {
   __ movl(EBX, Address(ESP, +2 * kWordSize));  // Index.
   __ testl(EBX, Immediate(kSmiTagMask));
   // Index not Smi.
-  __ j(NOT_ZERO, &fall_through);
+  __ j(NOT_ZERO, normal_ir_body);
   __ movl(EAX, Address(ESP, +3 * kWordSize));  // Array.
   // Range check.
   __ cmpl(EBX, FieldAddress(EAX, Array::length_offset()));
   // Runtime throws exception.
-  __ j(ABOVE_EQUAL, &fall_through);
+  __ j(ABOVE_EQUAL, normal_ir_body);
   // Note that EBX is Smi, i.e, times 2.
   ASSERT(kSmiTagShift == 1);
   // Destroy ECX (ic data) as we will not continue in the function.
@@ -72,24 +72,24 @@
                      ECX);
   // Caller is responsible of preserving the value if necessary.
   __ ret();
-  __ Bind(&fall_through);
+  __ Bind(normal_ir_body);
 }
 
 // Allocate a GrowableObjectArray using the backing array specified.
 // On stack: type argument (+2), data (+1), return-address (+0).
-void Intrinsifier::GrowableArray_Allocate(Assembler* assembler) {
+void Intrinsifier::GrowableArray_Allocate(Assembler* assembler,
+                                          Label* normal_ir_body) {
   // This snippet of inlined code uses the following registers:
   // EAX, EBX
   // and the newly allocated object is returned in EAX.
   const intptr_t kTypeArgumentsOffset = 2 * kWordSize;
 
   const intptr_t kArrayOffset = 1 * kWordSize;
-  Label fall_through;
 
   // Try allocating in new space.
   const Class& cls = Class::Handle(
       Isolate::Current()->object_store()->growable_object_array_class());
-  __ TryAllocate(cls, &fall_through, Assembler::kNearJump, EAX, EBX);
+  __ TryAllocate(cls, normal_ir_body, Assembler::kNearJump, EAX, EBX);
 
   // Store backing array object in growable array object.
   __ movl(EBX, Address(ESP, kArrayOffset));  // data argument.
@@ -107,17 +107,17 @@
   __ ZeroInitSmiField(FieldAddress(EAX, GrowableObjectArray::length_offset()));
   __ ret();  // returns the newly allocated object in EAX.
 
-  __ Bind(&fall_through);
+  __ Bind(normal_ir_body);
 }
 
 // Add an element to growable array if it doesn't need to grow, otherwise
 // call into regular code.
 // On stack: growable array (+2), value (+1), return-address (+0).
-void Intrinsifier::GrowableArray_add(Assembler* assembler) {
+void Intrinsifier::GrowableArray_add(Assembler* assembler,
+                                     Label* normal_ir_body) {
   // In checked mode we need to type-check the incoming argument.
   if (Isolate::Current()->argument_type_checks()) return;
 
-  Label fall_through;
   __ movl(EAX, Address(ESP, +2 * kWordSize));  // Array.
   __ movl(EBX, FieldAddress(EAX, GrowableObjectArray::length_offset()));
   // EBX: length.
@@ -125,7 +125,7 @@
   // EDI: data.
   // Compare length with capacity.
   __ cmpl(EBX, FieldAddress(EDI, Array::length_offset()));
-  __ j(EQUAL, &fall_through);  // Must grow data.
+  __ j(EQUAL, normal_ir_body);  // Must grow data.
   __ IncrementSmiField(FieldAddress(EAX, GrowableObjectArray::length_offset()),
                        1);
   __ movl(EAX, Address(ESP, +1 * kWordSize));  // Value
@@ -136,25 +136,24 @@
       Immediate(reinterpret_cast<int32_t>(Object::null()));
   __ movl(EAX, raw_null);
   __ ret();
-  __ Bind(&fall_through);
+  __ Bind(normal_ir_body);
 }
 
 #define TYPED_ARRAY_ALLOCATION(type_name, cid, max_len, scale_factor)          \
-  Label fall_through;                                                          \
   const intptr_t kArrayLengthStackOffset = 1 * kWordSize;                      \
-  NOT_IN_PRODUCT(__ MaybeTraceAllocation(cid, EDI, &fall_through, false));     \
+  NOT_IN_PRODUCT(__ MaybeTraceAllocation(cid, EDI, normal_ir_body, false));    \
   __ movl(EDI, Address(ESP, kArrayLengthStackOffset)); /* Array length. */     \
   /* Check that length is a positive Smi. */                                   \
   /* EDI: requested array length argument. */                                  \
   __ testl(EDI, Immediate(kSmiTagMask));                                       \
-  __ j(NOT_ZERO, &fall_through);                                               \
+  __ j(NOT_ZERO, normal_ir_body);                                              \
   __ cmpl(EDI, Immediate(0));                                                  \
-  __ j(LESS, &fall_through);                                                   \
+  __ j(LESS, normal_ir_body);                                                  \
   __ SmiUntag(EDI);                                                            \
   /* Check for maximum allowed length. */                                      \
   /* EDI: untagged array length. */                                            \
   __ cmpl(EDI, Immediate(max_len));                                            \
-  __ j(GREATER, &fall_through);                                                \
+  __ j(GREATER, normal_ir_body);                                               \
   /* Special case for scaling by 16. */                                        \
   if (scale_factor == TIMES_16) {                                              \
     /* double length of array. */                                              \
@@ -172,14 +171,14 @@
                                                                                \
   /* EDI: allocation size. */                                                  \
   __ addl(EBX, EDI);                                                           \
-  __ j(CARRY, &fall_through);                                                  \
+  __ j(CARRY, normal_ir_body);                                                 \
                                                                                \
   /* Check if the allocation fits into the remaining space. */                 \
   /* EAX: potential new object start. */                                       \
   /* EBX: potential next object start. */                                      \
   /* EDI: allocation size. */                                                  \
   __ cmpl(EBX, Address(THR, Thread::end_offset()));                            \
-  __ j(ABOVE_EQUAL, &fall_through);                                            \
+  __ j(ABOVE_EQUAL, normal_ir_body);                                           \
                                                                                \
   /* Successfully allocated the object(s), now update top to point to */       \
   /* next object start and initialize the object. */                           \
@@ -233,7 +232,7 @@
   __ Bind(&done);                                                              \
                                                                                \
   __ ret();                                                                    \
-  __ Bind(&fall_through);
+  __ Bind(normal_ir_body);
 
 static ScaleFactor GetScaleFactor(intptr_t size) {
   switch (size) {
@@ -253,7 +252,8 @@
 }
 
 #define TYPED_DATA_ALLOCATOR(clazz)                                            \
-  void Intrinsifier::TypedData_##clazz##_factory(Assembler* assembler) {       \
+  void Intrinsifier::TypedData_##clazz##_factory(Assembler* assembler,         \
+                                                 Label* normal_ir_body) {      \
     intptr_t size = TypedData::ElementSizeInBytes(kTypedData##clazz##Cid);     \
     intptr_t max_len = TypedData::MaxNewSpaceElements(kTypedData##clazz##Cid); \
     ScaleFactor scale = GetScaleFactor(size);                                  \
@@ -272,56 +272,55 @@
   __ j(NOT_ZERO, not_smi, Assembler::kNearJump);
 }
 
-void Intrinsifier::Integer_addFromInteger(Assembler* assembler) {
-  Label fall_through;
-  TestBothArgumentsSmis(assembler, &fall_through);
+void Intrinsifier::Integer_addFromInteger(Assembler* assembler,
+                                          Label* normal_ir_body) {
+  TestBothArgumentsSmis(assembler, normal_ir_body);
   __ addl(EAX, Address(ESP, +2 * kWordSize));
-  __ j(OVERFLOW, &fall_through, Assembler::kNearJump);
+  __ j(OVERFLOW, normal_ir_body, Assembler::kNearJump);
   // Result is in EAX.
   __ ret();
-  __ Bind(&fall_through);
+  __ Bind(normal_ir_body);
 }
 
-void Intrinsifier::Integer_add(Assembler* assembler) {
-  Integer_addFromInteger(assembler);
+void Intrinsifier::Integer_add(Assembler* assembler, Label* normal_ir_body) {
+  Integer_addFromInteger(assembler, normal_ir_body);
 }
 
-void Intrinsifier::Integer_subFromInteger(Assembler* assembler) {
-  Label fall_through;
-  TestBothArgumentsSmis(assembler, &fall_through);
+void Intrinsifier::Integer_subFromInteger(Assembler* assembler,
+                                          Label* normal_ir_body) {
+  TestBothArgumentsSmis(assembler, normal_ir_body);
   __ subl(EAX, Address(ESP, +2 * kWordSize));
-  __ j(OVERFLOW, &fall_through, Assembler::kNearJump);
+  __ j(OVERFLOW, normal_ir_body, Assembler::kNearJump);
   // Result is in EAX.
   __ ret();
-  __ Bind(&fall_through);
+  __ Bind(normal_ir_body);
 }
 
-void Intrinsifier::Integer_sub(Assembler* assembler) {
-  Label fall_through;
-  TestBothArgumentsSmis(assembler, &fall_through);
+void Intrinsifier::Integer_sub(Assembler* assembler, Label* normal_ir_body) {
+  TestBothArgumentsSmis(assembler, normal_ir_body);
   __ movl(EBX, EAX);
   __ movl(EAX, Address(ESP, +2 * kWordSize));
   __ subl(EAX, EBX);
-  __ j(OVERFLOW, &fall_through, Assembler::kNearJump);
+  __ j(OVERFLOW, normal_ir_body, Assembler::kNearJump);
   // Result is in EAX.
   __ ret();
-  __ Bind(&fall_through);
+  __ Bind(normal_ir_body);
 }
 
-void Intrinsifier::Integer_mulFromInteger(Assembler* assembler) {
-  Label fall_through;
-  TestBothArgumentsSmis(assembler, &fall_through);
+void Intrinsifier::Integer_mulFromInteger(Assembler* assembler,
+                                          Label* normal_ir_body) {
+  TestBothArgumentsSmis(assembler, normal_ir_body);
   ASSERT(kSmiTag == 0);  // Adjust code below if not the case.
   __ SmiUntag(EAX);
   __ imull(EAX, Address(ESP, +2 * kWordSize));
-  __ j(OVERFLOW, &fall_through, Assembler::kNearJump);
+  __ j(OVERFLOW, normal_ir_body, Assembler::kNearJump);
   // Result is in EAX.
   __ ret();
-  __ Bind(&fall_through);
+  __ Bind(normal_ir_body);
 }
 
-void Intrinsifier::Integer_mul(Assembler* assembler) {
-  Integer_mulFromInteger(assembler);
+void Intrinsifier::Integer_mul(Assembler* assembler, Label* normal_ir_body) {
+  Integer_mulFromInteger(assembler, normal_ir_body);
 }
 
 // Optimizations:
@@ -372,15 +371,16 @@
 //      res = res + right;
 //    }
 //  }
-void Intrinsifier::Integer_moduloFromInteger(Assembler* assembler) {
-  Label fall_through, subtract;
-  TestBothArgumentsSmis(assembler, &fall_through);
+void Intrinsifier::Integer_moduloFromInteger(Assembler* assembler,
+                                             Label* normal_ir_body) {
+  Label subtract;
+  TestBothArgumentsSmis(assembler, normal_ir_body);
   __ movl(EBX, Address(ESP, +2 * kWordSize));
   // EAX: Tagged left (dividend).
   // EBX: Tagged right (divisor).
   // Check if modulo by zero -> exception thrown in main function.
   __ cmpl(EBX, Immediate(0));
-  __ j(EQUAL, &fall_through, Assembler::kNearJump);
+  __ j(EQUAL, normal_ir_body, Assembler::kNearJump);
   EmitRemainderOperation(assembler);
   // Untagged remainder result in EDX.
   Label done;
@@ -402,15 +402,15 @@
   __ SmiTag(EAX);
   __ ret();
 
-  __ Bind(&fall_through);
+  __ Bind(normal_ir_body);
 }
 
-void Intrinsifier::Integer_truncDivide(Assembler* assembler) {
-  Label fall_through;
-  TestBothArgumentsSmis(assembler, &fall_through);
+void Intrinsifier::Integer_truncDivide(Assembler* assembler,
+                                       Label* normal_ir_body) {
+  TestBothArgumentsSmis(assembler, normal_ir_body);
   // EAX: right argument (divisor)
   __ cmpl(EAX, Immediate(0));
-  __ j(EQUAL, &fall_through, Assembler::kNearJump);
+  __ j(EQUAL, normal_ir_body, Assembler::kNearJump);
   __ movl(EBX, EAX);
   __ SmiUntag(EBX);
   __ movl(EAX, Address(ESP, +2 * kWordSize));  // Left argument (dividend).
@@ -422,74 +422,73 @@
   // Check the corner case of dividing the 'MIN_SMI' with -1, in which case we
   // cannot tag the result.
   __ cmpl(EAX, Immediate(0x40000000));
-  __ j(EQUAL, &fall_through);
+  __ j(EQUAL, normal_ir_body);
   __ SmiTag(EAX);
   __ ret();
-  __ Bind(&fall_through);
+  __ Bind(normal_ir_body);
 }
 
-void Intrinsifier::Integer_negate(Assembler* assembler) {
-  Label fall_through;
+void Intrinsifier::Integer_negate(Assembler* assembler, Label* normal_ir_body) {
   __ movl(EAX, Address(ESP, +1 * kWordSize));
   __ testl(EAX, Immediate(kSmiTagMask));
-  __ j(NOT_ZERO, &fall_through, Assembler::kNearJump);  // Non-smi value.
+  __ j(NOT_ZERO, normal_ir_body, Assembler::kNearJump);  // Non-smi value.
   __ negl(EAX);
-  __ j(OVERFLOW, &fall_through, Assembler::kNearJump);
+  __ j(OVERFLOW, normal_ir_body, Assembler::kNearJump);
   // Result is in EAX.
   __ ret();
-  __ Bind(&fall_through);
+  __ Bind(normal_ir_body);
 }
 
-void Intrinsifier::Integer_bitAndFromInteger(Assembler* assembler) {
-  Label fall_through;
-  TestBothArgumentsSmis(assembler, &fall_through);
+void Intrinsifier::Integer_bitAndFromInteger(Assembler* assembler,
+                                             Label* normal_ir_body) {
+  TestBothArgumentsSmis(assembler, normal_ir_body);
   __ movl(EBX, Address(ESP, +2 * kWordSize));
   __ andl(EAX, EBX);
   // Result is in EAX.
   __ ret();
-  __ Bind(&fall_through);
+  __ Bind(normal_ir_body);
 }
 
-void Intrinsifier::Integer_bitAnd(Assembler* assembler) {
-  Integer_bitAndFromInteger(assembler);
+void Intrinsifier::Integer_bitAnd(Assembler* assembler, Label* normal_ir_body) {
+  Integer_bitAndFromInteger(assembler, normal_ir_body);
 }
 
-void Intrinsifier::Integer_bitOrFromInteger(Assembler* assembler) {
-  Label fall_through;
-  TestBothArgumentsSmis(assembler, &fall_through);
+void Intrinsifier::Integer_bitOrFromInteger(Assembler* assembler,
+                                            Label* normal_ir_body) {
+  TestBothArgumentsSmis(assembler, normal_ir_body);
   __ movl(EBX, Address(ESP, +2 * kWordSize));
   __ orl(EAX, EBX);
   // Result is in EAX.
   __ ret();
-  __ Bind(&fall_through);
+  __ Bind(normal_ir_body);
 }
 
-void Intrinsifier::Integer_bitOr(Assembler* assembler) {
-  Integer_bitOrFromInteger(assembler);
+void Intrinsifier::Integer_bitOr(Assembler* assembler, Label* normal_ir_body) {
+  Integer_bitOrFromInteger(assembler, normal_ir_body);
 }
 
-void Intrinsifier::Integer_bitXorFromInteger(Assembler* assembler) {
-  Label fall_through;
-  TestBothArgumentsSmis(assembler, &fall_through);
+void Intrinsifier::Integer_bitXorFromInteger(Assembler* assembler,
+                                             Label* normal_ir_body) {
+  TestBothArgumentsSmis(assembler, normal_ir_body);
   __ movl(EBX, Address(ESP, +2 * kWordSize));
   __ xorl(EAX, EBX);
   // Result is in EAX.
   __ ret();
-  __ Bind(&fall_through);
+  __ Bind(normal_ir_body);
 }
 
-void Intrinsifier::Integer_bitXor(Assembler* assembler) {
-  Integer_bitXorFromInteger(assembler);
+void Intrinsifier::Integer_bitXor(Assembler* assembler, Label* normal_ir_body) {
+  Integer_bitXorFromInteger(assembler, normal_ir_body);
 }
 
-void Intrinsifier::Integer_shl(Assembler* assembler) {
+void Intrinsifier::Integer_shl(Assembler* assembler, Label* normal_ir_body) {
   ASSERT(kSmiTagShift == 1);
   ASSERT(kSmiTag == 0);
-  Label fall_through, overflow;
-  TestBothArgumentsSmis(assembler, &fall_through);
+  Label overflow;
+  TestBothArgumentsSmis(assembler, normal_ir_body);
   // Shift value is in EAX. Compare with tagged Smi.
   __ cmpl(EAX, Immediate(Smi::RawValue(Smi::kBits)));
-  __ j(ABOVE_EQUAL, &fall_through, Assembler::kNearJump);
+  __ j(ABOVE_EQUAL, normal_ir_body, Assembler::kNearJump);
 
   __ SmiUntag(EAX);
   __ movl(ECX, EAX);                           // Shift amount must be in ECX.
@@ -511,7 +510,7 @@
   // Arguments are Smi but the shift produced an overflow to Mint.
   __ cmpl(EBX, Immediate(0));
   // TODO(srdjan): Implement negative values, for now fall through.
-  __ j(LESS, &fall_through, Assembler::kNearJump);
+  __ j(LESS, normal_ir_body, Assembler::kNearJump);
   __ SmiUntag(EBX);
   __ movl(EAX, EBX);
   __ shll(EBX, ECX);
@@ -520,14 +519,14 @@
   // Result in EDI (high) and EBX (low).
   const Class& mint_class =
       Class::Handle(Isolate::Current()->object_store()->mint_class());
-  __ TryAllocate(mint_class, &fall_through, Assembler::kNearJump,
+  __ TryAllocate(mint_class, normal_ir_body, Assembler::kNearJump,
                  EAX,   // Result register.
                  ECX);  // temp
   // EBX and EDI are not objects but integer values.
   __ movl(FieldAddress(EAX, Mint::value_offset()), EBX);
   __ movl(FieldAddress(EAX, Mint::value_offset() + kWordSize), EDI);
   __ ret();
-  __ Bind(&fall_through);
+  __ Bind(normal_ir_body);
 }
 
 static void Push64SmiOrMint(Assembler* assembler,
@@ -553,7 +552,9 @@
   __ Bind(&done);
 }
 
-static void CompareIntegers(Assembler* assembler, Condition true_condition) {
+static void CompareIntegers(Assembler* assembler,
+                            Label* normal_ir_body,
+                            Condition true_condition) {
   Label try_mint_smi, is_true, is_false, drop_two_fall_through, fall_through;
   TestBothArgumentsSmis(assembler, &try_mint_smi);
   // EAX contains the right argument.
@@ -591,7 +592,7 @@
   // EAX contains the right argument.
   __ movl(EBX, Address(ESP, +2 * kWordSize));  // Left argument.
   // Push left as 64 bit integer.
-  Push64SmiOrMint(assembler, EBX, EDI, &fall_through);
+  Push64SmiOrMint(assembler, EBX, EDI, normal_ir_body);
   // Push right as 64 bit integer.
   Push64SmiOrMint(assembler, EAX, EDI, &drop_two_fall_through);
   __ popl(EBX);       // Right.LO.
@@ -608,33 +609,39 @@
 
   __ Bind(&drop_two_fall_through);
   __ Drop(2);
-  __ Bind(&fall_through);
+  __ Bind(normal_ir_body);
 }
 
-void Intrinsifier::Integer_greaterThanFromInt(Assembler* assembler) {
-  CompareIntegers(assembler, LESS);
+void Intrinsifier::Integer_greaterThanFromInt(Assembler* assembler,
+                                              Label* normal_ir_body) {
+  CompareIntegers(assembler, normal_ir_body, LESS);
 }
 
-void Intrinsifier::Integer_lessThan(Assembler* assembler) {
-  Integer_greaterThanFromInt(assembler);
+void Intrinsifier::Integer_lessThan(Assembler* assembler,
+                                    Label* normal_ir_body) {
+  Integer_greaterThanFromInt(assembler, normal_ir_body);
 }
 
-void Intrinsifier::Integer_greaterThan(Assembler* assembler) {
-  CompareIntegers(assembler, GREATER);
+void Intrinsifier::Integer_greaterThan(Assembler* assembler,
+                                       Label* normal_ir_body) {
+  CompareIntegers(assembler, normal_ir_body, GREATER);
 }
 
-void Intrinsifier::Integer_lessEqualThan(Assembler* assembler) {
-  CompareIntegers(assembler, LESS_EQUAL);
+void Intrinsifier::Integer_lessEqualThan(Assembler* assembler,
+                                         Label* normal_ir_body) {
+  CompareIntegers(assembler, normal_ir_body, LESS_EQUAL);
 }
 
-void Intrinsifier::Integer_greaterEqualThan(Assembler* assembler) {
-  CompareIntegers(assembler, GREATER_EQUAL);
+void Intrinsifier::Integer_greaterEqualThan(Assembler* assembler,
+                                            Label* normal_ir_body) {
+  CompareIntegers(assembler, normal_ir_body, GREATER_EQUAL);
 }
 
 // This is called for Smi and Mint receivers. The right argument
 // can be Smi, Mint or double.
-void Intrinsifier::Integer_equalToInteger(Assembler* assembler) {
-  Label fall_through, true_label, check_for_mint;
+void Intrinsifier::Integer_equalToInteger(Assembler* assembler,
+                                          Label* normal_ir_body) {
+  Label true_label, check_for_mint;
   // For integer receiver '===' check first.
   __ movl(EAX, Address(ESP, +1 * kWordSize));
   __ cmpl(EAX, Address(ESP, +2 * kWordSize));
@@ -662,32 +669,32 @@
   // represented by Smi.
   __ movl(EAX, Address(ESP, +1 * kWordSize));  // Right argument.
   __ CompareClassId(EAX, kDoubleCid, EDI);
-  __ j(EQUAL, &fall_through);
+  __ j(EQUAL, normal_ir_body);
   __ LoadObject(EAX, Bool::False());  // Smi == Mint -> false.
   __ ret();
 
   __ Bind(&receiver_not_smi);
   // EAX:: receiver.
   __ CompareClassId(EAX, kMintCid, EDI);
-  __ j(NOT_EQUAL, &fall_through);
+  __ j(NOT_EQUAL, normal_ir_body);
   // Receiver is Mint, return false if right is Smi.
   __ movl(EAX, Address(ESP, +1 * kWordSize));  // Right argument.
   __ testl(EAX, Immediate(kSmiTagMask));
-  __ j(NOT_ZERO, &fall_through);
+  __ j(NOT_ZERO, normal_ir_body);
   __ LoadObject(EAX, Bool::False());
   __ ret();
   // TODO(srdjan): Implement Mint == Mint comparison.
 
-  __ Bind(&fall_through);
+  __ Bind(normal_ir_body);
 }
 
-void Intrinsifier::Integer_equal(Assembler* assembler) {
-  Integer_equalToInteger(assembler);
+void Intrinsifier::Integer_equal(Assembler* assembler, Label* normal_ir_body) {
+  Integer_equalToInteger(assembler, normal_ir_body);
 }
 
-void Intrinsifier::Integer_sar(Assembler* assembler) {
-  Label fall_through, shift_count_ok;
-  TestBothArgumentsSmis(assembler, &fall_through);
+void Intrinsifier::Integer_sar(Assembler* assembler, Label* normal_ir_body) {
+  Label shift_count_ok;
+  TestBothArgumentsSmis(assembler, normal_ir_body);
   // Can destroy ECX since we are not falling through.
   const Immediate& count_limit = Immediate(0x1F);
   // Check that the count is not larger than what the hardware can handle.
@@ -696,7 +703,7 @@
   __ SmiUntag(EAX);
   // Negative counts throw exception.
   __ cmpl(EAX, Immediate(0));
-  __ j(LESS, &fall_through, Assembler::kNearJump);
+  __ j(LESS, normal_ir_body, Assembler::kNearJump);
   __ cmpl(EAX, count_limit);
   __ j(LESS_EQUAL, &shift_count_ok, Assembler::kNearJump);
   __ movl(EAX, count_limit);
@@ -707,18 +714,18 @@
   __ sarl(EAX, ECX);
   __ SmiTag(EAX);
   __ ret();
-  __ Bind(&fall_through);
+  __ Bind(normal_ir_body);
 }
 
 // Argument is Smi (receiver).
-void Intrinsifier::Smi_bitNegate(Assembler* assembler) {
+void Intrinsifier::Smi_bitNegate(Assembler* assembler, Label* normal_ir_body) {
   __ movl(EAX, Address(ESP, +1 * kWordSize));  // Receiver.
   __ notl(EAX);
   __ andl(EAX, Immediate(~kSmiTagMask));  // Remove inverted smi-tag.
   __ ret();
 }
 
-void Intrinsifier::Smi_bitLength(Assembler* assembler) {
+void Intrinsifier::Smi_bitLength(Assembler* assembler, Label* normal_ir_body) {
   ASSERT(kSmiTagShift == 1);
   __ movl(EAX, Address(ESP, +1 * kWordSize));  // Receiver.
   // XOR with sign bit to complement bits if value is negative.
@@ -733,11 +740,12 @@
   __ ret();
 }
 
-void Intrinsifier::Smi_bitAndFromSmi(Assembler* assembler) {
-  Integer_bitAndFromInteger(assembler);
+void Intrinsifier::Smi_bitAndFromSmi(Assembler* assembler,
+                                     Label* normal_ir_body) {
+  Integer_bitAndFromInteger(assembler, normal_ir_body);
 }
 
-void Intrinsifier::Bigint_lsh(Assembler* assembler) {
+void Intrinsifier::Bigint_lsh(Assembler* assembler, Label* normal_ir_body) {
   // static void _lsh(Uint32List x_digits, int x_used, int n,
   //                  Uint32List r_digits)
 
@@ -781,7 +789,7 @@
   __ ret();
 }
 
-void Intrinsifier::Bigint_rsh(Assembler* assembler) {
+void Intrinsifier::Bigint_rsh(Assembler* assembler, Label* normal_ir_body) {
   // static void _rsh(Uint32List x_digits, int x_used, int n,
   //                  Uint32List r_digits)
 
@@ -826,7 +834,7 @@
   __ ret();
 }
 
-void Intrinsifier::Bigint_absAdd(Assembler* assembler) {
+void Intrinsifier::Bigint_absAdd(Assembler* assembler, Label* normal_ir_body) {
   // static void _absAdd(Uint32List digits, int used,
   //                     Uint32List a_digits, int a_used,
   //                     Uint32List r_digits)
@@ -885,7 +893,7 @@
   __ ret();
 }
 
-void Intrinsifier::Bigint_absSub(Assembler* assembler) {
+void Intrinsifier::Bigint_absSub(Assembler* assembler, Label* normal_ir_body) {
   // static void _absSub(Uint32List digits, int used,
   //                     Uint32List a_digits, int a_used,
   //                     Uint32List r_digits)
@@ -940,7 +948,7 @@
   __ ret();
 }
 
-void Intrinsifier::Bigint_mulAdd(Assembler* assembler) {
+void Intrinsifier::Bigint_mulAdd(Assembler* assembler, Label* normal_ir_body) {
   // Pseudo code:
   // static int _mulAdd(Uint32List x_digits, int xi,
   //                    Uint32List m_digits, int i,
@@ -1059,7 +1067,7 @@
   __ ret();
 }
 
-void Intrinsifier::Bigint_sqrAdd(Assembler* assembler) {
+void Intrinsifier::Bigint_sqrAdd(Assembler* assembler, Label* normal_ir_body) {
   // Pseudo code:
   // static int _sqrAdd(Uint32List x_digits, int i,
   //                    Uint32List a_digits, int used) {
@@ -1191,7 +1199,8 @@
   __ ret();
 }
 
-void Intrinsifier::Bigint_estimateQuotientDigit(Assembler* assembler) {
+void Intrinsifier::Bigint_estimateQuotientDigit(Assembler* assembler,
+                                                Label* normal_ir_body) {
   // Pseudo code:
   // static int _estQuotientDigit(Uint32List args, Uint32List digits, int i) {
   //   uint32_t yt = args[_YT];  // _YT == 1.
@@ -1247,7 +1256,8 @@
   __ ret();
 }
 
-void Intrinsifier::Montgomery_mulMod(Assembler* assembler) {
+void Intrinsifier::Montgomery_mulMod(Assembler* assembler,
+                                     Label* normal_ir_body) {
   // Pseudo code:
   // static int _mulMod(Uint32List args, Uint32List digits, int i) {
   //   uint32_t rho = args[_RHO];  // _RHO == 2.
@@ -1299,9 +1309,11 @@
 // type. Return true or false object in the register EAX. Any NaN argument
 // returns false. Any non-double arg1 causes control flow to fall through to the
 // slow case (compiled method body).
-static void CompareDoubles(Assembler* assembler, Condition true_condition) {
-  Label fall_through, is_false, is_true, is_smi, double_op;
-  TestLastArgumentIsDouble(assembler, &is_smi, &fall_through);
+static void CompareDoubles(Assembler* assembler,
+                           Label* normal_ir_body,
+                           Condition true_condition) {
+  Label is_false, is_true, is_smi, double_op;
+  TestLastArgumentIsDouble(assembler, &is_smi, normal_ir_body);
   // Both arguments are double, right operand is in EAX.
   __ movsd(XMM1, FieldAddress(EAX, Double::value_offset()));
   __ Bind(&double_op);
@@ -1321,39 +1333,45 @@
   __ SmiUntag(EAX);
   __ cvtsi2sd(XMM1, EAX);
   __ jmp(&double_op);
-  __ Bind(&fall_through);
+  __ Bind(normal_ir_body);
 }
 
 // arg0 is Double, arg1 is unknown.
-void Intrinsifier::Double_greaterThan(Assembler* assembler) {
-  CompareDoubles(assembler, ABOVE);
+void Intrinsifier::Double_greaterThan(Assembler* assembler,
+                                      Label* normal_ir_body) {
+  CompareDoubles(assembler, normal_ir_body, ABOVE);
 }
 
 // arg0 is Double, arg1 is unknown.
-void Intrinsifier::Double_greaterEqualThan(Assembler* assembler) {
-  CompareDoubles(assembler, ABOVE_EQUAL);
+void Intrinsifier::Double_greaterEqualThan(Assembler* assembler,
+                                           Label* normal_ir_body) {
+  CompareDoubles(assembler, normal_ir_body, ABOVE_EQUAL);
 }
 
 // arg0 is Double, arg1 is unknown.
-void Intrinsifier::Double_lessThan(Assembler* assembler) {
-  CompareDoubles(assembler, BELOW);
+void Intrinsifier::Double_lessThan(Assembler* assembler,
+                                   Label* normal_ir_body) {
+  CompareDoubles(assembler, normal_ir_body, BELOW);
 }
 
 // arg0 is Double, arg1 is unknown.
-void Intrinsifier::Double_equal(Assembler* assembler) {
-  CompareDoubles(assembler, EQUAL);
+void Intrinsifier::Double_equal(Assembler* assembler, Label* normal_ir_body) {
+  CompareDoubles(assembler, normal_ir_body, EQUAL);
 }
 
 // arg0 is Double, arg1 is unknown.
-void Intrinsifier::Double_lessEqualThan(Assembler* assembler) {
-  CompareDoubles(assembler, BELOW_EQUAL);
+void Intrinsifier::Double_lessEqualThan(Assembler* assembler,
+                                        Label* normal_ir_body) {
+  CompareDoubles(assembler, normal_ir_body, BELOW_EQUAL);
 }
 
 // Expects left argument to be double (receiver). Right argument is unknown.
 // Both arguments are on stack.
-static void DoubleArithmeticOperations(Assembler* assembler, Token::Kind kind) {
-  Label fall_through, is_smi, double_op;
-  TestLastArgumentIsDouble(assembler, &is_smi, &fall_through);
+static void DoubleArithmeticOperations(Assembler* assembler,
+                                       Label* normal_ir_body,
+                                       Token::Kind kind) {
+  Label is_smi, double_op;
+  TestLastArgumentIsDouble(assembler, &is_smi, normal_ir_body);
   // Both arguments are double, right operand is in EAX.
   __ movsd(XMM1, FieldAddress(EAX, Double::value_offset()));
   __ Bind(&double_op);
@@ -1377,7 +1395,7 @@
   }
   const Class& double_class =
       Class::Handle(Isolate::Current()->object_store()->double_class());
-  __ TryAllocate(double_class, &fall_through, Assembler::kNearJump,
+  __ TryAllocate(double_class, normal_ir_body, Assembler::kNearJump,
                  EAX,  // Result register.
                  EBX);
   __ movsd(FieldAddress(EAX, Double::value_offset()), XMM0);
@@ -1386,32 +1404,32 @@
   __ SmiUntag(EAX);
   __ cvtsi2sd(XMM1, EAX);
   __ jmp(&double_op);
-  __ Bind(&fall_through);
+  __ Bind(normal_ir_body);
 }
 
-void Intrinsifier::Double_add(Assembler* assembler) {
-  DoubleArithmeticOperations(assembler, Token::kADD);
+void Intrinsifier::Double_add(Assembler* assembler, Label* normal_ir_body) {
+  DoubleArithmeticOperations(assembler, normal_ir_body, Token::kADD);
 }
 
-void Intrinsifier::Double_mul(Assembler* assembler) {
-  DoubleArithmeticOperations(assembler, Token::kMUL);
+void Intrinsifier::Double_mul(Assembler* assembler, Label* normal_ir_body) {
+  DoubleArithmeticOperations(assembler, normal_ir_body, Token::kMUL);
 }
 
-void Intrinsifier::Double_sub(Assembler* assembler) {
-  DoubleArithmeticOperations(assembler, Token::kSUB);
+void Intrinsifier::Double_sub(Assembler* assembler, Label* normal_ir_body) {
+  DoubleArithmeticOperations(assembler, normal_ir_body, Token::kSUB);
 }
 
-void Intrinsifier::Double_div(Assembler* assembler) {
-  DoubleArithmeticOperations(assembler, Token::kDIV);
+void Intrinsifier::Double_div(Assembler* assembler, Label* normal_ir_body) {
+  DoubleArithmeticOperations(assembler, normal_ir_body, Token::kDIV);
 }
 
 // Left is double, right is integer (Mint or Smi)
-void Intrinsifier::Double_mulFromInteger(Assembler* assembler) {
-  Label fall_through;
+void Intrinsifier::Double_mulFromInteger(Assembler* assembler,
+                                         Label* normal_ir_body) {
   // Only smis allowed.
   __ movl(EAX, Address(ESP, +1 * kWordSize));
   __ testl(EAX, Immediate(kSmiTagMask));
-  __ j(NOT_ZERO, &fall_through, Assembler::kNearJump);
+  __ j(NOT_ZERO, normal_ir_body, Assembler::kNearJump);
   // Is Smi.
   __ SmiUntag(EAX);
   __ cvtsi2sd(XMM1, EAX);
@@ -1420,33 +1438,34 @@
   __ mulsd(XMM0, XMM1);
   const Class& double_class =
       Class::Handle(Isolate::Current()->object_store()->double_class());
-  __ TryAllocate(double_class, &fall_through, Assembler::kNearJump,
+  __ TryAllocate(double_class, normal_ir_body, Assembler::kNearJump,
                  EAX,  // Result register.
                  EBX);
   __ movsd(FieldAddress(EAX, Double::value_offset()), XMM0);
   __ ret();
-  __ Bind(&fall_through);
+  __ Bind(normal_ir_body);
 }
 
-void Intrinsifier::DoubleFromInteger(Assembler* assembler) {
-  Label fall_through;
+void Intrinsifier::DoubleFromInteger(Assembler* assembler,
+                                     Label* normal_ir_body) {
   __ movl(EAX, Address(ESP, +1 * kWordSize));
   __ testl(EAX, Immediate(kSmiTagMask));
-  __ j(NOT_ZERO, &fall_through, Assembler::kNearJump);
+  __ j(NOT_ZERO, normal_ir_body, Assembler::kNearJump);
   // Is Smi.
   __ SmiUntag(EAX);
   __ cvtsi2sd(XMM0, EAX);
   const Class& double_class =
       Class::Handle(Isolate::Current()->object_store()->double_class());
-  __ TryAllocate(double_class, &fall_through, Assembler::kNearJump,
+  __ TryAllocate(double_class, normal_ir_body, Assembler::kNearJump,
                  EAX,  // Result register.
                  EBX);
   __ movsd(FieldAddress(EAX, Double::value_offset()), XMM0);
   __ ret();
-  __ Bind(&fall_through);
+  __ Bind(normal_ir_body);
 }
 
-void Intrinsifier::Double_getIsNaN(Assembler* assembler) {
+void Intrinsifier::Double_getIsNaN(Assembler* assembler,
+                                   Label* normal_ir_body) {
   Label is_true;
   __ movl(EAX, Address(ESP, +1 * kWordSize));
   __ movsd(XMM0, FieldAddress(EAX, Double::value_offset()));
@@ -1459,7 +1478,8 @@
   __ ret();
 }
 
-void Intrinsifier::Double_getIsInfinite(Assembler* assembler) {
+void Intrinsifier::Double_getIsInfinite(Assembler* assembler,
+                                        Label* normal_ir_body) {
   Label not_inf;
   __ movl(EAX, Address(ESP, +1 * kWordSize));
   __ movl(EBX, FieldAddress(EAX, Double::value_offset()));
@@ -1482,7 +1502,8 @@
   __ ret();
 }
 
-void Intrinsifier::Double_getIsNegative(Assembler* assembler) {
+void Intrinsifier::Double_getIsNegative(Assembler* assembler,
+                                        Label* normal_ir_body) {
   Label is_false, is_true, is_zero;
   __ movl(EAX, Address(ESP, +1 * kWordSize));
   __ movsd(XMM0, FieldAddress(EAX, Double::value_offset()));
@@ -1505,21 +1526,22 @@
   __ jmp(&is_false, Assembler::kNearJump);
 }
 
-void Intrinsifier::DoubleToInteger(Assembler* assembler) {
+void Intrinsifier::DoubleToInteger(Assembler* assembler,
+                                   Label* normal_ir_body) {
   __ movl(EAX, Address(ESP, +1 * kWordSize));
   __ movsd(XMM0, FieldAddress(EAX, Double::value_offset()));
   __ cvttsd2si(EAX, XMM0);
   // Overflow is signalled with minint.
-  Label fall_through;
   // Check for overflow and that it fits into Smi.
   __ cmpl(EAX, Immediate(0xC0000000));
-  __ j(NEGATIVE, &fall_through, Assembler::kNearJump);
+  __ j(NEGATIVE, normal_ir_body, Assembler::kNearJump);
   __ SmiTag(EAX);
   __ ret();
-  __ Bind(&fall_through);
+  __ Bind(normal_ir_body);
 }
 
-void Intrinsifier::Double_hashCode(Assembler* assembler) {
+void Intrinsifier::Double_hashCode(Assembler* assembler,
+                                   Label* normal_ir_body) {
   // TODO(dartbug.com/31174): Convert this to a graph intrinsic.
 
   // Convert double value to signed 32-bit int in EAX and
@@ -1532,10 +1554,9 @@
   // Tag the int as a Smi, making sure that it fits; this checks for
   // overflow and NaN in the conversion from double to int. Conversion
   // overflow from cvttsd2si is signalled with an INT32_MIN value.
-  Label fall_through;
   ASSERT(kSmiTag == 0 && kSmiTagShift == 1);
   __ addl(EAX, EAX);
-  __ j(OVERFLOW, &fall_through, Assembler::kNearJump);
+  __ j(OVERFLOW, normal_ir_body, Assembler::kNearJump);
 
   // Compare the two double values. If they are equal, we return the
   // Smi tagged result immediately as the hash code.
@@ -1554,20 +1575,20 @@
   __ ret();
 
   // Fall into the native C++ implementation.
-  __ Bind(&fall_through);
+  __ Bind(normal_ir_body);
 }
 
 // Argument type is not known
-void Intrinsifier::MathSqrt(Assembler* assembler) {
-  Label fall_through, is_smi, double_op;
-  TestLastArgumentIsDouble(assembler, &is_smi, &fall_through);
+void Intrinsifier::MathSqrt(Assembler* assembler, Label* normal_ir_body) {
+  Label is_smi, double_op;
+  TestLastArgumentIsDouble(assembler, &is_smi, normal_ir_body);
   // Argument is double and is in EAX.
   __ movsd(XMM1, FieldAddress(EAX, Double::value_offset()));
   __ Bind(&double_op);
   __ sqrtsd(XMM0, XMM1);
   const Class& double_class =
       Class::Handle(Isolate::Current()->object_store()->double_class());
-  __ TryAllocate(double_class, &fall_through, Assembler::kNearJump,
+  __ TryAllocate(double_class, normal_ir_body, Assembler::kNearJump,
                  EAX,  // Result register.
                  EBX);
   __ movsd(FieldAddress(EAX, Double::value_offset()), XMM0);
@@ -1576,13 +1597,14 @@
   __ SmiUntag(EAX);
   __ cvtsi2sd(XMM1, EAX);
   __ jmp(&double_op);
-  __ Bind(&fall_through);
+  __ Bind(normal_ir_body);
 }
 
 //    var state = ((_A * (_state[kSTATE_LO])) + _state[kSTATE_HI]) & _MASK_64;
 //    _state[kSTATE_LO] = state & _MASK_32;
 //    _state[kSTATE_HI] = state >> 32;
-void Intrinsifier::Random_nextState(Assembler* assembler) {
+void Intrinsifier::Random_nextState(Assembler* assembler,
+                                    Label* normal_ir_body) {
   const Library& math_lib = Library::Handle(Library::MathLibrary());
   ASSERT(!math_lib.IsNull());
   const Class& random_class =
@@ -1618,7 +1640,7 @@
 }
 
 // Identity comparison.
-void Intrinsifier::ObjectEquals(Assembler* assembler) {
+void Intrinsifier::ObjectEquals(Assembler* assembler, Label* normal_ir_body) {
   Label is_true;
   __ movl(EAX, Address(ESP, +1 * kWordSize));
   __ cmpl(EAX, Address(ESP, +2 * kWordSize));
@@ -1665,13 +1687,14 @@
 }
 
 // Return type quickly for simple types (not parameterized and not signature).
-void Intrinsifier::ObjectRuntimeType(Assembler* assembler) {
-  Label fall_through, use_canonical_type, not_double, not_integer;
+void Intrinsifier::ObjectRuntimeType(Assembler* assembler,
+                                     Label* normal_ir_body) {
+  Label use_canonical_type, not_double, not_integer;
   __ movl(EAX, Address(ESP, +1 * kWordSize));
   __ LoadClassIdMayBeSmi(EDI, EAX);
 
   __ cmpl(EDI, Immediate(kClosureCid));
-  __ j(EQUAL, &fall_through);  // Instance is a closure.
+  __ j(EQUAL, normal_ir_body);  // Instance is a closure.
 
   __ cmpl(EDI, Immediate(kNumPredefinedCids));
   __ j(ABOVE, &use_canonical_type);
@@ -1711,24 +1734,25 @@
   __ LoadClassById(EBX, EDI);
   __ movzxw(EDI, FieldAddress(EBX, Class::num_type_arguments_offset()));
   __ cmpl(EDI, Immediate(0));
-  __ j(NOT_EQUAL, &fall_through, Assembler::kNearJump);
+  __ j(NOT_EQUAL, normal_ir_body, Assembler::kNearJump);
   __ movl(EAX, FieldAddress(EBX, Class::canonical_type_offset()));
   __ CompareObject(EAX, Object::null_object());
-  __ j(EQUAL, &fall_through, Assembler::kNearJump);  // Not yet set.
+  __ j(EQUAL, normal_ir_body, Assembler::kNearJump);  // Not yet set.
   __ ret();
 
-  __ Bind(&fall_through);
+  __ Bind(normal_ir_body);
 }
 
-void Intrinsifier::ObjectHaveSameRuntimeType(Assembler* assembler) {
-  Label fall_through, different_cids, equal, not_equal, not_integer;
+void Intrinsifier::ObjectHaveSameRuntimeType(Assembler* assembler,
+                                             Label* normal_ir_body) {
+  Label different_cids, equal, not_equal, not_integer;
 
   __ movl(EAX, Address(ESP, +1 * kWordSize));
   __ LoadClassIdMayBeSmi(EDI, EAX);
 
   // Check if left hand size is a closure. Closures are handled in the runtime.
   __ cmpl(EDI, Immediate(kClosureCid));
-  __ j(EQUAL, &fall_through);
+  __ j(EQUAL, normal_ir_body);
 
   __ movl(EAX, Address(ESP, +2 * kWordSize));
   __ LoadClassIdMayBeSmi(EBX, EAX);
@@ -1745,7 +1769,7 @@
   __ LoadClassById(EBX, EDI);
   __ movzxw(EBX, FieldAddress(EBX, Class::num_type_arguments_offset()));
   __ cmpl(EBX, Immediate(0));
-  __ j(NOT_EQUAL, &fall_through, Assembler::kNearJump);
+  __ j(NOT_EQUAL, normal_ir_body, Assembler::kNearJump);
 
   __ Bind(&equal);
   __ LoadObject(EAX, Bool::True());
@@ -1780,60 +1804,62 @@
   __ LoadObject(EAX, Bool::False());
   __ ret();
 
-  __ Bind(&fall_through);
+  __ Bind(normal_ir_body);
 }
 
-void Intrinsifier::String_getHashCode(Assembler* assembler) {
-  Label fall_through;
+void Intrinsifier::String_getHashCode(Assembler* assembler,
+                                      Label* normal_ir_body) {
   __ movl(EAX, Address(ESP, +1 * kWordSize));  // String object.
   __ movl(EAX, FieldAddress(EAX, String::hash_offset()));
   __ cmpl(EAX, Immediate(0));
-  __ j(EQUAL, &fall_through, Assembler::kNearJump);
+  __ j(EQUAL, normal_ir_body, Assembler::kNearJump);
   __ ret();
-  __ Bind(&fall_through);
+  __ Bind(normal_ir_body);
   // Hash not yet computed.
 }
 
-void Intrinsifier::Type_getHashCode(Assembler* assembler) {
-  Label fall_through;
+void Intrinsifier::Type_getHashCode(Assembler* assembler,
+                                    Label* normal_ir_body) {
   __ movl(EAX, Address(ESP, +1 * kWordSize));  // Type object.
   __ movl(EAX, FieldAddress(EAX, Type::hash_offset()));
   __ testl(EAX, EAX);
-  __ j(EQUAL, &fall_through, Assembler::kNearJump);
+  __ j(EQUAL, normal_ir_body, Assembler::kNearJump);
   __ ret();
-  __ Bind(&fall_through);
+  __ Bind(normal_ir_body);
   // Hash not yet computed.
 }
 
 // bool _substringMatches(int start, String other)
-void Intrinsifier::StringBaseSubstringMatches(Assembler* assembler) {
+void Intrinsifier::StringBaseSubstringMatches(Assembler* assembler,
+                                              Label* normal_ir_body) {
   // For precompilation, not implemented on IA32.
 }
 
-void Intrinsifier::Object_getHash(Assembler* assembler) {
+void Intrinsifier::Object_getHash(Assembler* assembler, Label* normal_ir_body) {
   UNREACHABLE();
 }
 
-void Intrinsifier::Object_setHash(Assembler* assembler) {
+void Intrinsifier::Object_setHash(Assembler* assembler, Label* normal_ir_body) {
   UNREACHABLE();
 }
 
-void Intrinsifier::StringBaseCharAt(Assembler* assembler) {
-  Label fall_through, try_two_byte_string;
+void Intrinsifier::StringBaseCharAt(Assembler* assembler,
+                                    Label* normal_ir_body) {
+  Label try_two_byte_string;
   __ movl(EBX, Address(ESP, +1 * kWordSize));  // Index.
   __ movl(EAX, Address(ESP, +2 * kWordSize));  // String.
   __ testl(EBX, Immediate(kSmiTagMask));
-  __ j(NOT_ZERO, &fall_through, Assembler::kNearJump);  // Non-smi index.
+  __ j(NOT_ZERO, normal_ir_body, Assembler::kNearJump);  // Non-smi index.
   // Range check.
   __ cmpl(EBX, FieldAddress(EAX, String::length_offset()));
   // Runtime throws exception.
-  __ j(ABOVE_EQUAL, &fall_through, Assembler::kNearJump);
+  __ j(ABOVE_EQUAL, normal_ir_body, Assembler::kNearJump);
   __ CompareClassId(EAX, kOneByteStringCid, EDI);
   __ j(NOT_EQUAL, &try_two_byte_string, Assembler::kNearJump);
   __ SmiUntag(EBX);
   __ movzxb(EBX, FieldAddress(EAX, EBX, TIMES_1, OneByteString::data_offset()));
   __ cmpl(EBX, Immediate(Symbols::kNumberOfOneCharCodeSymbols));
-  __ j(GREATER_EQUAL, &fall_through);
+  __ j(GREATER_EQUAL, normal_ir_body);
   __ movl(EAX,
           Immediate(reinterpret_cast<uword>(Symbols::PredefinedAddress())));
   __ movl(EAX, Address(EAX, EBX, TIMES_4,
@@ -1842,21 +1868,22 @@
 
   __ Bind(&try_two_byte_string);
   __ CompareClassId(EAX, kTwoByteStringCid, EDI);
-  __ j(NOT_EQUAL, &fall_through, Assembler::kNearJump);
+  __ j(NOT_EQUAL, normal_ir_body, Assembler::kNearJump);
   ASSERT(kSmiTagShift == 1);
   __ movzxw(EBX, FieldAddress(EAX, EBX, TIMES_1, TwoByteString::data_offset()));
   __ cmpl(EBX, Immediate(Symbols::kNumberOfOneCharCodeSymbols));
-  __ j(GREATER_EQUAL, &fall_through);
+  __ j(GREATER_EQUAL, normal_ir_body);
   __ movl(EAX,
           Immediate(reinterpret_cast<uword>(Symbols::PredefinedAddress())));
   __ movl(EAX, Address(EAX, EBX, TIMES_4,
                        Symbols::kNullCharCodeSymbolOffset * kWordSize));
   __ ret();
 
-  __ Bind(&fall_through);
+  __ Bind(normal_ir_body);
 }
 
-void Intrinsifier::StringBaseIsEmpty(Assembler* assembler) {
+void Intrinsifier::StringBaseIsEmpty(Assembler* assembler,
+                                     Label* normal_ir_body) {
   Label is_true;
   // Get length.
   __ movl(EAX, Address(ESP, +1 * kWordSize));  // String object.
@@ -1870,7 +1897,8 @@
   __ ret();
 }
 
-void Intrinsifier::OneByteString_getHashCode(Assembler* assembler) {
+void Intrinsifier::OneByteString_getHashCode(Assembler* assembler,
+                                             Label* normal_ir_body) {
   Label compute_hash;
   __ movl(EBX, Address(ESP, +1 * kWordSize));  // OneByteString object.
   __ movl(EAX, FieldAddress(EBX, String::hash_offset()));
@@ -2022,19 +2050,20 @@
 // Arg1: Start index as Smi.
 // Arg2: End index as Smi.
 // The indexes must be valid.
-void Intrinsifier::OneByteString_substringUnchecked(Assembler* assembler) {
+void Intrinsifier::OneByteString_substringUnchecked(Assembler* assembler,
+                                                    Label* normal_ir_body) {
   const intptr_t kStringOffset = 3 * kWordSize;
   const intptr_t kStartIndexOffset = 2 * kWordSize;
   const intptr_t kEndIndexOffset = 1 * kWordSize;
-  Label fall_through, ok;
+  Label ok;
   __ movl(EAX, Address(ESP, +kStartIndexOffset));
   __ movl(EDI, Address(ESP, +kEndIndexOffset));
   __ orl(EAX, EDI);
   __ testl(EAX, Immediate(kSmiTagMask));
-  __ j(NOT_ZERO, &fall_through);  // 'start', 'end' not Smi.
+  __ j(NOT_ZERO, normal_ir_body);  // 'start', 'end' not Smi.
 
   __ subl(EDI, Address(ESP, +kStartIndexOffset));
-  TryAllocateOnebyteString(assembler, &ok, &fall_through, EDI);
+  TryAllocateOnebyteString(assembler, &ok, normal_ir_body, EDI);
   __ Bind(&ok);
   // EAX: new string as tagged pointer.
   // Copy string.
@@ -2063,10 +2092,11 @@
   __ cmpl(EDX, ECX);
   __ j(LESS, &loop, Assembler::kNearJump);
   __ ret();
-  __ Bind(&fall_through);
+  __ Bind(normal_ir_body);
 }
 
-void Intrinsifier::OneByteStringSetAt(Assembler* assembler) {
+void Intrinsifier::OneByteStringSetAt(Assembler* assembler,
+                                      Label* normal_ir_body) {
   __ movl(ECX, Address(ESP, +1 * kWordSize));  // Value.
   __ movl(EBX, Address(ESP, +2 * kWordSize));  // Index.
   __ movl(EAX, Address(ESP, +3 * kWordSize));  // OneByteString.
@@ -2076,21 +2106,24 @@
   __ ret();
 }
 
-void Intrinsifier::OneByteString_allocate(Assembler* assembler) {
+void Intrinsifier::OneByteString_allocate(Assembler* assembler,
+                                          Label* normal_ir_body) {
   __ movl(EDI, Address(ESP, +1 * kWordSize));  // Length.
-  Label fall_through, ok;
-  TryAllocateOnebyteString(assembler, &ok, &fall_through, EDI);
+  Label ok;
+  TryAllocateOnebyteString(assembler, &ok, normal_ir_body, EDI);
   // EDI: Start address to copy from (untagged).
 
   __ Bind(&ok);
   __ ret();
 
-  __ Bind(&fall_through);
+  __ Bind(normal_ir_body);
 }
 
 // TODO(srdjan): Add combinations (one-byte/two-byte/external strings).
-static void StringEquality(Assembler* assembler, intptr_t string_cid) {
-  Label fall_through, is_true, is_false, loop;
+static void StringEquality(Assembler* assembler,
+                           Label* normal_ir_body,
+                           intptr_t string_cid) {
+  Label is_true, is_false, loop;
   __ movl(EAX, Address(ESP, +2 * kWordSize));  // This.
   __ movl(EBX, Address(ESP, +1 * kWordSize));  // Other.
 
@@ -2102,7 +2135,7 @@
   __ testl(EBX, Immediate(kSmiTagMask));
   __ j(ZERO, &is_false);  // Smi
   __ CompareClassId(EBX, string_cid, EDI);
-  __ j(NOT_EQUAL, &fall_through, Assembler::kNearJump);
+  __ j(NOT_EQUAL, normal_ir_body, Assembler::kNearJump);
 
   // Have same length?
   __ movl(EDI, FieldAddress(EAX, String::length_offset()));
@@ -2141,18 +2174,21 @@
   __ LoadObject(EAX, Bool::False());
   __ ret();
 
-  __ Bind(&fall_through);
+  __ Bind(normal_ir_body);
 }
 
-void Intrinsifier::OneByteString_equality(Assembler* assembler) {
-  StringEquality(assembler, kOneByteStringCid);
+void Intrinsifier::OneByteString_equality(Assembler* assembler,
+                                          Label* normal_ir_body) {
+  StringEquality(assembler, normal_ir_body, kOneByteStringCid);
 }
 
-void Intrinsifier::TwoByteString_equality(Assembler* assembler) {
-  StringEquality(assembler, kTwoByteStringCid);
+void Intrinsifier::TwoByteString_equality(Assembler* assembler,
+                                          Label* normal_ir_body) {
+  StringEquality(assembler, normal_ir_body, kTwoByteStringCid);
 }
 
 void Intrinsifier::IntrinsifyRegExpExecuteMatch(Assembler* assembler,
+                                                Label* normal_ir_body,
                                                 bool sticky) {
   if (FLAG_interpret_irregexp) return;
 
@@ -2185,7 +2221,8 @@
 }
 
 // On stack: user tag (+1), return-address (+0).
-void Intrinsifier::UserTag_makeCurrent(Assembler* assembler) {
+void Intrinsifier::UserTag_makeCurrent(Assembler* assembler,
+                                       Label* normal_ir_body) {
   // RDI: Isolate.
   __ LoadIsolate(EDI);
   // EAX: Current user tag.
@@ -2201,23 +2238,25 @@
   __ ret();
 }
 
-void Intrinsifier::UserTag_defaultTag(Assembler* assembler) {
+void Intrinsifier::UserTag_defaultTag(Assembler* assembler,
+                                      Label* normal_ir_body) {
   __ LoadIsolate(EAX);
   __ movl(EAX, Address(EAX, Isolate::default_tag_offset()));
   __ ret();
 }
 
-void Intrinsifier::Profiler_getCurrentTag(Assembler* assembler) {
+void Intrinsifier::Profiler_getCurrentTag(Assembler* assembler,
+                                          Label* normal_ir_body) {
   __ LoadIsolate(EAX);
   __ movl(EAX, Address(EAX, Isolate::current_tag_offset()));
   __ ret();
 }
 
-void Intrinsifier::Timeline_isDartStreamEnabled(Assembler* assembler) {
+void Intrinsifier::Timeline_isDartStreamEnabled(Assembler* assembler,
+                                                Label* normal_ir_body) {
   if (!FLAG_support_timeline) {
     __ LoadObject(EAX, Bool::False());
     __ ret();
-    return;
   }
   Label true_label;
   // Load TimelineStream*.
@@ -2235,13 +2274,15 @@
   __ ret();
 }
 
-void Intrinsifier::ClearAsyncThreadStackTrace(Assembler* assembler) {
+void Intrinsifier::ClearAsyncThreadStackTrace(Assembler* assembler,
+                                              Label* normal_ir_body) {
   __ LoadObject(EAX, Object::null_object());
   __ movl(Address(THR, Thread::async_stack_trace_offset()), EAX);
   __ ret();
 }
 
-void Intrinsifier::SetAsyncThreadStackTrace(Assembler* assembler) {
+void Intrinsifier::SetAsyncThreadStackTrace(Assembler* assembler,
+                                            Label* normal_ir_body) {
   __ movl(Address(THR, Thread::async_stack_trace_offset()), EAX);
   __ LoadObject(EAX, Object::null_object());
   __ ret();
diff --git a/runtime/vm/compiler/intrinsifier_x64.cc b/runtime/vm/compiler/intrinsifier_x64.cc
index b3bd008..5fc1f89 100644
--- a/runtime/vm/compiler/intrinsifier_x64.cc
+++ b/runtime/vm/compiler/intrinsifier_x64.cc
@@ -52,17 +52,17 @@
   assembler->movq(ARGS_DESC_REG, CALLEE_SAVED_TEMP);
 }
 
-void Intrinsifier::ObjectArraySetIndexedUnchecked(Assembler* assembler) {
-  Label fall_through;
+void Intrinsifier::ObjectArraySetIndexedUnchecked(Assembler* assembler,
+                                                  Label* normal_ir_body) {
   __ movq(RDX, Address(RSP, +1 * kWordSize));  // Value.
   __ movq(RCX, Address(RSP, +2 * kWordSize));  // Index.
   __ movq(RAX, Address(RSP, +3 * kWordSize));  // Array.
   __ testq(RCX, Immediate(kSmiTagMask));
-  __ j(NOT_ZERO, &fall_through);
+  __ j(NOT_ZERO, normal_ir_body);
   // Range check.
   __ cmpq(RCX, FieldAddress(RAX, Array::length_offset()));
   // Runtime throws exception.
-  __ j(ABOVE_EQUAL, &fall_through);
+  __ j(ABOVE_EQUAL, normal_ir_body);
   // Note that RBX is Smi, i.e, times 2.
   ASSERT(kSmiTagShift == 1);
   // Destroy RCX (ic data) as we will not continue in the function.
@@ -70,23 +70,23 @@
                      RDX);
   // Caller is responsible of preserving the value if necessary.
   __ ret();
-  __ Bind(&fall_through);
+  __ Bind(normal_ir_body);
 }
 
 // Allocate a GrowableObjectArray using the backing array specified.
 // On stack: type argument (+2), data (+1), return-address (+0).
-void Intrinsifier::GrowableArray_Allocate(Assembler* assembler) {
+void Intrinsifier::GrowableArray_Allocate(Assembler* assembler,
+                                          Label* normal_ir_body) {
   // This snippet of inlined code uses the following registers:
   // RAX, RCX, R13
   // and the newly allocated object is returned in RAX.
   const intptr_t kTypeArgumentsOffset = 2 * kWordSize;
   const intptr_t kArrayOffset = 1 * kWordSize;
-  Label fall_through;
 
   // Try allocating in new space.
   const Class& cls = Class::Handle(
       Isolate::Current()->object_store()->growable_object_array_class());
-  __ TryAllocate(cls, &fall_through, Assembler::kFarJump, RAX, R13);
+  __ TryAllocate(cls, normal_ir_body, Assembler::kFarJump, RAX, R13);
 
   // Store backing array object in growable array object.
   __ movq(RCX, Address(RSP, kArrayOffset));  // data argument.
@@ -105,16 +105,17 @@
   __ ZeroInitSmiField(FieldAddress(RAX, GrowableObjectArray::length_offset()));
   __ ret();  // returns the newly allocated object in RAX.
 
-  __ Bind(&fall_through);
+  __ Bind(normal_ir_body);
 }
 
 // Add an element to growable array if it doesn't need to grow, otherwise
 // call into regular code.
 // On stack: growable array (+2), value (+1), return-address (+0).
-void Intrinsifier::GrowableArray_add(Assembler* assembler) {
+void Intrinsifier::GrowableArray_add(Assembler* assembler,
+                                     Label* normal_ir_body) {
   // In checked mode we need to check the incoming argument.
   if (Isolate::Current()->argument_type_checks()) return;
-  Label fall_through;
+
   __ movq(RAX, Address(RSP, +2 * kWordSize));  // Array.
   __ movq(RCX, FieldAddress(RAX, GrowableObjectArray::length_offset()));
   // RCX: length.
@@ -122,7 +123,7 @@
   // RDX: data.
   // Compare length with capacity.
   __ cmpq(RCX, FieldAddress(RDX, Array::length_offset()));
-  __ j(EQUAL, &fall_through);  // Must grow data.
+  __ j(EQUAL, normal_ir_body);  // Must grow data.
   // len = len + 1;
   __ IncrementSmiField(FieldAddress(RAX, GrowableObjectArray::length_offset()),
                        1);
@@ -132,25 +133,25 @@
                      RAX);
   __ LoadObject(RAX, Object::null_object());
   __ ret();
-  __ Bind(&fall_through);
+  __ Bind(normal_ir_body);
 }
 
 #define TYPED_ARRAY_ALLOCATION(type_name, cid, max_len, scale_factor)          \
   Label fall_through;                                                          \
   const intptr_t kArrayLengthStackOffset = 1 * kWordSize;                      \
-  NOT_IN_PRODUCT(__ MaybeTraceAllocation(cid, &fall_through, false));          \
+  NOT_IN_PRODUCT(__ MaybeTraceAllocation(cid, normal_ir_body, false));         \
   __ movq(RDI, Address(RSP, kArrayLengthStackOffset)); /* Array length. */     \
   /* Check that length is a positive Smi. */                                   \
   /* RDI: requested array length argument. */                                  \
   __ testq(RDI, Immediate(kSmiTagMask));                                       \
-  __ j(NOT_ZERO, &fall_through);                                               \
+  __ j(NOT_ZERO, normal_ir_body);                                              \
   __ cmpq(RDI, Immediate(0));                                                  \
-  __ j(LESS, &fall_through);                                                   \
+  __ j(LESS, normal_ir_body);                                                  \
   __ SmiUntag(RDI);                                                            \
   /* Check for maximum allowed length. */                                      \
   /* RDI: untagged array length. */                                            \
   __ cmpq(RDI, Immediate(max_len));                                            \
-  __ j(GREATER, &fall_through);                                                \
+  __ j(GREATER, normal_ir_body);                                               \
   /* Special case for scaling by 16. */                                        \
   if (scale_factor == TIMES_16) {                                              \
     /* double length of array. */                                              \
@@ -168,14 +169,14 @@
                                                                                \
   /* RDI: allocation size. */                                                  \
   __ addq(RCX, RDI);                                                           \
-  __ j(CARRY, &fall_through);                                                  \
+  __ j(CARRY, normal_ir_body);                                                 \
                                                                                \
   /* Check if the allocation fits into the remaining space. */                 \
   /* RAX: potential new object start. */                                       \
   /* RCX: potential next object start. */                                      \
   /* RDI: allocation size. */                                                  \
   __ cmpq(RCX, Address(THR, Thread::end_offset()));                            \
-  __ j(ABOVE_EQUAL, &fall_through);                                            \
+  __ j(ABOVE_EQUAL, normal_ir_body);                                           \
                                                                                \
   /* Successfully allocated the object(s), now update top to point to */       \
   /* next object start and initialize the object. */                           \
@@ -229,7 +230,7 @@
   __ Bind(&done);                                                              \
                                                                                \
   __ ret();                                                                    \
-  __ Bind(&fall_through);
+  __ Bind(normal_ir_body);
 
 static ScaleFactor GetScaleFactor(intptr_t size) {
   switch (size) {
@@ -249,7 +250,8 @@
 }
 
 #define TYPED_DATA_ALLOCATOR(clazz)                                            \
-  void Intrinsifier::TypedData_##clazz##_factory(Assembler* assembler) {       \
+  void Intrinsifier::TypedData_##clazz##_factory(Assembler* assembler,         \
+                                                 Label* normal_ir_body) {      \
     intptr_t size = TypedData::ElementSizeInBytes(kTypedData##clazz##Cid);     \
     intptr_t max_len = TypedData::MaxNewSpaceElements(kTypedData##clazz##Cid); \
     ScaleFactor scale = GetScaleFactor(size);                                  \
@@ -268,60 +270,59 @@
   __ j(NOT_ZERO, not_smi);
 }
 
-void Intrinsifier::Integer_addFromInteger(Assembler* assembler) {
-  Label fall_through;
-  TestBothArgumentsSmis(assembler, &fall_through);
+void Intrinsifier::Integer_addFromInteger(Assembler* assembler,
+                                          Label* normal_ir_body) {
+  TestBothArgumentsSmis(assembler, normal_ir_body);
   // RAX contains right argument.
   __ addq(RAX, Address(RSP, +2 * kWordSize));
-  __ j(OVERFLOW, &fall_through, Assembler::kNearJump);
+  __ j(OVERFLOW, normal_ir_body, Assembler::kNearJump);
   // Result is in RAX.
   __ ret();
-  __ Bind(&fall_through);
+  __ Bind(normal_ir_body);
 }
 
-void Intrinsifier::Integer_add(Assembler* assembler) {
-  Integer_addFromInteger(assembler);
+void Intrinsifier::Integer_add(Assembler* assembler, Label* normal_ir_body) {
+  Integer_addFromInteger(assembler, normal_ir_body);
 }
 
-void Intrinsifier::Integer_subFromInteger(Assembler* assembler) {
-  Label fall_through;
-  TestBothArgumentsSmis(assembler, &fall_through);
+void Intrinsifier::Integer_subFromInteger(Assembler* assembler,
+                                          Label* normal_ir_body) {
+  TestBothArgumentsSmis(assembler, normal_ir_body);
   // RAX contains right argument, which is the actual minuend of subtraction.
   __ subq(RAX, Address(RSP, +2 * kWordSize));
-  __ j(OVERFLOW, &fall_through, Assembler::kNearJump);
+  __ j(OVERFLOW, normal_ir_body, Assembler::kNearJump);
   // Result is in RAX.
   __ ret();
-  __ Bind(&fall_through);
+  __ Bind(normal_ir_body);
 }
 
-void Intrinsifier::Integer_sub(Assembler* assembler) {
-  Label fall_through;
-  TestBothArgumentsSmis(assembler, &fall_through);
+void Intrinsifier::Integer_sub(Assembler* assembler, Label* normal_ir_body) {
+  TestBothArgumentsSmis(assembler, normal_ir_body);
   // RAX contains right argument, which is the actual subtrahend of subtraction.
   __ movq(RCX, RAX);
   __ movq(RAX, Address(RSP, +2 * kWordSize));
   __ subq(RAX, RCX);
-  __ j(OVERFLOW, &fall_through, Assembler::kNearJump);
+  __ j(OVERFLOW, normal_ir_body, Assembler::kNearJump);
   // Result is in RAX.
   __ ret();
-  __ Bind(&fall_through);
+  __ Bind(normal_ir_body);
 }
 
-void Intrinsifier::Integer_mulFromInteger(Assembler* assembler) {
-  Label fall_through;
-  TestBothArgumentsSmis(assembler, &fall_through);
+void Intrinsifier::Integer_mulFromInteger(Assembler* assembler,
+                                          Label* normal_ir_body) {
+  TestBothArgumentsSmis(assembler, normal_ir_body);
   // RAX is the right argument.
   ASSERT(kSmiTag == 0);  // Adjust code below if not the case.
   __ SmiUntag(RAX);
   __ imulq(RAX, Address(RSP, +2 * kWordSize));
-  __ j(OVERFLOW, &fall_through, Assembler::kNearJump);
+  __ j(OVERFLOW, normal_ir_body, Assembler::kNearJump);
   // Result is in RAX.
   __ ret();
-  __ Bind(&fall_through);
+  __ Bind(normal_ir_body);
 }
 
-void Intrinsifier::Integer_mul(Assembler* assembler) {
-  Integer_mulFromInteger(assembler);
+void Intrinsifier::Integer_mul(Assembler* assembler, Label* normal_ir_body) {
+  Integer_mulFromInteger(assembler, normal_ir_body);
 }
 
 // Optimizations:
@@ -396,14 +397,15 @@
 //      res = res + right;
 //    }
 //  }
-void Intrinsifier::Integer_moduloFromInteger(Assembler* assembler) {
-  Label fall_through, negative_result;
-  TestBothArgumentsSmis(assembler, &fall_through);
+void Intrinsifier::Integer_moduloFromInteger(Assembler* assembler,
+                                             Label* normal_ir_body) {
+  Label negative_result;
+  TestBothArgumentsSmis(assembler, normal_ir_body);
   __ movq(RCX, Address(RSP, +2 * kWordSize));
   // RAX: Tagged left (dividend).
   // RCX: Tagged right (divisor).
   __ cmpq(RCX, Immediate(0));
-  __ j(EQUAL, &fall_through);
+  __ j(EQUAL, normal_ir_body);
   EmitRemainderOperation(assembler);
   // Untagged remainder result in RAX.
   __ cmpq(RAX, Immediate(0));
@@ -426,15 +428,16 @@
   __ SmiTag(RAX);
   __ ret();
 
-  __ Bind(&fall_through);
+  __ Bind(normal_ir_body);
 }
 
-void Intrinsifier::Integer_truncDivide(Assembler* assembler) {
-  Label fall_through, not_32bit;
-  TestBothArgumentsSmis(assembler, &fall_through);
+void Intrinsifier::Integer_truncDivide(Assembler* assembler,
+                                       Label* normal_ir_body) {
+  Label not_32bit;
+  TestBothArgumentsSmis(assembler, normal_ir_body);
   // RAX: right argument (divisor)
   __ cmpq(RAX, Immediate(0));
-  __ j(EQUAL, &fall_through, Assembler::kNearJump);
+  __ j(EQUAL, normal_ir_body, Assembler::kNearJump);
   __ movq(RCX, RAX);
   __ movq(RAX, Address(RSP, +2 * kWordSize));  // Left argument (dividend).
 
@@ -469,74 +472,73 @@
   // Check the corner case of dividing the 'MIN_SMI' with -1, in which case we
   // cannot tag the result.
   __ cmpq(RAX, Immediate(0x4000000000000000));
-  __ j(EQUAL, &fall_through);
+  __ j(EQUAL, normal_ir_body);
   __ SmiTag(RAX);
   __ ret();
-  __ Bind(&fall_through);
+  __ Bind(normal_ir_body);
 }
 
-void Intrinsifier::Integer_negate(Assembler* assembler) {
-  Label fall_through;
+void Intrinsifier::Integer_negate(Assembler* assembler, Label* normal_ir_body) {
   __ movq(RAX, Address(RSP, +1 * kWordSize));
   __ testq(RAX, Immediate(kSmiTagMask));
-  __ j(NOT_ZERO, &fall_through, Assembler::kNearJump);  // Non-smi value.
+  __ j(NOT_ZERO, normal_ir_body, Assembler::kNearJump);  // Non-smi value.
   __ negq(RAX);
-  __ j(OVERFLOW, &fall_through, Assembler::kNearJump);
+  __ j(OVERFLOW, normal_ir_body, Assembler::kNearJump);
   // Result is in RAX.
   __ ret();
-  __ Bind(&fall_through);
+  __ Bind(normal_ir_body);
 }
 
-void Intrinsifier::Integer_bitAndFromInteger(Assembler* assembler) {
-  Label fall_through;
-  TestBothArgumentsSmis(assembler, &fall_through);
+void Intrinsifier::Integer_bitAndFromInteger(Assembler* assembler,
+                                             Label* normal_ir_body) {
+  TestBothArgumentsSmis(assembler, normal_ir_body);
   // RAX is the right argument.
   __ andq(RAX, Address(RSP, +2 * kWordSize));
   // Result is in RAX.
   __ ret();
-  __ Bind(&fall_through);
+  __ Bind(normal_ir_body);
 }
 
-void Intrinsifier::Integer_bitAnd(Assembler* assembler) {
-  Integer_bitAndFromInteger(assembler);
+void Intrinsifier::Integer_bitAnd(Assembler* assembler, Label* normal_ir_body) {
+  Integer_bitAndFromInteger(assembler, normal_ir_body);
 }
 
-void Intrinsifier::Integer_bitOrFromInteger(Assembler* assembler) {
-  Label fall_through;
-  TestBothArgumentsSmis(assembler, &fall_through);
+void Intrinsifier::Integer_bitOrFromInteger(Assembler* assembler,
+                                            Label* normal_ir_body) {
+  TestBothArgumentsSmis(assembler, normal_ir_body);
   // RAX is the right argument.
   __ orq(RAX, Address(RSP, +2 * kWordSize));
   // Result is in RAX.
   __ ret();
-  __ Bind(&fall_through);
+  __ Bind(normal_ir_body);
 }
 
-void Intrinsifier::Integer_bitOr(Assembler* assembler) {
-  Integer_bitOrFromInteger(assembler);
+void Intrinsifier::Integer_bitOr(Assembler* assembler, Label* normal_ir_body) {
+  Integer_bitOrFromInteger(assembler, normal_ir_body);
 }
 
-void Intrinsifier::Integer_bitXorFromInteger(Assembler* assembler) {
-  Label fall_through;
-  TestBothArgumentsSmis(assembler, &fall_through);
+void Intrinsifier::Integer_bitXorFromInteger(Assembler* assembler,
+                                             Label* normal_ir_body) {
+  TestBothArgumentsSmis(assembler, normal_ir_body);
   // RAX is the right argument.
   __ xorq(RAX, Address(RSP, +2 * kWordSize));
   // Result is in RAX.
   __ ret();
-  __ Bind(&fall_through);
+  __ Bind(normal_ir_body);
 }
 
-void Intrinsifier::Integer_bitXor(Assembler* assembler) {
-  Integer_bitXorFromInteger(assembler);
+void Intrinsifier::Integer_bitXor(Assembler* assembler, Label* normal_ir_body) {
+  Integer_bitXorFromInteger(assembler, normal_ir_body);
 }
 
-void Intrinsifier::Integer_shl(Assembler* assembler) {
+void Intrinsifier::Integer_shl(Assembler* assembler, Label* normal_ir_body) {
   ASSERT(kSmiTagShift == 1);
   ASSERT(kSmiTag == 0);
-  Label fall_through, overflow;
-  TestBothArgumentsSmis(assembler, &fall_through);
+  Label overflow;
+  TestBothArgumentsSmis(assembler, normal_ir_body);
   // Shift value is in RAX. Compare with tagged Smi.
   __ cmpq(RAX, Immediate(Smi::RawValue(Smi::kBits)));
-  __ j(ABOVE_EQUAL, &fall_through, Assembler::kNearJump);
+  __ j(ABOVE_EQUAL, normal_ir_body, Assembler::kNearJump);
 
   __ SmiUntag(RAX);
   __ movq(RCX, RAX);                           // Shift amount must be in RCX.
@@ -557,12 +559,14 @@
   __ Bind(&overflow);
   // Mint is rarely used on x64 (only for integers requiring 64 bit instead of
   // 63 bits as represented by Smi).
-  __ Bind(&fall_through);
+  __ Bind(normal_ir_body);
 }
 
-static void CompareIntegers(Assembler* assembler, Condition true_condition) {
-  Label fall_through, true_label;
-  TestBothArgumentsSmis(assembler, &fall_through);
+static void CompareIntegers(Assembler* assembler,
+                            Label* normal_ir_body,
+                            Condition true_condition) {
+  Label true_label;
+  TestBothArgumentsSmis(assembler, normal_ir_body);
   // RAX contains the right argument.
   __ cmpq(Address(RSP, +2 * kWordSize), RAX);
   __ j(true_condition, &true_label, Assembler::kNearJump);
@@ -571,33 +575,39 @@
   __ Bind(&true_label);
   __ LoadObject(RAX, Bool::True());
   __ ret();
-  __ Bind(&fall_through);
+  __ Bind(normal_ir_body);
 }
 
-void Intrinsifier::Integer_lessThan(Assembler* assembler) {
-  CompareIntegers(assembler, LESS);
+void Intrinsifier::Integer_lessThan(Assembler* assembler,
+                                    Label* normal_ir_body) {
+  CompareIntegers(assembler, normal_ir_body, LESS);
 }
 
-void Intrinsifier::Integer_greaterThanFromInt(Assembler* assembler) {
-  CompareIntegers(assembler, LESS);
+void Intrinsifier::Integer_greaterThanFromInt(Assembler* assembler,
+                                              Label* normal_ir_body) {
+  CompareIntegers(assembler, normal_ir_body, LESS);
 }
 
-void Intrinsifier::Integer_greaterThan(Assembler* assembler) {
-  CompareIntegers(assembler, GREATER);
+void Intrinsifier::Integer_greaterThan(Assembler* assembler,
+                                       Label* normal_ir_body) {
+  CompareIntegers(assembler, normal_ir_body, GREATER);
 }
 
-void Intrinsifier::Integer_lessEqualThan(Assembler* assembler) {
-  CompareIntegers(assembler, LESS_EQUAL);
+void Intrinsifier::Integer_lessEqualThan(Assembler* assembler,
+                                         Label* normal_ir_body) {
+  CompareIntegers(assembler, normal_ir_body, LESS_EQUAL);
 }
 
-void Intrinsifier::Integer_greaterEqualThan(Assembler* assembler) {
-  CompareIntegers(assembler, GREATER_EQUAL);
+void Intrinsifier::Integer_greaterEqualThan(Assembler* assembler,
+                                            Label* normal_ir_body) {
+  CompareIntegers(assembler, normal_ir_body, GREATER_EQUAL);
 }
 
 // This is called for Smi and Mint receivers. The right argument
 // can be Smi, Mint or double.
-void Intrinsifier::Integer_equalToInteger(Assembler* assembler) {
-  Label fall_through, true_label, check_for_mint;
+void Intrinsifier::Integer_equalToInteger(Assembler* assembler,
+                                          Label* normal_ir_body) {
+  Label true_label, check_for_mint;
   const intptr_t kReceiverOffset = 2;
   const intptr_t kArgumentOffset = 1;
 
@@ -628,33 +638,33 @@
   // represented by Smi.
   __ movq(RAX, Address(RSP, +kArgumentOffset * kWordSize));
   __ CompareClassId(RAX, kDoubleCid);
-  __ j(EQUAL, &fall_through);
+  __ j(EQUAL, normal_ir_body);
   __ LoadObject(RAX, Bool::False());
   __ ret();
 
   __ Bind(&receiver_not_smi);
   // RAX:: receiver.
   __ CompareClassId(RAX, kMintCid);
-  __ j(NOT_EQUAL, &fall_through);
+  __ j(NOT_EQUAL, normal_ir_body);
   // Receiver is Mint, return false if right is Smi.
   __ movq(RAX, Address(RSP, +kArgumentOffset * kWordSize));
   __ testq(RAX, Immediate(kSmiTagMask));
-  __ j(NOT_ZERO, &fall_through);
+  __ j(NOT_ZERO, normal_ir_body);
   // Smi == Mint -> false.
   __ LoadObject(RAX, Bool::False());
   __ ret();
   // TODO(srdjan): Implement Mint == Mint comparison.
 
-  __ Bind(&fall_through);
+  __ Bind(normal_ir_body);
 }
 
-void Intrinsifier::Integer_equal(Assembler* assembler) {
-  Integer_equalToInteger(assembler);
+void Intrinsifier::Integer_equal(Assembler* assembler, Label* normal_ir_body) {
+  Integer_equalToInteger(assembler, normal_ir_body);
 }
 
-void Intrinsifier::Integer_sar(Assembler* assembler) {
-  Label fall_through, shift_count_ok;
-  TestBothArgumentsSmis(assembler, &fall_through);
+void Intrinsifier::Integer_sar(Assembler* assembler, Label* normal_ir_body) {
+  Label shift_count_ok;
+  TestBothArgumentsSmis(assembler, normal_ir_body);
   const Immediate& count_limit = Immediate(0x3F);
   // Check that the count is not larger than what the hardware can handle.
   // For shifting right a Smi the result is the same for all numbers
@@ -662,7 +672,7 @@
   __ SmiUntag(RAX);
   // Negative counts throw exception.
   __ cmpq(RAX, Immediate(0));
-  __ j(LESS, &fall_through, Assembler::kNearJump);
+  __ j(LESS, normal_ir_body, Assembler::kNearJump);
   __ cmpq(RAX, count_limit);
   __ j(LESS_EQUAL, &shift_count_ok, Assembler::kNearJump);
   __ movq(RAX, count_limit);
@@ -673,18 +683,18 @@
   __ sarq(RAX, RCX);
   __ SmiTag(RAX);
   __ ret();
-  __ Bind(&fall_through);
+  __ Bind(normal_ir_body);
 }
 
 // Argument is Smi (receiver).
-void Intrinsifier::Smi_bitNegate(Assembler* assembler) {
+void Intrinsifier::Smi_bitNegate(Assembler* assembler, Label* normal_ir_body) {
   __ movq(RAX, Address(RSP, +1 * kWordSize));  // Index.
   __ notq(RAX);
   __ andq(RAX, Immediate(~kSmiTagMask));  // Remove inverted smi-tag.
   __ ret();
 }
 
-void Intrinsifier::Smi_bitLength(Assembler* assembler) {
+void Intrinsifier::Smi_bitLength(Assembler* assembler, Label* normal_ir_body) {
   ASSERT(kSmiTagShift == 1);
   __ movq(RAX, Address(RSP, +1 * kWordSize));  // Index.
   // XOR with sign bit to complement bits if value is negative.
@@ -699,11 +709,12 @@
   __ ret();
 }
 
-void Intrinsifier::Smi_bitAndFromSmi(Assembler* assembler) {
-  Integer_bitAndFromInteger(assembler);
+void Intrinsifier::Smi_bitAndFromSmi(Assembler* assembler,
+                                     Label* normal_ir_body) {
+  Integer_bitAndFromInteger(assembler, normal_ir_body);
 }
 
-void Intrinsifier::Bigint_lsh(Assembler* assembler) {
+void Intrinsifier::Bigint_lsh(Assembler* assembler, Label* normal_ir_body) {
   // static void _lsh(Uint32List x_digits, int x_used, int n,
   //                  Uint32List r_digits)
 
@@ -741,7 +752,7 @@
   __ ret();
 }
 
-void Intrinsifier::Bigint_rsh(Assembler* assembler) {
+void Intrinsifier::Bigint_rsh(Assembler* assembler, Label* normal_ir_body) {
   // static void _rsh(Uint32List x_digits, int x_used, int n,
   //                  Uint32List r_digits)
 
@@ -777,7 +788,7 @@
   __ ret();
 }
 
-void Intrinsifier::Bigint_absAdd(Assembler* assembler) {
+void Intrinsifier::Bigint_absAdd(Assembler* assembler, Label* normal_ir_body) {
   // static void _absAdd(Uint32List digits, int used,
   //                     Uint32List a_digits, int a_used,
   //                     Uint32List r_digits)
@@ -832,7 +843,7 @@
   __ ret();
 }
 
-void Intrinsifier::Bigint_absSub(Assembler* assembler) {
+void Intrinsifier::Bigint_absSub(Assembler* assembler, Label* normal_ir_body) {
   // static void _absSub(Uint32List digits, int used,
   //                     Uint32List a_digits, int a_used,
   //                     Uint32List r_digits)
@@ -881,7 +892,7 @@
   __ ret();
 }
 
-void Intrinsifier::Bigint_mulAdd(Assembler* assembler) {
+void Intrinsifier::Bigint_mulAdd(Assembler* assembler, Label* normal_ir_body) {
   // Pseudo code:
   // static int _mulAdd(Uint32List x_digits, int xi,
   //                    Uint32List m_digits, int i,
@@ -988,7 +999,7 @@
   __ ret();
 }
 
-void Intrinsifier::Bigint_sqrAdd(Assembler* assembler) {
+void Intrinsifier::Bigint_sqrAdd(Assembler* assembler, Label* normal_ir_body) {
   // Pseudo code:
   // static int _sqrAdd(Uint32List x_digits, int i,
   //                    Uint32List a_digits, int used) {
@@ -1107,7 +1118,8 @@
   __ ret();
 }
 
-void Intrinsifier::Bigint_estimateQuotientDigit(Assembler* assembler) {
+void Intrinsifier::Bigint_estimateQuotientDigit(Assembler* assembler,
+                                                Label* normal_ir_body) {
   // Pseudo code:
   // static int _estQuotientDigit(Uint32List args, Uint32List digits, int i) {
   //   uint64_t yt = args[_YT_LO .. _YT];  // _YT_LO == 0, _YT == 1.
@@ -1163,7 +1175,8 @@
   __ ret();
 }
 
-void Intrinsifier::Montgomery_mulMod(Assembler* assembler) {
+void Intrinsifier::Montgomery_mulMod(Assembler* assembler,
+                                     Label* normal_ir_body) {
   // Pseudo code:
   // static int _mulMod(Uint32List args, Uint32List digits, int i) {
   //   uint64_t rho = args[_RHO .. _RHO_HI];  // _RHO == 2, _RHO_HI == 3.
@@ -1215,9 +1228,11 @@
 // unknown type. Return true or false object in RAX. Any NaN argument
 // returns false. Any non-double argument causes control flow to fall through
 // to the slow case (compiled method body).
-static void CompareDoubles(Assembler* assembler, Condition true_condition) {
-  Label fall_through, is_false, is_true, is_smi, double_op;
-  TestLastArgumentIsDouble(assembler, &is_smi, &fall_through);
+static void CompareDoubles(Assembler* assembler,
+                           Label* normal_ir_body,
+                           Condition true_condition) {
+  Label is_false, is_true, is_smi, double_op;
+  TestLastArgumentIsDouble(assembler, &is_smi, normal_ir_body);
   // Both arguments are double, right operand is in RAX.
   __ movsd(XMM1, FieldAddress(RAX, Double::value_offset()));
   __ Bind(&double_op);
@@ -1237,34 +1252,40 @@
   __ SmiUntag(RAX);
   __ cvtsi2sdq(XMM1, RAX);
   __ jmp(&double_op);
-  __ Bind(&fall_through);
+  __ Bind(normal_ir_body);
 }
 
-void Intrinsifier::Double_greaterThan(Assembler* assembler) {
-  CompareDoubles(assembler, ABOVE);
+void Intrinsifier::Double_greaterThan(Assembler* assembler,
+                                      Label* normal_ir_body) {
+  CompareDoubles(assembler, normal_ir_body, ABOVE);
 }
 
-void Intrinsifier::Double_greaterEqualThan(Assembler* assembler) {
-  CompareDoubles(assembler, ABOVE_EQUAL);
+void Intrinsifier::Double_greaterEqualThan(Assembler* assembler,
+                                           Label* normal_ir_body) {
+  CompareDoubles(assembler, normal_ir_body, ABOVE_EQUAL);
 }
 
-void Intrinsifier::Double_lessThan(Assembler* assembler) {
-  CompareDoubles(assembler, BELOW);
+void Intrinsifier::Double_lessThan(Assembler* assembler,
+                                   Label* normal_ir_body) {
+  CompareDoubles(assembler, normal_ir_body, BELOW);
 }
 
-void Intrinsifier::Double_equal(Assembler* assembler) {
-  CompareDoubles(assembler, EQUAL);
+void Intrinsifier::Double_equal(Assembler* assembler, Label* normal_ir_body) {
+  CompareDoubles(assembler, normal_ir_body, EQUAL);
 }
 
-void Intrinsifier::Double_lessEqualThan(Assembler* assembler) {
-  CompareDoubles(assembler, BELOW_EQUAL);
+void Intrinsifier::Double_lessEqualThan(Assembler* assembler,
+                                        Label* normal_ir_body) {
+  CompareDoubles(assembler, normal_ir_body, BELOW_EQUAL);
 }
 
 // Expects left argument to be double (receiver). Right argument is unknown.
 // Both arguments are on stack.
-static void DoubleArithmeticOperations(Assembler* assembler, Token::Kind kind) {
-  Label fall_through, is_smi, double_op;
-  TestLastArgumentIsDouble(assembler, &is_smi, &fall_through);
+static void DoubleArithmeticOperations(Assembler* assembler,
+                                       Label* normal_ir_body,
+                                       Token::Kind kind) {
+  Label is_smi, double_op;
+  TestLastArgumentIsDouble(assembler, &is_smi, normal_ir_body);
   // Both arguments are double, right operand is in RAX.
   __ movsd(XMM1, FieldAddress(RAX, Double::value_offset()));
   __ Bind(&double_op);
@@ -1288,7 +1309,7 @@
   }
   const Class& double_class =
       Class::Handle(Isolate::Current()->object_store()->double_class());
-  __ TryAllocate(double_class, &fall_through, Assembler::kFarJump,
+  __ TryAllocate(double_class, normal_ir_body, Assembler::kFarJump,
                  RAX,  // Result register.
                  R13);
   __ movsd(FieldAddress(RAX, Double::value_offset()), XMM0);
@@ -1297,31 +1318,31 @@
   __ SmiUntag(RAX);
   __ cvtsi2sdq(XMM1, RAX);
   __ jmp(&double_op);
-  __ Bind(&fall_through);
+  __ Bind(normal_ir_body);
 }
 
-void Intrinsifier::Double_add(Assembler* assembler) {
-  DoubleArithmeticOperations(assembler, Token::kADD);
+void Intrinsifier::Double_add(Assembler* assembler, Label* normal_ir_body) {
+  DoubleArithmeticOperations(assembler, normal_ir_body, Token::kADD);
 }
 
-void Intrinsifier::Double_mul(Assembler* assembler) {
-  DoubleArithmeticOperations(assembler, Token::kMUL);
+void Intrinsifier::Double_mul(Assembler* assembler, Label* normal_ir_body) {
+  DoubleArithmeticOperations(assembler, normal_ir_body, Token::kMUL);
 }
 
-void Intrinsifier::Double_sub(Assembler* assembler) {
-  DoubleArithmeticOperations(assembler, Token::kSUB);
+void Intrinsifier::Double_sub(Assembler* assembler, Label* normal_ir_body) {
+  DoubleArithmeticOperations(assembler, normal_ir_body, Token::kSUB);
 }
 
-void Intrinsifier::Double_div(Assembler* assembler) {
-  DoubleArithmeticOperations(assembler, Token::kDIV);
+void Intrinsifier::Double_div(Assembler* assembler, Label* normal_ir_body) {
+  DoubleArithmeticOperations(assembler, normal_ir_body, Token::kDIV);
 }
 
-void Intrinsifier::Double_mulFromInteger(Assembler* assembler) {
-  Label fall_through;
+void Intrinsifier::Double_mulFromInteger(Assembler* assembler,
+                                         Label* normal_ir_body) {
   // Only smis allowed.
   __ movq(RAX, Address(RSP, +1 * kWordSize));
   __ testq(RAX, Immediate(kSmiTagMask));
-  __ j(NOT_ZERO, &fall_through);
+  __ j(NOT_ZERO, normal_ir_body);
   // Is Smi.
   __ SmiUntag(RAX);
   __ cvtsi2sdq(XMM1, RAX);
@@ -1330,34 +1351,35 @@
   __ mulsd(XMM0, XMM1);
   const Class& double_class =
       Class::Handle(Isolate::Current()->object_store()->double_class());
-  __ TryAllocate(double_class, &fall_through, Assembler::kFarJump,
+  __ TryAllocate(double_class, normal_ir_body, Assembler::kFarJump,
                  RAX,  // Result register.
                  R13);
   __ movsd(FieldAddress(RAX, Double::value_offset()), XMM0);
   __ ret();
-  __ Bind(&fall_through);
+  __ Bind(normal_ir_body);
 }
 
 // Left is double, right is integer (Mint or Smi)
-void Intrinsifier::DoubleFromInteger(Assembler* assembler) {
-  Label fall_through;
+void Intrinsifier::DoubleFromInteger(Assembler* assembler,
+                                     Label* normal_ir_body) {
   __ movq(RAX, Address(RSP, +1 * kWordSize));
   __ testq(RAX, Immediate(kSmiTagMask));
-  __ j(NOT_ZERO, &fall_through);
+  __ j(NOT_ZERO, normal_ir_body);
   // Is Smi.
   __ SmiUntag(RAX);
   __ cvtsi2sdq(XMM0, RAX);
   const Class& double_class =
       Class::Handle(Isolate::Current()->object_store()->double_class());
-  __ TryAllocate(double_class, &fall_through, Assembler::kFarJump,
+  __ TryAllocate(double_class, normal_ir_body, Assembler::kFarJump,
                  RAX,  // Result register.
                  R13);
   __ movsd(FieldAddress(RAX, Double::value_offset()), XMM0);
   __ ret();
-  __ Bind(&fall_through);
+  __ Bind(normal_ir_body);
 }
 
-void Intrinsifier::Double_getIsNaN(Assembler* assembler) {
+void Intrinsifier::Double_getIsNaN(Assembler* assembler,
+                                   Label* normal_ir_body) {
   Label is_true;
   __ movq(RAX, Address(RSP, +1 * kWordSize));
   __ movsd(XMM0, FieldAddress(RAX, Double::value_offset()));
@@ -1370,7 +1392,8 @@
   __ ret();
 }
 
-void Intrinsifier::Double_getIsInfinite(Assembler* assembler) {
+void Intrinsifier::Double_getIsInfinite(Assembler* assembler,
+                                        Label* normal_ir_body) {
   Label is_inf, done;
   __ movq(RAX, Address(RSP, +1 * kWordSize));
   __ movq(RAX, FieldAddress(RAX, Double::value_offset()));
@@ -1389,7 +1412,8 @@
   __ ret();
 }
 
-void Intrinsifier::Double_getIsNegative(Assembler* assembler) {
+void Intrinsifier::Double_getIsNegative(Assembler* assembler,
+                                        Label* normal_ir_body) {
   Label is_false, is_true, is_zero;
   __ movq(RAX, Address(RSP, +1 * kWordSize));
   __ movsd(XMM0, FieldAddress(RAX, Double::value_offset()));
@@ -1412,22 +1436,23 @@
   __ jmp(&is_false, Assembler::kNearJump);
 }
 
-void Intrinsifier::DoubleToInteger(Assembler* assembler) {
+void Intrinsifier::DoubleToInteger(Assembler* assembler,
+                                   Label* normal_ir_body) {
   __ movq(RAX, Address(RSP, +1 * kWordSize));
   __ movsd(XMM0, FieldAddress(RAX, Double::value_offset()));
   __ cvttsd2siq(RAX, XMM0);
   // Overflow is signalled with minint.
-  Label fall_through;
   // Check for overflow and that it fits into Smi.
   __ movq(RCX, RAX);
   __ shlq(RCX, Immediate(1));
-  __ j(OVERFLOW, &fall_through, Assembler::kNearJump);
+  __ j(OVERFLOW, normal_ir_body, Assembler::kNearJump);
   __ SmiTag(RAX);
   __ ret();
-  __ Bind(&fall_through);
+  __ Bind(normal_ir_body);
 }
 
-void Intrinsifier::Double_hashCode(Assembler* assembler) {
+void Intrinsifier::Double_hashCode(Assembler* assembler,
+                                   Label* normal_ir_body) {
   // TODO(dartbug.com/31174): Convert this to a graph intrinsic.
 
   // Convert double value to signed 64-bit int in RAX and
@@ -1440,10 +1465,9 @@
   // Tag the int as a Smi, making sure that it fits; this checks for
   // overflow and NaN in the conversion from double to int. Conversion
   // overflow from cvttsd2si is signalled with an INT64_MIN value.
-  Label fall_through;
   ASSERT(kSmiTag == 0 && kSmiTagShift == 1);
   __ addq(RAX, RAX);
-  __ j(OVERFLOW, &fall_through, Assembler::kNearJump);
+  __ j(OVERFLOW, normal_ir_body, Assembler::kNearJump);
 
   // Compare the two double values. If they are equal, we return the
   // Smi tagged result immediately as the hash code.
@@ -1463,19 +1487,19 @@
   __ ret();
 
   // Fall into the native C++ implementation.
-  __ Bind(&fall_through);
+  __ Bind(normal_ir_body);
 }
 
-void Intrinsifier::MathSqrt(Assembler* assembler) {
-  Label fall_through, is_smi, double_op;
-  TestLastArgumentIsDouble(assembler, &is_smi, &fall_through);
+void Intrinsifier::MathSqrt(Assembler* assembler, Label* normal_ir_body) {
+  Label is_smi, double_op;
+  TestLastArgumentIsDouble(assembler, &is_smi, normal_ir_body);
   // Argument is double and is in RAX.
   __ movsd(XMM1, FieldAddress(RAX, Double::value_offset()));
   __ Bind(&double_op);
   __ sqrtsd(XMM0, XMM1);
   const Class& double_class =
       Class::Handle(Isolate::Current()->object_store()->double_class());
-  __ TryAllocate(double_class, &fall_through, Assembler::kFarJump,
+  __ TryAllocate(double_class, normal_ir_body, Assembler::kFarJump,
                  RAX,  // Result register.
                  R13);
   __ movsd(FieldAddress(RAX, Double::value_offset()), XMM0);
@@ -1484,13 +1508,14 @@
   __ SmiUntag(RAX);
   __ cvtsi2sdq(XMM1, RAX);
   __ jmp(&double_op);
-  __ Bind(&fall_through);
+  __ Bind(normal_ir_body);
 }
 
 //    var state = ((_A * (_state[kSTATE_LO])) + _state[kSTATE_HI]) & _MASK_64;
 //    _state[kSTATE_LO] = state & _MASK_32;
 //    _state[kSTATE_HI] = state >> 32;
-void Intrinsifier::Random_nextState(Assembler* assembler) {
+void Intrinsifier::Random_nextState(Assembler* assembler,
+                                    Label* normal_ir_body) {
   const Library& math_lib = Library::Handle(Library::MathLibrary());
   ASSERT(!math_lib.IsNull());
   const Class& random_class =
@@ -1524,7 +1549,7 @@
 }
 
 // Identity comparison.
-void Intrinsifier::ObjectEquals(Assembler* assembler) {
+void Intrinsifier::ObjectEquals(Assembler* assembler, Label* normal_ir_body) {
   Label is_true;
   const intptr_t kReceiverOffset = 2;
   const intptr_t kArgumentOffset = 1;
@@ -1574,14 +1599,15 @@
 }
 
 // Return type quickly for simple types (not parameterized and not signature).
-void Intrinsifier::ObjectRuntimeType(Assembler* assembler) {
-  Label fall_through, use_canonical_type, not_integer, not_double;
+void Intrinsifier::ObjectRuntimeType(Assembler* assembler,
+                                     Label* normal_ir_body) {
+  Label use_canonical_type, not_integer, not_double;
   __ movq(RAX, Address(RSP, +1 * kWordSize));
   __ LoadClassIdMayBeSmi(RCX, RAX);
 
   // RCX: untagged cid of instance (RAX).
   __ cmpq(RCX, Immediate(kClosureCid));
-  __ j(EQUAL, &fall_through);  // Instance is a closure.
+  __ j(EQUAL, normal_ir_body);  // Instance is a closure.
 
   __ cmpl(RCX, Immediate(kNumPredefinedCids));
   __ j(ABOVE, &use_canonical_type);
@@ -1621,24 +1647,25 @@
   __ LoadClassById(RDI, RCX);
   __ movzxw(RCX, FieldAddress(RDI, Class::num_type_arguments_offset()));
   __ cmpq(RCX, Immediate(0));
-  __ j(NOT_EQUAL, &fall_through, Assembler::kNearJump);
+  __ j(NOT_EQUAL, normal_ir_body, Assembler::kNearJump);
   __ movq(RAX, FieldAddress(RDI, Class::canonical_type_offset()));
   __ CompareObject(RAX, Object::null_object());
-  __ j(EQUAL, &fall_through, Assembler::kNearJump);  // Not yet set.
+  __ j(EQUAL, normal_ir_body, Assembler::kNearJump);  // Not yet set.
   __ ret();
 
-  __ Bind(&fall_through);
+  __ Bind(normal_ir_body);
 }
 
-void Intrinsifier::ObjectHaveSameRuntimeType(Assembler* assembler) {
-  Label fall_through, different_cids, equal, not_equal, not_integer;
+void Intrinsifier::ObjectHaveSameRuntimeType(Assembler* assembler,
+                                             Label* normal_ir_body) {
+  Label different_cids, equal, not_equal, not_integer;
 
   __ movq(RAX, Address(RSP, +1 * kWordSize));
   __ LoadClassIdMayBeSmi(RCX, RAX);
 
   // Check if left hand size is a closure. Closures are handled in the runtime.
   __ cmpq(RCX, Immediate(kClosureCid));
-  __ j(EQUAL, &fall_through);
+  __ j(EQUAL, normal_ir_body);
 
   __ movq(RAX, Address(RSP, +2 * kWordSize));
   __ LoadClassIdMayBeSmi(RDX, RAX);
@@ -1655,7 +1682,7 @@
   __ LoadClassById(RDI, RCX);
   __ movzxw(RCX, FieldAddress(RDI, Class::num_type_arguments_offset()));
   __ cmpq(RCX, Immediate(0));
-  __ j(NOT_EQUAL, &fall_through, Assembler::kNearJump);
+  __ j(NOT_EQUAL, normal_ir_body, Assembler::kNearJump);
 
   __ Bind(&equal);
   __ LoadObject(RAX, Bool::True());
@@ -1690,43 +1717,43 @@
   __ LoadObject(RAX, Bool::False());
   __ ret();
 
-  __ Bind(&fall_through);
+  __ Bind(normal_ir_body);
 }
 
-void Intrinsifier::String_getHashCode(Assembler* assembler) {
-  Label fall_through;
+void Intrinsifier::String_getHashCode(Assembler* assembler,
+                                      Label* normal_ir_body) {
   __ movq(RAX, Address(RSP, +1 * kWordSize));  // String object.
   __ movl(RAX, FieldAddress(RAX, String::hash_offset()));
   ASSERT(kSmiTag == 0);
   ASSERT(kSmiTagShift == 1);
   __ addq(RAX, RAX);  // Smi tag RAX, setting Z flag.
-  __ j(ZERO, &fall_through, Assembler::kNearJump);
+  __ j(ZERO, normal_ir_body, Assembler::kNearJump);
   __ ret();
-  __ Bind(&fall_through);
+  __ Bind(normal_ir_body);
   // Hash not yet computed.
 }
 
-void Intrinsifier::Type_getHashCode(Assembler* assembler) {
-  Label fall_through;
+void Intrinsifier::Type_getHashCode(Assembler* assembler,
+                                    Label* normal_ir_body) {
   __ movq(RAX, Address(RSP, +1 * kWordSize));  // Type object.
   __ movq(RAX, FieldAddress(RAX, Type::hash_offset()));
   ASSERT(kSmiTag == 0);
   ASSERT(kSmiTagShift == 1);
   __ testq(RAX, RAX);
-  __ j(ZERO, &fall_through, Assembler::kNearJump);
+  __ j(ZERO, normal_ir_body, Assembler::kNearJump);
   __ ret();
-  __ Bind(&fall_through);
+  __ Bind(normal_ir_body);
   // Hash not yet computed.
 }
 
-void Intrinsifier::Object_getHash(Assembler* assembler) {
+void Intrinsifier::Object_getHash(Assembler* assembler, Label* normal_ir_body) {
   __ movq(RAX, Address(RSP, +1 * kWordSize));  // Object.
   __ movl(RAX, FieldAddress(RAX, String::hash_offset()));
   __ SmiTag(RAX);
   __ ret();
 }
 
-void Intrinsifier::Object_setHash(Assembler* assembler) {
+void Intrinsifier::Object_setHash(Assembler* assembler, Label* normal_ir_body) {
   __ movq(RAX, Address(RSP, +2 * kWordSize));  // Object.
   __ movq(RDX, Address(RSP, +1 * kWordSize));  // Value.
   __ SmiUntag(RDX);
@@ -1799,17 +1826,18 @@
 // bool _substringMatches(int start, String other)
 // This intrinsic handles a OneByteString or TwoByteString receiver with a
 // OneByteString other.
-void Intrinsifier::StringBaseSubstringMatches(Assembler* assembler) {
-  Label fall_through, return_true, return_false, try_two_byte;
+void Intrinsifier::StringBaseSubstringMatches(Assembler* assembler,
+                                              Label* normal_ir_body) {
+  Label return_true, return_false, try_two_byte;
   __ movq(RAX, Address(RSP, +3 * kWordSize));  // receiver
   __ movq(RBX, Address(RSP, +2 * kWordSize));  // start
   __ movq(RCX, Address(RSP, +1 * kWordSize));  // other
 
   __ testq(RBX, Immediate(kSmiTagMask));
-  __ j(NOT_ZERO, &fall_through);  // 'start' is not Smi.
+  __ j(NOT_ZERO, normal_ir_body);  // 'start' is not Smi.
 
   __ CompareClassId(RCX, kOneByteStringCid);
-  __ j(NOT_EQUAL, &fall_through);
+  __ j(NOT_EQUAL, normal_ir_body);
 
   __ CompareClassId(RAX, kOneByteStringCid);
   __ j(NOT_EQUAL, &try_two_byte);
@@ -1820,7 +1848,7 @@
 
   __ Bind(&try_two_byte);
   __ CompareClassId(RAX, kTwoByteStringCid);
-  __ j(NOT_EQUAL, &fall_through);
+  __ j(NOT_EQUAL, normal_ir_body);
 
   GenerateSubstringMatchesSpecialization(assembler, kTwoByteStringCid,
                                          kOneByteStringCid, &return_true,
@@ -1834,25 +1862,26 @@
   __ LoadObject(RAX, Bool::False());
   __ ret();
 
-  __ Bind(&fall_through);
+  __ Bind(normal_ir_body);
 }
 
-void Intrinsifier::StringBaseCharAt(Assembler* assembler) {
-  Label fall_through, try_two_byte_string;
+void Intrinsifier::StringBaseCharAt(Assembler* assembler,
+                                    Label* normal_ir_body) {
+  Label try_two_byte_string;
   __ movq(RCX, Address(RSP, +1 * kWordSize));  // Index.
   __ movq(RAX, Address(RSP, +2 * kWordSize));  // String.
   __ testq(RCX, Immediate(kSmiTagMask));
-  __ j(NOT_ZERO, &fall_through);  // Non-smi index.
+  __ j(NOT_ZERO, normal_ir_body);  // Non-smi index.
   // Range check.
   __ cmpq(RCX, FieldAddress(RAX, String::length_offset()));
   // Runtime throws exception.
-  __ j(ABOVE_EQUAL, &fall_through);
+  __ j(ABOVE_EQUAL, normal_ir_body);
   __ CompareClassId(RAX, kOneByteStringCid);
   __ j(NOT_EQUAL, &try_two_byte_string, Assembler::kNearJump);
   __ SmiUntag(RCX);
   __ movzxb(RCX, FieldAddress(RAX, RCX, TIMES_1, OneByteString::data_offset()));
   __ cmpq(RCX, Immediate(Symbols::kNumberOfOneCharCodeSymbols));
-  __ j(GREATER_EQUAL, &fall_through);
+  __ j(GREATER_EQUAL, normal_ir_body);
   __ movq(RAX, Address(THR, Thread::predefined_symbols_address_offset()));
   __ movq(RAX, Address(RAX, RCX, TIMES_8,
                        Symbols::kNullCharCodeSymbolOffset * kWordSize));
@@ -1860,20 +1889,21 @@
 
   __ Bind(&try_two_byte_string);
   __ CompareClassId(RAX, kTwoByteStringCid);
-  __ j(NOT_EQUAL, &fall_through);
+  __ j(NOT_EQUAL, normal_ir_body);
   ASSERT(kSmiTagShift == 1);
   __ movzxw(RCX, FieldAddress(RAX, RCX, TIMES_1, OneByteString::data_offset()));
   __ cmpq(RCX, Immediate(Symbols::kNumberOfOneCharCodeSymbols));
-  __ j(GREATER_EQUAL, &fall_through);
+  __ j(GREATER_EQUAL, normal_ir_body);
   __ movq(RAX, Address(THR, Thread::predefined_symbols_address_offset()));
   __ movq(RAX, Address(RAX, RCX, TIMES_8,
                        Symbols::kNullCharCodeSymbolOffset * kWordSize));
   __ ret();
 
-  __ Bind(&fall_through);
+  __ Bind(normal_ir_body);
 }
 
-void Intrinsifier::StringBaseIsEmpty(Assembler* assembler) {
+void Intrinsifier::StringBaseIsEmpty(Assembler* assembler,
+                                     Label* normal_ir_body) {
   Label is_true;
   // Get length.
   __ movq(RAX, Address(RSP, +1 * kWordSize));  // String object.
@@ -1887,7 +1917,8 @@
   __ ret();
 }
 
-void Intrinsifier::OneByteString_getHashCode(Assembler* assembler) {
+void Intrinsifier::OneByteString_getHashCode(Assembler* assembler,
+                                             Label* normal_ir_body) {
   Label compute_hash;
   __ movq(RBX, Address(RSP, +1 * kWordSize));  // OneByteString object.
   __ movl(RAX, FieldAddress(RBX, String::hash_offset()));
@@ -2042,19 +2073,20 @@
 // Arg1: Start index as Smi.
 // Arg2: End index as Smi.
 // The indexes must be valid.
-void Intrinsifier::OneByteString_substringUnchecked(Assembler* assembler) {
+void Intrinsifier::OneByteString_substringUnchecked(Assembler* assembler,
+                                                    Label* normal_ir_body) {
   const intptr_t kStringOffset = 3 * kWordSize;
   const intptr_t kStartIndexOffset = 2 * kWordSize;
   const intptr_t kEndIndexOffset = 1 * kWordSize;
-  Label fall_through, ok;
+  Label ok;
   __ movq(RSI, Address(RSP, +kStartIndexOffset));
   __ movq(RDI, Address(RSP, +kEndIndexOffset));
   __ orq(RSI, RDI);
   __ testq(RSI, Immediate(kSmiTagMask));
-  __ j(NOT_ZERO, &fall_through);  // 'start', 'end' not Smi.
+  __ j(NOT_ZERO, normal_ir_body);  // 'start', 'end' not Smi.
 
   __ subq(RDI, Address(RSP, +kStartIndexOffset));
-  TryAllocateOnebyteString(assembler, &ok, &fall_through, RDI);
+  TryAllocateOnebyteString(assembler, &ok, normal_ir_body, RDI);
   __ Bind(&ok);
   // RAX: new string as tagged pointer.
   // Copy string.
@@ -2083,10 +2115,11 @@
   __ cmpq(RDX, RCX);
   __ j(LESS, &loop, Assembler::kNearJump);
   __ ret();
-  __ Bind(&fall_through);
+  __ Bind(normal_ir_body);
 }
 
-void Intrinsifier::OneByteStringSetAt(Assembler* assembler) {
+void Intrinsifier::OneByteStringSetAt(Assembler* assembler,
+                                      Label* normal_ir_body) {
   __ movq(RCX, Address(RSP, +1 * kWordSize));  // Value.
   __ movq(RBX, Address(RSP, +2 * kWordSize));  // Index.
   __ movq(RAX, Address(RSP, +3 * kWordSize));  // OneByteString.
@@ -2096,21 +2129,24 @@
   __ ret();
 }
 
-void Intrinsifier::OneByteString_allocate(Assembler* assembler) {
+void Intrinsifier::OneByteString_allocate(Assembler* assembler,
+                                          Label* normal_ir_body) {
   __ movq(RDI, Address(RSP, +1 * kWordSize));  // Length.v=
-  Label fall_through, ok;
-  TryAllocateOnebyteString(assembler, &ok, &fall_through, RDI);
+  Label ok;
+  TryAllocateOnebyteString(assembler, &ok, normal_ir_body, RDI);
   // RDI: Start address to copy from (untagged).
 
   __ Bind(&ok);
   __ ret();
 
-  __ Bind(&fall_through);
+  __ Bind(normal_ir_body);
 }
 
 // TODO(srdjan): Add combinations (one-byte/two-byte/external strings).
-static void StringEquality(Assembler* assembler, intptr_t string_cid) {
-  Label fall_through, is_true, is_false, loop;
+static void StringEquality(Assembler* assembler,
+                           Label* normal_ir_body,
+                           intptr_t string_cid) {
+  Label is_true, is_false, loop;
   __ movq(RAX, Address(RSP, +2 * kWordSize));  // This.
   __ movq(RCX, Address(RSP, +1 * kWordSize));  // Other.
 
@@ -2122,7 +2158,7 @@
   __ testq(RCX, Immediate(kSmiTagMask));
   __ j(ZERO, &is_false);  // Smi
   __ CompareClassId(RCX, string_cid);
-  __ j(NOT_EQUAL, &fall_through, Assembler::kNearJump);
+  __ j(NOT_EQUAL, normal_ir_body, Assembler::kNearJump);
 
   // Have same length?
   __ movq(RDI, FieldAddress(RAX, String::length_offset()));
@@ -2161,18 +2197,21 @@
   __ LoadObject(RAX, Bool::False());
   __ ret();
 
-  __ Bind(&fall_through);
+  __ Bind(normal_ir_body);
 }
 
-void Intrinsifier::OneByteString_equality(Assembler* assembler) {
-  StringEquality(assembler, kOneByteStringCid);
+void Intrinsifier::OneByteString_equality(Assembler* assembler,
+                                          Label* normal_ir_body) {
+  StringEquality(assembler, normal_ir_body, kOneByteStringCid);
 }
 
-void Intrinsifier::TwoByteString_equality(Assembler* assembler) {
-  StringEquality(assembler, kTwoByteStringCid);
+void Intrinsifier::TwoByteString_equality(Assembler* assembler,
+                                          Label* normal_ir_body) {
+  StringEquality(assembler, normal_ir_body, kTwoByteStringCid);
 }
 
 void Intrinsifier::IntrinsifyRegExpExecuteMatch(Assembler* assembler,
+                                                Label* normal_ir_body,
                                                 bool sticky) {
   if (FLAG_interpret_irregexp) return;
 
@@ -2206,7 +2245,8 @@
 }
 
 // On stack: user tag (+1), return-address (+0).
-void Intrinsifier::UserTag_makeCurrent(Assembler* assembler) {
+void Intrinsifier::UserTag_makeCurrent(Assembler* assembler,
+                                       Label* normal_ir_body) {
   // RBX: Isolate.
   __ LoadIsolate(RBX);
   // RAX: Current user tag.
@@ -2222,19 +2262,22 @@
   __ ret();
 }
 
-void Intrinsifier::UserTag_defaultTag(Assembler* assembler) {
+void Intrinsifier::UserTag_defaultTag(Assembler* assembler,
+                                      Label* normal_ir_body) {
   __ LoadIsolate(RAX);
   __ movq(RAX, Address(RAX, Isolate::default_tag_offset()));
   __ ret();
 }
 
-void Intrinsifier::Profiler_getCurrentTag(Assembler* assembler) {
+void Intrinsifier::Profiler_getCurrentTag(Assembler* assembler,
+                                          Label* normal_ir_body) {
   __ LoadIsolate(RAX);
   __ movq(RAX, Address(RAX, Isolate::current_tag_offset()));
   __ ret();
 }
 
-void Intrinsifier::Timeline_isDartStreamEnabled(Assembler* assembler) {
+void Intrinsifier::Timeline_isDartStreamEnabled(Assembler* assembler,
+                                                Label* normal_ir_body) {
   if (!FLAG_support_timeline) {
     __ LoadObject(RAX, Bool::False());
     __ ret();
@@ -2256,13 +2299,15 @@
   __ ret();
 }
 
-void Intrinsifier::ClearAsyncThreadStackTrace(Assembler* assembler) {
+void Intrinsifier::ClearAsyncThreadStackTrace(Assembler* assembler,
+                                              Label* normal_ir_body) {
   __ LoadObject(RAX, Object::null_object());
   __ movq(Address(THR, Thread::async_stack_trace_offset()), RAX);
   __ ret();
 }
 
-void Intrinsifier::SetAsyncThreadStackTrace(Assembler* assembler) {
+void Intrinsifier::SetAsyncThreadStackTrace(Assembler* assembler,
+                                            Label* normal_ir_body) {
   __ movq(Address(THR, Thread::async_stack_trace_offset()), RAX);
   __ LoadObject(RAX, Object::null_object());
   __ ret();
diff --git a/runtime/vm/compiler/jit/compiler.cc b/runtime/vm/compiler/jit/compiler.cc
index 371fafa..50ff623 100644
--- a/runtime/vm/compiler/jit/compiler.cc
+++ b/runtime/vm/compiler/jit/compiler.cc
@@ -89,6 +89,7 @@
             false,
             "Enable compiler verification assertions");
 
+DECLARE_FLAG(bool, enable_interpreter);
 DECLARE_FLAG(bool, huge_method_cutoff_in_code_size);
 DECLARE_FLAG(bool, trace_failed_optimization_attempts);
 DECLARE_FLAG(bool, unbox_numeric_fields);
@@ -139,6 +140,7 @@
 bool UseKernelFrontEndFor(ParsedFunction* parsed_function) {
   const Function& function = parsed_function->function();
   return (function.kernel_offset() > 0) ||
+         (FLAG_use_bytecode_compiler && function.HasBytecode()) ||
          (function.kind() == RawFunction::kNoSuchMethodDispatcher) ||
          (function.kind() == RawFunction::kInvokeFieldDispatcher);
 }
@@ -153,7 +155,7 @@
 FlowGraph* DartCompilationPipeline::BuildFlowGraph(
     Zone* zone,
     ParsedFunction* parsed_function,
-    const ZoneGrowableArray<const ICData*>& ic_data_array,
+    ZoneGrowableArray<const ICData*>* ic_data_array,
     intptr_t osr_id,
     bool optimized) {
   if (UseKernelFrontEndFor(parsed_function)) {
@@ -162,14 +164,11 @@
                                      /* not inlining */ NULL, optimized,
                                      osr_id);
     FlowGraph* graph = builder.BuildGraph();
-#if defined(DART_USE_INTERPRETER)
-    ASSERT((graph != NULL) || parsed_function->function().HasBytecode());
-#else
-    ASSERT(graph != NULL);
-#endif
+    ASSERT((graph != NULL) || (FLAG_enable_interpreter &&
+                               parsed_function->function().HasBytecode()));
     return graph;
   }
-  FlowGraphBuilder builder(*parsed_function, ic_data_array,
+  FlowGraphBuilder builder(*parsed_function, *ic_data_array,
                            /* not building var desc */ NULL,
                            /* not inlining */ NULL, osr_id);
 
@@ -209,13 +208,13 @@
 FlowGraph* IrregexpCompilationPipeline::BuildFlowGraph(
     Zone* zone,
     ParsedFunction* parsed_function,
-    const ZoneGrowableArray<const ICData*>& ic_data_array,
+    ZoneGrowableArray<const ICData*>* ic_data_array,
     intptr_t osr_id,
     bool optimized) {
   // Compile to the dart IR.
   RegExpEngine::CompilationResult result =
       RegExpEngine::CompileIR(parsed_function->regexp_compile_data(),
-                              parsed_function, ic_data_array, osr_id);
+                              parsed_function, *ic_data_array, osr_id);
   backtrack_goto_ = result.backtrack_goto;
 
   // Allocate variables now that we know the number of locals.
@@ -260,14 +259,13 @@
     }
     Exceptions::PropagateError(Error::Cast(result));
   }
-#if defined(DART_USE_INTERPRETER)
   // TODO(regis): Revisit.
-  if (!function.HasCode() && function.HasBytecode()) {
+  if (FLAG_enable_interpreter && !function.HasCode() &&
+      function.HasBytecode()) {
     // Function was not actually compiled, but its bytecode was loaded.
     // Verify that InterpretCall stub code was installed.
     ASSERT(function.CurrentCode() == StubCode::InterpretCall_entry()->code());
   }
-#endif
 }
 
 bool Compiler::CanOptimizeFunction(Thread* thread, const Function& function) {
@@ -633,7 +631,7 @@
   graph_compiler->FinalizeStackMaps(code);
   graph_compiler->FinalizeVarDescriptors(code);
   graph_compiler->FinalizeExceptionHandlers(code);
-  graph_compiler->FinalizeCatchEntryStateMap(code);
+  graph_compiler->FinalizeCatchEntryMovesMap(code);
   graph_compiler->FinalizeStaticCallTargetsTable(code);
   graph_compiler->FinalizeCodeSourceMap(code);
 
@@ -829,15 +827,14 @@
         NOT_IN_PRODUCT(TimelineDurationScope tds(thread(), compiler_timeline,
                                                  "BuildFlowGraph"));
         flow_graph = pipeline->BuildFlowGraph(
-            zone, parsed_function(), *ic_data_array, osr_id(), optimized());
+            zone, parsed_function(), ic_data_array, osr_id(), optimized());
       }
 
-#if defined(DART_USE_INTERPRETER)
       // TODO(regis): Revisit.
-      if (flow_graph == NULL && function.HasBytecode()) {
+      if (FLAG_enable_interpreter && (flow_graph == NULL) &&
+          function.HasBytecode()) {
         return Code::null();
       }
-#endif
 
       const bool print_flow_graph =
           (FLAG_print_flow_graph ||
@@ -1022,12 +1019,10 @@
 
     const Code& result = Code::Handle(helper.Compile(pipeline));
 
-#if defined(DART_USE_INTERPRETER)
     // TODO(regis): Revisit.
-    if (result.IsNull() && function.HasBytecode()) {
+    if (FLAG_enable_interpreter && result.IsNull() && function.HasBytecode()) {
       return Object::null();
     }
-#endif
 
     if (!result.IsNull()) {
       if (!optimized) {
@@ -1259,6 +1254,10 @@
 
 RawError* Compiler::EnsureUnoptimizedCode(Thread* thread,
                                           const Function& function) {
+  if (FLAG_enable_interpreter && function.HasBytecode()) {
+    // TODO(regis): This may not be sufficient when deoptimizing. Revisit then.
+    return Error::null();
+  }
   if (function.unoptimized_code() != Object::null()) {
     return Error::null();
   }
@@ -1274,6 +1273,9 @@
   if (result.IsError()) {
     return Error::Cast(result).raw();
   }
+  if (FLAG_enable_interpreter && function.HasBytecode()) {
+    return Error::null();
+  }
   // Since CompileFunctionHelper replaces the current code, re-attach the
   // the original code if the function was already compiled.
   if (!original_code.IsNull() && result.raw() == function.CurrentCode() &&
@@ -1345,6 +1347,12 @@
 void Compiler::ComputeLocalVarDescriptors(const Code& code) {
   ASSERT(!code.is_optimized());
   const Function& function = Function::Handle(code.function());
+  if (FLAG_enable_interpreter && function.Bytecode() == code.raw()) {
+    // TODO(regis): Kernel bytecode does not yet provide var descriptors.
+    ASSERT(code.var_descriptors() == Object::null());
+    code.set_var_descriptors(Object::empty_var_descriptors());
+    return;
+  }
   ParsedFunction* parsed_function = new ParsedFunction(
       Thread::Current(), Function::ZoneHandle(function.raw()));
   ASSERT(code.var_descriptors() == Object::null());
@@ -1370,7 +1378,7 @@
     } else {
       parsed_function->EnsureKernelScopes();
       kernel::FlowGraphBuilder builder(
-          parsed_function, *ic_data_array, context_level_array,
+          parsed_function, ic_data_array, context_level_array,
           /* not inlining */ NULL, false, Compiler::kNoOSRDeoptId);
       builder.BuildGraph();
     }
@@ -1403,11 +1411,9 @@
     func ^= functions.At(i);
     ASSERT(!func.IsNull());
     if (!func.HasCode() &&
-#if defined(DART_USE_INTERPRETER)
         // TODO(regis): Revisit.
         // Do not compile function if its bytecode is already loaded.
-        !func.HasBytecode() &&
-#endif
+        (!FLAG_enable_interpreter || !func.HasBytecode()) &&
         !func.is_abstract() && !func.IsRedirectingFactory()) {
       if ((cls.is_mixin_app_alias() || cls.IsMixinApplication()) &&
           func.HasOptionalParameters()) {
@@ -1418,13 +1424,10 @@
       if (result.IsError()) {
         return Error::Cast(result).raw();
       }
-#if defined(DART_USE_INTERPRETER)
       // TODO(regis): Revisit.
       // The compiler may load bytecode and return Code::null().
-      ASSERT(!result.IsNull() || func.HasBytecode());
-#else
-      ASSERT(!result.IsNull());
-#endif
+      ASSERT(!result.IsNull() ||
+             (FLAG_enable_interpreter && func.HasBytecode()));
     }
   }
   return Error::null();
@@ -1511,15 +1514,13 @@
       CompileParsedFunctionHelper helper(parsed_function, false, kNoOSRDeoptId);
       const Code& code = Code::Handle(helper.Compile(&pipeline));
       const Function& initializer = parsed_function->function();
+
       if (!code.IsNull()) {
         code.set_var_descriptors(Object::empty_var_descriptors());
-#if defined(DART_USE_INTERPRETER)
-      }
-      // In case the initializer has bytecode, the compilation step above only
-      // loaded the bytecode without generating code.
-      if (!code.IsNull() || initializer.HasBytecode()) {
-#endif
-        // Invoke the function to evaluate the expression.
+        return DartEntry::InvokeFunction(initializer, Object::empty_array());
+      } else if (FLAG_enable_interpreter && initializer.HasBytecode()) {
+        // In case the initializer has bytecode, the compilation step above only
+        // loaded the bytecode without generating code.
         return DartEntry::InvokeFunction(initializer, Object::empty_array());
       }
     }
diff --git a/runtime/vm/compiler/jit/compiler.h b/runtime/vm/compiler/jit/compiler.h
index 68ef8d1..1636109 100644
--- a/runtime/vm/compiler/jit/compiler.h
+++ b/runtime/vm/compiler/jit/compiler.h
@@ -38,7 +38,7 @@
   virtual FlowGraph* BuildFlowGraph(
       Zone* zone,
       ParsedFunction* parsed_function,
-      const ZoneGrowableArray<const ICData*>& ic_data_array,
+      ZoneGrowableArray<const ICData*>* ic_data_array,
       intptr_t osr_id,
       bool optimized) = 0;
   virtual void FinalizeCompilation(FlowGraph* flow_graph) = 0;
@@ -47,32 +47,30 @@
 
 class DartCompilationPipeline : public CompilationPipeline {
  public:
-  virtual void ParseFunction(ParsedFunction* parsed_function);
+  void ParseFunction(ParsedFunction* parsed_function) override;
 
-  virtual FlowGraph* BuildFlowGraph(
-      Zone* zone,
-      ParsedFunction* parsed_function,
-      const ZoneGrowableArray<const ICData*>& ic_data_array,
-      intptr_t osr_id,
-      bool optimized);
+  FlowGraph* BuildFlowGraph(Zone* zone,
+                            ParsedFunction* parsed_function,
+                            ZoneGrowableArray<const ICData*>* ic_data_array,
+                            intptr_t osr_id,
+                            bool optimized) override;
 
-  virtual void FinalizeCompilation(FlowGraph* flow_graph);
+  void FinalizeCompilation(FlowGraph* flow_graph) override;
 };
 
 class IrregexpCompilationPipeline : public CompilationPipeline {
  public:
   IrregexpCompilationPipeline() : backtrack_goto_(NULL) {}
 
-  virtual void ParseFunction(ParsedFunction* parsed_function);
+  void ParseFunction(ParsedFunction* parsed_function) override;
 
-  virtual FlowGraph* BuildFlowGraph(
-      Zone* zone,
-      ParsedFunction* parsed_function,
-      const ZoneGrowableArray<const ICData*>& ic_data_array,
-      intptr_t osr_id,
-      bool optimized);
+  FlowGraph* BuildFlowGraph(Zone* zone,
+                            ParsedFunction* parsed_function,
+                            ZoneGrowableArray<const ICData*>* ic_data_array,
+                            intptr_t osr_id,
+                            bool optimized) override;
 
-  virtual void FinalizeCompilation(FlowGraph* flow_graph);
+  void FinalizeCompilation(FlowGraph* flow_graph) override;
 
  private:
   IndirectGotoInstr* backtrack_goto_;
@@ -108,6 +106,8 @@
   static RawError* ParseFunction(Thread* thread, const Function& function);
 
   // Generates unoptimized code if not present, current code is unchanged.
+  // Bytecode is considered unoptimized code.
+  // TODO(regis): Revisit when deoptimizing mixed bytecode and jitted code.
   static RawError* EnsureUnoptimizedCode(Thread* thread,
                                          const Function& function);
 
diff --git a/runtime/vm/compiler/method_recognizer.cc b/runtime/vm/compiler/method_recognizer.cc
index 70def2a..85f86c8 100644
--- a/runtime/vm/compiler/method_recognizer.cc
+++ b/runtime/vm/compiler/method_recognizer.cc
@@ -35,10 +35,79 @@
 }
 
 intptr_t MethodRecognizer::ResultCid(const Function& function) {
+  // Use the 'vm:exact-result-type' annotation if available. This can only be
+  // used within the core library, see 'result_type_pragma.md', detail 1.2 for
+  // explanation.
+  Class& cls = Thread::Current()->ClassHandle();
+  Library& lib = Thread::Current()->LibraryHandle();
+  cls = function.Owner();
+  lib = cls.library();
+  const bool can_use_pragma =
+      function.kernel_offset() > 0 && lib.IsAnyCoreLibrary();
+  cls = Class::null();
+  if (can_use_pragma) {
+    Isolate* I = Isolate::Current();
+    auto& option = Object::Handle();
+    if (function.FindPragma(I, Symbols::vm_exact_result_type(), &option)) {
+      if (option.IsType()) {
+        return Type::Cast(option).type_class_id();
+      } else if (option.IsString()) {
+        auto& str = String::Cast(option);
+        // 'str' should match the pattern '([^#]+)#([^#\?]+)' where group 1
+        // is the library URI and group 2 is the class name.
+        bool parse_failure = false;
+        intptr_t library_end = -1;
+        for (intptr_t i = 0; i < str.Length(); ++i) {
+          if (str.CharAt(i) == '#') {
+            if (library_end != -1) {
+              parse_failure = true;
+              break;
+            } else {
+              library_end = i;
+            }
+          }
+        }
+        if (!parse_failure && library_end > 0) {
+          auto& libraryUri = String::Handle(
+              String::SubString(str, 0, library_end, Heap::kOld));
+          auto& className = String::Handle(
+              String::SubString(str, library_end + 1,
+                                str.Length() - library_end - 1, Heap::kOld));
+
+          Library& lib = Library::Handle(
+              Library::LookupLibrary(Thread::Current(), libraryUri));
+          if (!lib.IsNull()) {
+            Class& klass =
+                Class::Handle(lib.LookupClassAllowPrivate(className));
+            if (!klass.IsNull()) {
+              return klass.id();
+            }
+          }
+        }
+      }
+    }
+  }
+
+  // No result-type annotation can be used, so fall back on the table of
+  // recognized methods.
   switch (function.recognized_kind()) {
 #define DEFINE_CASE(cname, fname, ename, result_type, fingerprint)             \
-  case k##ename:                                                               \
-    return k##result_type##Cid;
+  case k##ename: {                                                             \
+    const intptr_t cid = k##result_type##Cid;                                  \
+    if (FLAG_strong && cid != kDynamicCid) {                                   \
+      String& err = String::Handle();                                          \
+      err = function.QualifiedScrubbedName();                                  \
+      err = String::Concat(                                                    \
+          err,                                                                 \
+          String::Handle(String::New(" (MethodRecognizer::k" #ename            \
+                                     ") should be using pragma annotation"     \
+                                     " rather than method recognizer.",        \
+                                     Heap::kOld)),                             \
+          Heap::kOld);                                                         \
+      FATAL(err.ToCString());                                                  \
+    }                                                                          \
+    return cid;                                                                \
+  }
     RECOGNIZED_LIST(DEFINE_CASE)
 #undef DEFINE_CASE
     default:
diff --git a/runtime/vm/compiler/result_type_pragma.md b/runtime/vm/compiler/result_type_pragma.md
new file mode 100644
index 0000000..debb523
--- /dev/null
+++ b/runtime/vm/compiler/result_type_pragma.md
@@ -0,0 +1,33 @@
+# Result type @pragma annotations
+
+To facilitate type-flow analysis and other optimizations, Dart methods may use the pragma `vm:exact-result-type` to declare an exact return type different than the return type in the signature of the method. There are three limitations on this pragma:
+
+0. The Dart object returned by the method at runtime must have exactly the type specified in the annotation (not a subtype).
+
+1. The exact return type declared in the pragma must be a subtype of the return type declared in the method signature.
+   Note that this restriction is not enforced automatically by the compiler.
+
+2. `vm:exact-result-type` may only be attached to methods in the core library.
+   This pragma can introduce unsafe behavior since it allows the compiler to make stronger assumptions during optimization than what the sound strong-mode type system allows, so it is only allowed in the core library where the Dart VM team can ensure that it is not misused.
+
+If limitations 0 or 1 are violated, undefined behavior may result.
+Note that since `null` is an instance of the `Null` type, which is a subtype of any other, exactness of the annotated result type implies that the result must be non-null.
+
+## Syntax
+
+### Reference to type via type literal
+
+```dart
+class A {}
+class B extends A {}
+
+@pragma("vm:exact-result-type", B)
+A foo() native "foo_impl";
+```
+
+### Reference to type via path
+
+```dart
+@pragma("vm:exact-result-type", "dart:core#_Smi");
+int foo() native "foo_impl";
+```
diff --git a/runtime/vm/constants_arm.h b/runtime/vm/constants_arm.h
index c9973c3..67a2739 100644
--- a/runtime/vm/constants_arm.h
+++ b/runtime/vm/constants_arm.h
@@ -306,11 +306,12 @@
 const int kAbiPreservedFpuRegCount = 4;
 
 const RegList kReservedCpuRegisters = (1 << SPREG) | (1 << FPREG) | (1 << TMP) |
-                                      (1 << PP) | (1 << THR) | (1 << PC);
+                                      (1 << PP) | (1 << THR) | (1 << LR) |
+                                      (1 << PC);
 // CPU registers available to Dart allocator.
 constexpr RegList kDartAvailableCpuRegs =
     kAllCpuRegistersList & ~kReservedCpuRegisters;
-constexpr int kNumberOfDartAvailableCpuRegs = kNumberOfCpuRegisters - 6;
+constexpr int kNumberOfDartAvailableCpuRegs = kNumberOfCpuRegisters - 7;
 const intptr_t kStoreBufferWrapperSize = 24;
 // Registers available to Dart that are not preserved by runtime calls.
 const RegList kDartVolatileCpuRegs =
diff --git a/runtime/vm/constants_arm64.h b/runtime/vm/constants_arm64.h
index 64b09b6..7ae393b 100644
--- a/runtime/vm/constants_arm64.h
+++ b/runtime/vm/constants_arm64.h
@@ -38,7 +38,7 @@
   R25 = 25,
   R26 = 26,  // THR
   R27 = 27,  // PP
-  R28 = 28,
+  R28 = 28,  // BARRIER_MASK
   R29 = 29,  // FP
   R30 = 30,  // LR
   R31 = 31,  // ZR, CSP
@@ -116,6 +116,7 @@
 const Register THR = R26;           // Caches current thread in generated code.
 const Register CALLEE_SAVED_TEMP = R19;
 const Register CALLEE_SAVED_TEMP2 = R20;
+const Register BARRIER_MASK = R28;
 
 // Exception object is passed in this register to the catch handlers when an
 // exception is thrown.
@@ -149,11 +150,11 @@
 const VRegister kAbiLastPreservedFpuReg = V15;
 const int kAbiPreservedFpuRegCount = 8;
 
-const intptr_t kReservedCpuRegisters = (1 << SPREG) |  // Dart SP
-                                       (1 << FPREG) | (1 << TMP) | (1 << TMP2) |
-                                       (1 << PP) | (1 << THR) | (1 << LR) |
-                                       (1 << R31) |  // C++ SP
-                                       (1 << R18);   // iOS platform register.
+const intptr_t kReservedCpuRegisters =
+    (1 << SPREG) |  // Dart SP
+    (1 << FPREG) | (1 << TMP) | (1 << TMP2) | (1 << PP) | (1 << THR) |
+    (1 << LR) | (1 << BARRIER_MASK) | (1 << R31) |  // C++ SP
+    (1 << R18);                                     // iOS platform register.
 // TODO(rmacnak): Only reserve on Mac & iOS.
 // CPU registers available to Dart allocator.
 const RegList kDartAvailableCpuRegs =
diff --git a/runtime/vm/constants_kbc.h b/runtime/vm/constants_kbc.h
index a7b8922..2a5d9e5 100644
--- a/runtime/vm/constants_kbc.h
+++ b/runtime/vm/constants_kbc.h
@@ -154,6 +154,22 @@
 //    Load value at index D from constant pool into FP[rA] or push it onto the
 //    stack.
 //
+//  - PushNull
+//
+//    Push `null` onto the stack.
+//
+//  - PushTrue
+//
+//    Push `true` onto the stack.
+//
+//  - PushFalse
+//
+//    Push `false` onto the stack.
+//
+//  - PushInt rX
+//
+//    Push int rX onto the stack.
+//
 //  - StoreLocal rX; PopLocal rX
 //
 //    Store top of the stack into FP[rX] and pop it if needed.
@@ -588,7 +604,7 @@
 //    If B is not 0 then EntryOptional bytecode is followed by B LoadConstant
 //    bytecodes specifying default values for optional arguments.
 //
-//    If C is not 0 then EntryOptional is followed by 2 * B LoadConstant
+//    If C is not 0 then EntryOptional is followed by 2 * C LoadConstant
 //    bytecodes.
 //    Bytecode at 2 * i specifies name of the i-th named argument and at
 //    2 * i + 1 default value. rA part of the LoadConstant bytecode specifies
@@ -597,7 +613,8 @@
 //    prologues are implemented on other architectures.
 //
 //    Note: Unlike Entry bytecode EntryOptional does not setup the frame for
-//    local variables this is done by a separate bytecode Frame.
+//    local variables this is done by a separate bytecode Frame, which should
+//    follow EntryOptional and its LoadConstant instructions.
 //
 //  - EntryOptimized rD
 //
@@ -831,6 +848,10 @@
   V(LoadClassId,                         A_D, reg, reg, ___)                   \
   V(LoadClassIdTOS,                        0, ___, ___, ___)                   \
   V(PushConstant,                          D, lit, ___, ___)                   \
+  V(PushNull,                              0, ___, ___, ___)                   \
+  V(PushTrue,                              0, ___, ___, ___)                   \
+  V(PushFalse,                             0, ___, ___, ___)                   \
+  V(PushInt,                               X, num, ___, ___)                   \
   V(StoreLocal,                            X, xeg, ___, ___)                   \
   V(PopLocal,                              X, xeg, ___, ___)                   \
   V(IndirectStaticCall,                  A_D, num, num, ___)                   \
@@ -1037,6 +1058,12 @@
     return names[DecodeOpcode(instr)];
   }
 
+  enum SpecialIndex {
+    kExceptionSpecialIndex,
+    kStackTraceSpecialIndex,
+    kSpecialIndexCount
+  };
+
   static const intptr_t kOpShift = 0;
   static const intptr_t kAShift = 8;
   static const intptr_t kAMask = 0xFF;
@@ -1048,6 +1075,7 @@
   static const intptr_t kDMask = 0xFFFF;
   static const intptr_t kYShift = 24;
   static const intptr_t kYMask = 0xFF;
+  static const intptr_t kTShift = 8;
 
   static KBCInstr Encode(Opcode op, uintptr_t a, uintptr_t b, uintptr_t c) {
     ASSERT((a & kAMask) == a);
@@ -1083,10 +1111,22 @@
     return (bc >> kBShift) & kBMask;
   }
 
+  DART_FORCE_INLINE static uint8_t DecodeC(KBCInstr bc) {
+    return (bc >> kCShift) & kCMask;
+  }
+
   DART_FORCE_INLINE static uint16_t DecodeD(KBCInstr bc) {
     return (bc >> kDShift) & kDMask;
   }
 
+  DART_FORCE_INLINE static int16_t DecodeX(KBCInstr bc) {
+    return static_cast<int16_t>((bc >> kDShift) & kDMask);
+  }
+
+  DART_FORCE_INLINE static int32_t DecodeT(KBCInstr bc) {
+    return static_cast<int32_t>(bc) >> kTShift;
+  }
+
   DART_FORCE_INLINE static Opcode DecodeOpcode(KBCInstr bc) {
     return static_cast<Opcode>(bc & 0xFF);
   }
diff --git a/runtime/vm/dart.cc b/runtime/vm/dart.cc
index a133085..18bb9b2 100644
--- a/runtime/vm/dart.cc
+++ b/runtime/vm/dart.cc
@@ -92,7 +92,7 @@
   // These offsets are embedded in precompiled instructions. We need simarm
   // (compiler) and arm (runtime) to agree.
   CHECK_OFFSET(Thread::stack_limit_offset(), 4);
-  CHECK_OFFSET(Thread::object_null_offset(), 56);
+  CHECK_OFFSET(Thread::object_null_offset(), 64);
   CHECK_OFFSET(SingleTargetCache::upper_limit_offset(), 14);
   CHECK_OFFSET(Isolate::object_store_offset(), 28);
   NOT_IN_PRODUCT(CHECK_OFFSET(sizeof(ClassHeapStats), 168));
@@ -101,7 +101,7 @@
   // These offsets are embedded in precompiled instructions. We need simarm64
   // (compiler) and arm64 (runtime) to agree.
   CHECK_OFFSET(Thread::stack_limit_offset(), 8);
-  CHECK_OFFSET(Thread::object_null_offset(), 104);
+  CHECK_OFFSET(Thread::object_null_offset(), 112);
   CHECK_OFFSET(SingleTargetCache::upper_limit_offset(), 26);
   CHECK_OFFSET(Isolate::object_store_offset(), 56);
   NOT_IN_PRODUCT(CHECK_OFFSET(sizeof(ClassHeapStats), 288));
@@ -135,6 +135,30 @@
     FLAG_verify_gc_contains = true;
   }
 #endif
+
+  if (FLAG_use_bytecode_compiler) {
+    // Interpreter is not able to trigger compilation yet.
+    // TODO(alexmarkov): Revise
+    FLAG_enable_interpreter = false;
+  }
+
+  if (FLAG_enable_interpreter) {
+#if defined(USING_SIMULATOR) || defined(TARGET_ARCH_DBC)
+    return strdup(
+        "--enable-interpreter is not supported when targeting "
+        "a sim* architecture.");
+#endif  // defined(USING_SIMULATOR) || defined(TARGET_ARCH_DBC)
+
+#if defined(TARGET_OS_WINDOWS)
+    // TODO(34393): The interpreter currently relies on computed gotos, which
+    // aren't supported on Windows.
+    return strdup("--enable-interpreter is not supported on Windows.");
+#endif  // defined(TARGET_OS_WINDOWS)
+
+    FLAG_use_field_guards = false;
+    FLAG_optimization_counter_threshold = -1;
+  }
+
   FrameLayout::InitOnce();
 
   set_thread_exit_callback(thread_exit);
@@ -676,7 +700,7 @@
   // isolate is always initialized from a vm_snapshot generated in non strong
   // mode.
   if (!is_vm_isolate) {
-    ADD_FLAG(strong, strong, FLAG_strong);
+    buffer.AddString(FLAG_strong ? " strong" : " no-strong");
   }
 
   if (Snapshot::IncludesCode(kind)) {
@@ -688,9 +712,10 @@
     ADD_FLAG(error_on_bad_override, enable_error_on_bad_override,
              FLAG_error_on_bad_override);
     // sync-async and reify_generic_functions also affect deopt_ids.
-    ADD_FLAG(sync_async, sync_async, FLAG_sync_async);
-    ADD_FLAG(reify_generic_functions, reify_generic_functions,
-             FLAG_reify_generic_functions);
+    buffer.AddString(FLAG_sync_async ? " sync_async" : " no-sync_async");
+    buffer.AddString(FLAG_reify_generic_functions
+                         ? " reify_generic_functions"
+                         : " no-reify_generic_functions");
     if (kind == Snapshot::kFullJIT) {
       ADD_FLAG(use_field_guards, use_field_guards, FLAG_use_field_guards);
       ADD_FLAG(use_osr, use_osr, FLAG_use_osr);
@@ -716,10 +741,6 @@
     buffer.AddString(" x64-sysv");
 #endif
 
-#if defined(DART_USE_INTERPRETER)
-    buffer.AddString(" kbc");
-#endif
-
 #elif defined(TARGET_ARCH_DBC)
 #if defined(ARCH_IS_32_BIT)
     buffer.AddString(" dbc32");
@@ -766,6 +787,9 @@
 void Dart::ShutdownIsolate() {
   Isolate* isolate = Isolate::Current();
   isolate->Shutdown();
+  if (KernelIsolate::IsKernelIsolate(isolate)) {
+    KernelIsolate::SetKernelIsolate(NULL);
+  }
   delete isolate;
 }
 
diff --git a/runtime/vm/dart_api_impl.cc b/runtime/vm/dart_api_impl.cc
index 5cf89d7..717daf3 100644
--- a/runtime/vm/dart_api_impl.cc
+++ b/runtime/vm/dart_api_impl.cc
@@ -1487,7 +1487,7 @@
   Isolate* I = T->isolate();
   CHECK_NULL(script_snapshot_buffer);
   CHECK_NULL(script_snapshot_size);
-  if (I->strong()) {
+  if (I->use_dart_frontend()) {
     return Api::NewError("Script snapshots are not supported in Dart 2");
   }
   // Finalize all classes if needed.
@@ -5078,7 +5078,7 @@
   if (buffer == NULL) {
     RETURN_NULL_ERROR(buffer);
   }
-  if (I->strong()) {
+  if (I->use_dart_frontend()) {
     return Api::NewError("Script snapshots are not supported in Dart 2");
   }
   NoHeapGrowthControlScope no_growth_control;
diff --git a/runtime/vm/dart_entry.cc b/runtime/vm/dart_entry.cc
index 8fca526..a49749d 100644
--- a/runtime/vm/dart_entry.cc
+++ b/runtime/vm/dart_entry.cc
@@ -19,6 +19,8 @@
 
 namespace dart {
 
+DECLARE_FLAG(bool, enable_interpreter);
+
 // A cache of VM heap allocated arguments descriptors.
 RawArray* ArgumentsDescriptor::cached_args_descriptors_[kCachedDescriptorCount];
 
@@ -114,7 +116,7 @@
   // and never start the VM service isolate. So we should never end up invoking
   // any dart code in the Dart 2.0 AOT compiler.
 #if !defined(DART_PRECOMPILED_RUNTIME)
-  if (Isolate::Current()->strong() && FLAG_precompiled_mode) {
+  if (FLAG_strong && FLAG_precompiled_mode) {
     UNREACHABLE();
   }
 #endif  // !defined(DART_PRECOMPILED_RUNTIME)
@@ -126,17 +128,24 @@
   Zone* zone = thread->zone();
   ASSERT(thread->IsMutatorThread());
   ScopedIsolateStackLimits stack_limit(thread, current_sp);
+#if !defined(DART_PRECOMPILED_RUNTIME)
   if (!function.HasCode()) {
-#if defined(DART_USE_INTERPRETER)
-    // The function is not compiled yet. Interpret it if it has bytecode.
-    // The bytecode is loaded as part as an aborted compilation step.
-    if (!function.HasBytecode()) {
+    // There's no native code. If we're not using the interpreter, then we
+    // compile to native code. If we are using the interpreter, but there's no
+    // native code and no bytecode, then we invoke the compiler to extract the
+    // bytecode.
+    if (!FLAG_enable_interpreter || !function.HasBytecode()) {
       const Object& result =
           Object::Handle(zone, Compiler::CompileFunction(thread, function));
       if (result.IsError()) {
         return Error::Cast(result).raw();
       }
     }
+
+    // At this point we should have either native code or bytecode.
+    ASSERT(function.HasCode() || function.HasBytecode());
+
+    // If we have bytecode but no native code then invoke the interpreter.
     if (!function.HasCode() && function.HasBytecode()) {
       ASSERT(thread->no_callback_scope_depth() == 0);
       SuspendLongJumpScope suspend_long_jump_scope(thread);
@@ -144,14 +153,9 @@
       return Interpreter::Current()->Call(function, arguments_descriptor,
                                           arguments, thread);
     }
-#else
-    const Object& result =
-        Object::Handle(zone, Compiler::CompileFunction(thread, function));
-    if (result.IsError()) {
-      return Error::Cast(result).raw();
-    }
-#endif
   }
+#endif  // !defined(DART_PRECOMPILED_RUNTIME)
+
 // Now Call the invoke stub which will invoke the dart function.
 #if !defined(TARGET_ARCH_DBC)
   invokestub entrypoint = reinterpret_cast<invokestub>(
@@ -335,6 +339,26 @@
   return NameAt(index) == other.raw();
 }
 
+RawArray* ArgumentsDescriptor::GetArgumentNames() const {
+  const intptr_t num_named_args = NamedCount();
+  if (num_named_args == 0) {
+    return Array::null();
+  }
+
+  Zone* zone = Thread::Current()->zone();
+  const Array& names =
+      Array::Handle(zone, Array::New(num_named_args, Heap::kOld));
+  String& name = String::Handle(zone);
+  const intptr_t num_pos_args = PositionalCount();
+  for (intptr_t i = 0; i < num_named_args; ++i) {
+    const intptr_t index = PositionAt(i) - num_pos_args;
+    name = NameAt(i);
+    ASSERT(names.At(index) == Object::null());
+    names.SetAt(index, name);
+  }
+  return names.raw();
+}
+
 intptr_t ArgumentsDescriptor::type_args_len_offset() {
   return Array::element_offset(kTypeArgsLenIndex);
 }
diff --git a/runtime/vm/dart_entry.h b/runtime/vm/dart_entry.h
index 0898a93..cfcd404 100644
--- a/runtime/vm/dart_entry.h
+++ b/runtime/vm/dart_entry.h
@@ -45,6 +45,8 @@
   RawString* NameAt(intptr_t i) const;
   intptr_t PositionAt(intptr_t i) const;
   bool MatchesNameAt(intptr_t i, const String& other) const;
+  // Returns array of argument names in the arguments order.
+  RawArray* GetArgumentNames() const;
 
   // Generated code support.
   static intptr_t type_args_len_offset();
diff --git a/runtime/vm/debugger.cc b/runtime/vm/debugger.cc
index 306cf6f..30f52a8 100644
--- a/runtime/vm/debugger.cc
+++ b/runtime/vm/debugger.cc
@@ -57,6 +57,8 @@
             "handler instead.  This handler dispatches breakpoints to "
             "the VM service.");
 
+DECLARE_FLAG(bool, enable_interpreter);
+DECLARE_FLAG(bool, trace_deoptimization);
 DECLARE_FLAG(bool, warn_on_pause_with_no_debugger);
 
 #ifndef PRODUCT
@@ -257,18 +259,16 @@
       deopt_frame_(Array::ZoneHandle(deopt_frame.raw())),
       deopt_frame_offset_(deopt_frame_offset),
       kind_(kind),
+#if !defined(DART_PRECOMPILED_RUNTIME)
+      is_interpreted_(FLAG_enable_interpreter &&
+                      function_.Bytecode() == code_.raw()),
+#else
+      is_interpreted_(false),
+#endif  // !defined(DART_PRECOMPILED_RUNTIME)
       vars_initialized_(false),
       var_descriptors_(LocalVarDescriptors::ZoneHandle()),
       desc_indices_(8),
       pc_desc_(PcDescriptors::ZoneHandle()) {
-  // TODO(regis): If debugging of interpreted code is required, recognize an
-  // interpreted activation frame and respect alternate frame layout.
-  // For now, punt.
-#if defined(DART_USE_INTERPRETER)
-  if (function_.Bytecode() == code_.raw()) {
-    UNIMPLEMENTED();
-  }
-#endif
 }
 
 ActivationFrame::ActivationFrame(Kind kind)
@@ -288,6 +288,7 @@
       deopt_frame_(Array::ZoneHandle()),
       deopt_frame_offset_(0),
       kind_(kind),
+      is_interpreted_(false),
       vars_initialized_(false),
       var_descriptors_(LocalVarDescriptors::ZoneHandle()),
       desc_indices_(8),
@@ -310,14 +311,27 @@
       deopt_frame_(Array::ZoneHandle()),
       deopt_frame_offset_(0),
       kind_(kAsyncActivation),
+      is_interpreted_(false),
       vars_initialized_(false),
       var_descriptors_(LocalVarDescriptors::ZoneHandle()),
       desc_indices_(8),
       pc_desc_(PcDescriptors::ZoneHandle()) {
   // Extract the function and the code from the asynchronous activation.
   function_ = async_activation.function();
+#if !defined(DART_PRECOMPILED_RUNTIME)
+  if (!FLAG_enable_interpreter || !function_.HasBytecode()) {
+    function_.EnsureHasCompiledUnoptimizedCode();
+  }
+  if (FLAG_enable_interpreter && function_.HasBytecode()) {
+    is_interpreted_ = true;
+    code_ = function_.Bytecode();
+  } else {
+    code_ = function_.unoptimized_code();
+  }
+#else
   function_.EnsureHasCompiledUnoptimizedCode();
   code_ = function_.unoptimized_code();
+#endif  // !defined(DART_PRECOMPILED_RUNTIME)
   ctx_ = async_activation.context();
   ASSERT(fp_ == 0);
   ASSERT(!ctx_.IsNull());
@@ -651,6 +665,11 @@
 
 void ActivationFrame::GetVarDescriptors() {
   if (var_descriptors_.IsNull()) {
+    if (is_interpreted()) {
+      // TODO(regis): Kernel bytecode does not yet provide var descriptors.
+      var_descriptors_ = Object::empty_var_descriptors().raw();
+      return;
+    }
     Code& unoptimized_code = Code::Handle(function().unoptimized_code());
     if (unoptimized_code.IsNull()) {
       Thread* thread = Thread::Current();
@@ -1850,6 +1869,9 @@
 // We currently don't have this info so we deoptimize all functions.
 void Debugger::DeoptimizeWorld() {
   BackgroundCompiler::Stop(isolate_);
+  if (FLAG_trace_deoptimization) {
+    THR_Print("Deopt for debugger\n");
+  }
   DeoptimizeFunctionsOnStack();
   // Iterate over all classes, deoptimize functions.
   // TODO(hausner): Could possibly be combined with RemoveOptimizedCode()
diff --git a/runtime/vm/debugger.h b/runtime/vm/debugger.h
index 2128046..ee4f234 100644
--- a/runtime/vm/debugger.h
+++ b/runtime/vm/debugger.h
@@ -287,6 +287,7 @@
     ASSERT(!code_.IsNull());
     return code_;
   }
+  bool is_interpreted() const { return is_interpreted_; }
 
   RawString* QualifiedFunctionName();
   RawString* SourceUrl();
@@ -420,6 +421,7 @@
 
   Kind kind_;
 
+  bool is_interpreted_;  // Running under kernel bytecode interpreter.
   bool vars_initialized_;
   LocalVarDescriptors& var_descriptors_;
   ZoneGrowableArray<intptr_t> desc_indices_;
diff --git a/runtime/vm/deopt_instructions.cc b/runtime/vm/deopt_instructions.cc
index ec6fa74..ec35ebc8 100644
--- a/runtime/vm/deopt_instructions.cc
+++ b/runtime/vm/deopt_instructions.cc
@@ -335,7 +335,7 @@
   }
 }
 
-intptr_t* DeoptContext::CatchEntryState(intptr_t num_vars) {
+const CatchEntryMoves* DeoptContext::ToCatchEntryMoves(intptr_t num_vars) {
   const Code& code = Code::Handle(code_);
   const TypedData& deopt_info = TypedData::Handle(deopt_info_);
   GrowableArray<DeoptInstr*> deopt_instructions;
@@ -343,8 +343,7 @@
   ASSERT(!deopt_table.IsNull());
   DeoptInfo::Unpack(deopt_table, deopt_info, &deopt_instructions);
 
-  intptr_t* state = new intptr_t[2 * num_vars + 1];
-  state[0] = num_vars;
+  CatchEntryMoves* moves = CatchEntryMoves::Allocate(num_vars);
 
   Function& function = Function::Handle(zone(), code.function());
   intptr_t params =
@@ -363,12 +362,10 @@
     DeoptInstr* instr = deopt_instructions[len - 1 - slot];
     intptr_t dest_index = i - params;
 #endif
-    CatchEntryStatePair p = instr->ToCatchEntryStatePair(this, dest_index);
-    state[1 + 2 * i] = p.src;
-    state[2 + 2 * i] = p.dest;
+    moves->At(i) = instr->ToCatchEntryMove(this, dest_index);
   }
 
-  return state;
+  return moves;
 }
 
 static void FillDeferredSlots(DeoptContext* deopt_context,
@@ -508,9 +505,9 @@
     *reinterpret_cast<RawObject**>(dest_addr) = obj.raw();
   }
 
-  CatchEntryStatePair ToCatchEntryStatePair(DeoptContext* deopt_context,
-                                            intptr_t dest_slot) {
-    return CatchEntryStatePair::FromConstant(object_table_index_, dest_slot);
+  CatchEntryMove ToCatchEntryMove(DeoptContext* deopt_context,
+                                  intptr_t dest_slot) {
+    return CatchEntryMove::FromConstant(object_table_index_, dest_slot);
   }
 
  private:
@@ -540,10 +537,11 @@
     *dest_addr = source_.Value<intptr_t>(deopt_context);
   }
 
-  CatchEntryStatePair ToCatchEntryStatePair(DeoptContext* deopt_context,
-                                            intptr_t dest_slot) {
-    return CatchEntryStatePair::FromMove(source_.StackSlot(deopt_context),
-                                         dest_slot);
+  CatchEntryMove ToCatchEntryMove(DeoptContext* deopt_context,
+                                  intptr_t dest_slot) {
+    return CatchEntryMove::FromSlot(CatchEntryMove::SourceKind::kTaggedSlot,
+                                    source_.StackSlot(deopt_context),
+                                    dest_slot);
   }
 
  private:
@@ -599,6 +597,15 @@
                                   hi_.Value<int32_t>(deopt_context));
   }
 
+  CatchEntryMove ToCatchEntryMove(DeoptContext* deopt_context,
+                                  intptr_t dest_slot) {
+    return CatchEntryMove::FromSlot(
+        CatchEntryMove::SourceKind::kInt64PairSlot,
+        CatchEntryMove::EncodePairSource(lo_.StackSlot(deopt_context),
+                                         hi_.StackSlot(deopt_context)),
+        dest_slot);
+  }
+
  private:
   static const intptr_t kFieldWidth = kBitsPerWord / 2;
   class LoRegister : public BitField<intptr_t, intptr_t, 0, kFieldWidth> {};
@@ -611,7 +618,7 @@
   DISALLOW_COPY_AND_ASSIGN(DeoptMintPairInstr);
 };
 
-template <DeoptInstr::Kind K, typename T>
+template <DeoptInstr::Kind K, CatchEntryMove::SourceKind slot_kind, typename T>
 class DeoptIntInstr : public DeoptIntegerInstrBase {
  public:
   explicit DeoptIntInstr(intptr_t source_index)
@@ -629,17 +636,35 @@
     return static_cast<int64_t>(source_.Value<T>(deopt_context));
   }
 
+  CatchEntryMove ToCatchEntryMove(DeoptContext* deopt_context,
+                                  intptr_t dest_slot) {
+    return CatchEntryMove::FromSlot(slot_kind, source_.StackSlot(deopt_context),
+                                    dest_slot);
+  }
+
  private:
   const CpuRegisterSource source_;
 
   DISALLOW_COPY_AND_ASSIGN(DeoptIntInstr);
 };
 
-typedef DeoptIntInstr<DeoptInstr::kUint32, uint32_t> DeoptUint32Instr;
-typedef DeoptIntInstr<DeoptInstr::kInt32, int32_t> DeoptInt32Instr;
-typedef DeoptIntInstr<DeoptInstr::kMint, int64_t> DeoptMintInstr;
+typedef DeoptIntInstr<DeoptInstr::kUint32,
+                      CatchEntryMove::SourceKind::kUint32Slot,
+                      uint32_t>
+    DeoptUint32Instr;
+typedef DeoptIntInstr<DeoptInstr::kInt32,
+                      CatchEntryMove::SourceKind::kInt32Slot,
+                      int32_t>
+    DeoptInt32Instr;
+typedef DeoptIntInstr<DeoptInstr::kMint,
+                      CatchEntryMove::SourceKind::kInt64Slot,
+                      int64_t>
+    DeoptMintInstr;
 
-template <DeoptInstr::Kind K, typename Type, typename RawObjectType>
+template <DeoptInstr::Kind K,
+          CatchEntryMove::SourceKind slot_kind,
+          typename Type,
+          typename RawObjectType>
 class DeoptFpuInstr : public DeoptInstr {
  public:
   explicit DeoptFpuInstr(intptr_t source_index) : source_(source_index) {}
@@ -658,22 +683,39 @@
         reinterpret_cast<RawObjectType**>(dest_addr));
   }
 
+  CatchEntryMove ToCatchEntryMove(DeoptContext* deopt_context,
+                                  intptr_t dest_slot) {
+    return CatchEntryMove::FromSlot(slot_kind, source_.StackSlot(deopt_context),
+                                    dest_slot);
+  }
+
  private:
   const FpuRegisterSource source_;
 
   DISALLOW_COPY_AND_ASSIGN(DeoptFpuInstr);
 };
 
-typedef DeoptFpuInstr<DeoptInstr::kDouble, double, RawDouble> DeoptDoubleInstr;
+typedef DeoptFpuInstr<DeoptInstr::kDouble,
+                      CatchEntryMove::SourceKind::kDoubleSlot,
+                      double,
+                      RawDouble>
+    DeoptDoubleInstr;
 
 // Simd128 types.
-typedef DeoptFpuInstr<DeoptInstr::kFloat32x4, simd128_value_t, RawFloat32x4>
+typedef DeoptFpuInstr<DeoptInstr::kFloat32x4,
+                      CatchEntryMove::SourceKind::kFloat32x4Slot,
+                      simd128_value_t,
+                      RawFloat32x4>
     DeoptFloat32x4Instr;
-typedef DeoptFpuInstr<DeoptInstr::kFloat32x4, simd128_value_t, RawFloat32x4>
-    DeoptFloat32x4Instr;
-typedef DeoptFpuInstr<DeoptInstr::kFloat64x2, simd128_value_t, RawFloat64x2>
+typedef DeoptFpuInstr<DeoptInstr::kFloat64x2,
+                      CatchEntryMove::SourceKind::kFloat64x2Slot,
+                      simd128_value_t,
+                      RawFloat64x2>
     DeoptFloat64x2Instr;
-typedef DeoptFpuInstr<DeoptInstr::kInt32x4, simd128_value_t, RawInt32x4>
+typedef DeoptFpuInstr<DeoptInstr::kInt32x4,
+                      CatchEntryMove::SourceKind::kInt32x4Slot,
+                      simd128_value_t,
+                      RawInt32x4>
     DeoptInt32x4Instr;
 
 // Deoptimization instruction creating a PC marker for the code of
diff --git a/runtime/vm/deopt_instructions.h b/runtime/vm/deopt_instructions.h
index 38d95fd..e2096b6 100644
--- a/runtime/vm/deopt_instructions.h
+++ b/runtime/vm/deopt_instructions.h
@@ -166,8 +166,10 @@
   // objects.
   void FillDestFrame();
 
-  // Allocate and prepare exceptions metadata for TrySync
-  intptr_t* CatchEntryState(intptr_t num_vars);
+  // Convert deoptimization instructions to a list of moves that need
+  // to be executed when entering catch entry block from this deoptimization
+  // point.
+  const CatchEntryMoves* ToCatchEntryMoves(intptr_t num_vars);
 
   // Materializes all deferred objects.  Returns the total number of
   // artificial arguments used during deoptimization.
@@ -334,11 +336,10 @@
 
   virtual void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) = 0;
 
-  // Convert DeoptInstr to TrySync metadata entry.
-  virtual CatchEntryStatePair ToCatchEntryStatePair(DeoptContext* deopt_context,
-                                                    intptr_t dest_slot) {
+  virtual CatchEntryMove ToCatchEntryMove(DeoptContext* deopt_context,
+                                          intptr_t dest_slot) {
     UNREACHABLE();
-    return CatchEntryStatePair();
+    return CatchEntryMove();
   }
 
   virtual DeoptInstr::Kind kind() const = 0;
diff --git a/runtime/vm/exceptions.cc b/runtime/vm/exceptions.cc
index 28520f9..45d836a 100644
--- a/runtime/vm/exceptions.cc
+++ b/runtime/vm/exceptions.cc
@@ -25,6 +25,7 @@
 
 namespace dart {
 
+DECLARE_FLAG(bool, enable_interpreter);
 DECLARE_FLAG(bool, trace_deoptimization);
 DEFINE_FLAG(bool,
             print_stacktrace_at_throw,
@@ -140,20 +141,10 @@
   }
 }
 
-static RawObject** VariableAt(uword fp, int stack_slot) {
-#if defined(TARGET_ARCH_DBC)
-  return reinterpret_cast<RawObject**>(fp + stack_slot * kWordSize);
-#else
-  const intptr_t frame_slot =
-      runtime_frame_layout.FrameSlotForVariableIndex(-stack_slot);
-  return reinterpret_cast<RawObject**>(fp + frame_slot * kWordSize);
-#endif
-}
-
 class ExceptionHandlerFinder : public StackResource {
  public:
   explicit ExceptionHandlerFinder(Thread* thread)
-      : StackResource(thread), thread_(thread), cache_(NULL), metadata_(NULL) {}
+      : StackResource(thread), thread_(thread) {}
 
   // Iterate through the stack frames and try to find a frame with an
   // exception handler. Once found, set the pc, sp and fp so that execution
@@ -171,7 +162,7 @@
     uword temp_handler_pc = kUwordMax;
     bool is_optimized = false;
     code_ = NULL;
-    cache_ = thread_->isolate()->catch_entry_state_cache();
+    catch_entry_moves_cache_ = thread_->isolate()->catch_entry_moves_cache();
 
     while (!frame->IsEntryFrame()) {
       if (frame->IsDartFrame()) {
@@ -186,13 +177,20 @@
             if (is_optimized) {
               pc_ = frame->pc();
               code_ = &Code::Handle(frame->LookupDartCode());
-              CatchEntryState* state = cache_->Lookup(pc_);
-              if (state != NULL) cached_ = *state;
+              CatchEntryMovesRefPtr* cached_catch_entry_moves =
+                  catch_entry_moves_cache_->Lookup(pc_);
+              if (cached_catch_entry_moves != NULL) {
+                cached_catch_entry_moves_ = *cached_catch_entry_moves;
+              }
 #if !defined(DART_PRECOMPILED_RUNTIME) && !defined(DART_PRECOMPILER)
               intptr_t num_vars = Smi::Value(code_->variables());
-              if (cached_.Empty()) GetMetaDataFromDeopt(num_vars, frame);
+              if (cached_catch_entry_moves_.IsEmpty()) {
+                GetCatchEntryMovesFromDeopt(num_vars, frame);
+              }
 #else
-              if (cached_.Empty()) ReadCompressedMetaData();
+              if (cached_catch_entry_moves_.IsEmpty()) {
+                ReadCompressedCatchEntryMoves();
+              }
 #endif  // !defined(DART_PRECOMPILED_RUNTIME) && !defined(DART_PRECOMPILER)
             }
           }
@@ -215,80 +213,124 @@
     return handler_pc_set_;
   }
 
-  void TrySync() {
-    if (code_ == NULL || !code_->is_optimized()) {
+  // When entering catch block in the optimized code we need to execute
+  // catch entry moves that would morph the state of the frame into
+  // what catch entry expects.
+  void PrepareFrameForCatchEntry() {
+    if (code_ == nullptr || !code_->is_optimized()) {
       return;
     }
-    if (!cached_.Empty()) {
-      // Cache hit.
-      TrySyncCached(&cached_);
+
+    if (cached_catch_entry_moves_.IsEmpty()) {
+      catch_entry_moves_cache_->Insert(
+          pc_, CatchEntryMovesRefPtr(catch_entry_moves_));
     } else {
-      // New cache entry.
-      CatchEntryState m(metadata_);
-      TrySyncCached(&m);
-      cache_->Insert(pc_, m);
+      catch_entry_moves_ = &cached_catch_entry_moves_.moves();
     }
+
+    ExecuteCatchEntryMoves(*catch_entry_moves_);
   }
 
-  void TrySyncCached(CatchEntryState* md) {
+  void ExecuteCatchEntryMoves(const CatchEntryMoves& moves) {
     uword fp = handler_fp;
-    ObjectPool* pool = NULL;
-    intptr_t pairs = md->Pairs();
-    for (int j = 0; j < pairs; j++) {
-      intptr_t src = md->Src(j);
-      intptr_t dest = md->Dest(j);
-      if (md->isMove(j)) {
-        *VariableAt(fp, dest) = *VariableAt(fp, src);
-      } else {
-        if (pool == NULL) {
-          pool = &ObjectPool::Handle(code_->object_pool());
-        }
-        RawObject* obj = pool->ObjectAt(src);
-        *VariableAt(fp, dest) = obj;
+    ObjectPool* pool = nullptr;
+    for (int j = 0; j < moves.count(); j++) {
+      const CatchEntryMove& move = moves.At(j);
+
+      RawObject* value;
+      switch (move.source_kind()) {
+        case CatchEntryMove::SourceKind::kConstant:
+          if (pool == nullptr) {
+            pool = &ObjectPool::Handle(code_->object_pool());
+          }
+          value = pool->ObjectAt(move.src_slot());
+          break;
+
+        case CatchEntryMove::SourceKind::kTaggedSlot:
+          value = *TaggedSlotAt(fp, move.src_slot());
+          break;
+
+        case CatchEntryMove::SourceKind::kDoubleSlot:
+          value = Double::New(*SlotAt<double>(fp, move.src_slot()));
+          break;
+
+        case CatchEntryMove::SourceKind::kFloat32x4Slot:
+          value = Float32x4::New(*SlotAt<simd128_value_t>(fp, move.src_slot()));
+          break;
+
+        case CatchEntryMove::SourceKind::kFloat64x2Slot:
+          value = Float64x2::New(*SlotAt<simd128_value_t>(fp, move.src_slot()));
+          break;
+
+        case CatchEntryMove::SourceKind::kInt32x4Slot:
+          value = Int32x4::New(*SlotAt<simd128_value_t>(fp, move.src_slot()));
+          break;
+
+        case CatchEntryMove::SourceKind::kInt64PairSlot:
+          value = Integer::New(
+              Utils::LowHighTo64Bits(*SlotAt<uint32_t>(fp, move.src_lo_slot()),
+                                     *SlotAt<int32_t>(fp, move.src_hi_slot())));
+          break;
+
+        case CatchEntryMove::SourceKind::kInt64Slot:
+          value = Integer::New(*SlotAt<int64_t>(fp, move.src_slot()));
+          break;
+
+        case CatchEntryMove::SourceKind::kInt32Slot:
+          value = Integer::New(*SlotAt<int32_t>(fp, move.src_slot()));
+          break;
+
+        case CatchEntryMove::SourceKind::kUint32Slot:
+          value = Integer::New(*SlotAt<uint32_t>(fp, move.src_slot()));
+          break;
+
+        default:
+          UNREACHABLE();
       }
+
+      *TaggedSlotAt(fp, move.dest_slot()) = value;
     }
   }
 
 #if defined(DART_PRECOMPILED_RUNTIME) || defined(DART_PRECOMPILER)
-  void ReadCompressedMetaData() {
+  void ReadCompressedCatchEntryMoves() {
     intptr_t pc_offset = pc_ - code_->PayloadStart();
-    const TypedData& td = TypedData::Handle(code_->catch_entry_state_maps());
+    const TypedData& td = TypedData::Handle(code_->catch_entry_moves_maps());
     NoSafepointScope no_safepoint;
     ReadStream stream(static_cast<uint8_t*>(td.DataAddr(0)), td.Length());
 
-    bool found_metadata = false;
+    intptr_t prefix_length = 0, suffix_length = 0, suffix_offset = 0;
     while (stream.PendingBytes() > 0) {
       intptr_t target_pc_offset = Reader::Read(&stream);
-      intptr_t variables = Reader::Read(&stream);
-      intptr_t suffix_length = Reader::Read(&stream);
-      intptr_t suffix_offset = Reader::Read(&stream);
+      prefix_length = Reader::Read(&stream);
+      suffix_length = Reader::Read(&stream);
+      suffix_offset = Reader::Read(&stream);
       if (pc_offset == target_pc_offset) {
-        metadata_ = new intptr_t[2 * (variables + suffix_length) + 1];
-        metadata_[0] = variables + suffix_length;
-        for (int j = 0; j < variables; j++) {
-          intptr_t src = Reader::Read(&stream);
-          intptr_t dest = Reader::Read(&stream);
-          metadata_[1 + 2 * j] = src;
-          metadata_[2 + 2 * j] = dest;
-        }
-        ReadCompressedSuffix(&stream, suffix_offset, suffix_length, metadata_,
-                             2 * variables + 1);
-        found_metadata = true;
         break;
-      } else {
-        for (intptr_t j = 0; j < 2 * variables; j++) {
-          Reader::Read(&stream);
-        }
+      }
+
+      // Skip the moves.
+      for (intptr_t j = 0; j < prefix_length; j++) {
+        CatchEntryMove::ReadFrom(&stream);
       }
     }
-    ASSERT(found_metadata);
+    ASSERT((stream.PendingBytes() > 0) || (prefix_length == 0));
+
+    CatchEntryMoves* moves =
+        CatchEntryMoves::Allocate(prefix_length + suffix_length);
+    for (int j = 0; j < prefix_length; j++) {
+      moves->At(j) = CatchEntryMove::ReadFrom(&stream);
+    }
+    ReadCompressedCatchEntryMovesSuffix(&stream, suffix_offset, suffix_length,
+                                        moves, prefix_length);
+    catch_entry_moves_ = moves;
   }
 
-  void ReadCompressedSuffix(ReadStream* stream,
-                            intptr_t offset,
-                            intptr_t length,
-                            intptr_t* target,
-                            intptr_t target_offset) {
+  void ReadCompressedCatchEntryMovesSuffix(ReadStream* stream,
+                                           intptr_t offset,
+                                           intptr_t length,
+                                           CatchEntryMoves* moves,
+                                           intptr_t moves_offset) {
     stream->SetPosition(offset);
     Reader::Read(stream);  // skip pc_offset
     Reader::Read(stream);  // skip variables
@@ -296,24 +338,23 @@
     intptr_t suffix_offset = Reader::Read(stream);
     intptr_t to_read = length - suffix_length;
     for (int j = 0; j < to_read; j++) {
-      target[target_offset + 2 * j] = Reader::Read(stream);
-      target[target_offset + 2 * j + 1] = Reader::Read(stream);
+      moves->At(moves_offset + j) = CatchEntryMove::ReadFrom(stream);
     }
     if (suffix_length > 0) {
-      ReadCompressedSuffix(stream, suffix_offset, suffix_length, target,
-                           target_offset + to_read * 2);
+      ReadCompressedCatchEntryMovesSuffix(stream, suffix_offset, suffix_length,
+                                          moves, moves_offset + to_read);
     }
   }
 
 #else
-  void GetMetaDataFromDeopt(intptr_t num_vars, StackFrame* frame) {
+  void GetCatchEntryMovesFromDeopt(intptr_t num_vars, StackFrame* frame) {
     Isolate* isolate = thread_->isolate();
     DeoptContext* deopt_context =
         new DeoptContext(frame, *code_, DeoptContext::kDestIsAllocated, NULL,
                          NULL, true, false /* deoptimizing_code */);
     isolate->set_deopt_context(deopt_context);
 
-    metadata_ = deopt_context->CatchEntryState(num_vars);
+    catch_entry_moves_ = deopt_context->ToCatchEntryMoves(num_vars);
 
     isolate->set_deopt_context(NULL);
     delete deopt_context;
@@ -326,16 +367,47 @@
   uword handler_fp;
 
  private:
+  template <typename T>
+  static T* SlotAt(uword fp, int stack_slot) {
+#if defined(TARGET_ARCH_DBC)
+    return reinterpret_cast<T*>(fp + stack_slot * kWordSize);
+#else
+    const intptr_t frame_slot =
+        runtime_frame_layout.FrameSlotForVariableIndex(-stack_slot);
+    return reinterpret_cast<T*>(fp + frame_slot * kWordSize);
+#endif
+  }
+
+  static RawObject** TaggedSlotAt(uword fp, int stack_slot) {
+    return SlotAt<RawObject*>(fp, stack_slot);
+  }
+
   typedef ReadStream::Raw<sizeof(intptr_t), intptr_t> Reader;
   Thread* thread_;
-  CatchEntryStateCache* cache_;
   Code* code_;
   bool handler_pc_set_;
-  intptr_t* metadata_;      // MetaData generated from deopt.
-  CatchEntryState cached_;  // Value of per PC MetaData cache.
   intptr_t pc_;             // Current pc in the handler frame.
+
+  const CatchEntryMoves* catch_entry_moves_ = nullptr;
+  CatchEntryMovesCache* catch_entry_moves_cache_ = nullptr;
+  CatchEntryMovesRefPtr cached_catch_entry_moves_;
 };
 
+CatchEntryMove CatchEntryMove::ReadFrom(ReadStream* stream) {
+  using Reader = ReadStream::Raw<sizeof(intptr_t), intptr_t>;
+  const intptr_t src = Reader::Read(stream);
+  const intptr_t dest_and_kind = Reader::Read(stream);
+  return CatchEntryMove(src, dest_and_kind);
+}
+
+#if !defined(DART_PRECOMPILED_RUNTIME)
+void CatchEntryMove::WriteTo(WriteStream* stream) {
+  using Writer = WriteStream::Raw<sizeof(intptr_t), intptr_t>;
+  Writer::Write(stream, src_);
+  Writer::Write(stream, dest_and_kind_);
+}
+#endif
+
 static void FindErrorHandler(uword* handler_pc,
                              uword* handler_sp,
                              uword* handler_fp) {
@@ -463,15 +535,19 @@
   Simulator::Current()->JumpToFrame(program_counter, stack_pointer,
                                     frame_pointer, thread);
 #else
-#if defined(DART_USE_INTERPRETER)
-  Interpreter* interpreter = thread->isolate()->interpreter();
-  if ((interpreter != NULL) && interpreter->HasFrame(frame_pointer)) {
-    interpreter->JumpToFrame(program_counter, stack_pointer, frame_pointer,
-                             thread);
-  }
+
+#if !defined(DART_PRECOMPILED_RUNTIME)
   // TODO(regis): We still possibly need to unwind interpreter frames if they
   // are callee frames of the C++ frame handling the exception.
-#endif
+  if (FLAG_enable_interpreter) {
+    Interpreter* interpreter = thread->isolate()->interpreter();
+    if ((interpreter != NULL) && interpreter->HasFrame(frame_pointer)) {
+      interpreter->JumpToFrame(program_counter, stack_pointer, frame_pointer,
+                               thread);
+    }
+  }
+#endif  // !defined(DART_PRECOMPILED_RUNTIME)
+
   // Prepare for unwinding frames by destroying all the stack resources
   // in the previous frames.
   StackResource::Unwind(thread);
@@ -614,7 +690,7 @@
     THR_Print("%s\n", stacktrace.ToCString());
   }
   if (handler_exists) {
-    finder.TrySync();
+    finder.PrepareFrameForCatchEntry();
     // Found a dart handler for the exception, jump to it.
     JumpToExceptionHandler(thread, handler_pc, handler_sp, handler_fp,
                            exception, stacktrace);
diff --git a/runtime/vm/exceptions.h b/runtime/vm/exceptions.h
index d9b8c14..b681b0f 100644
--- a/runtime/vm/exceptions.h
+++ b/runtime/vm/exceptions.h
@@ -6,6 +6,7 @@
 #define RUNTIME_VM_EXCEPTIONS_H_
 
 #include "vm/allocation.h"
+#include "vm/bitfield.h"
 #include "vm/token_position.h"
 
 namespace dart {
@@ -22,6 +23,8 @@
 class RawObject;
 class RawScript;
 class RawStackTrace;
+class ReadStream;
+class WriteStream;
 class String;
 class Thread;
 
@@ -106,61 +109,193 @@
   int8_t is_generated;         // True if this is a generated handler.
 };
 
-class CatchEntryState {
+//
+// Support for try/catch in the optimized code.
+//
+// Optimizing compiler does not model exceptional control flow explicitly,
+// instead we rely on the runtime system to create correct state at the
+// entry into the catch block by reshuffling values in the frame into
+// positions where they are expected to be at the beginning of the catch block.
+//
+// See runtime/docs/compiler/exceptions.md for more details.
+//
+
+// A single move from a stack slot or an object pool into another stack slot.
+// Destination slot is expecting only tagged values, however source
+// slot can contain an unboxed value (e.g. an unboxed double) - in this case
+// we will box the value before executing the move.
+class CatchEntryMove {
  public:
-  enum { kCatchEntryStateIsMove = 1, kCatchEntryStateDestShift = 1 };
+  CatchEntryMove()
+      : src_(0),
+        dest_and_kind_(static_cast<intptr_t>(SourceKind::kTaggedSlot)) {
+    ASSERT(IsRedundant());
+  }
 
-  CatchEntryState() : data_(NULL), ref_count_(NULL) {}
-  explicit CatchEntryState(intptr_t* data)
-      : data_(data), ref_count_(new intptr_t(1)) {}
+  enum class SourceKind {
+    kConstant,
+    kTaggedSlot,
+    kDoubleSlot,
+    kFloat32x4Slot,
+    kFloat64x2Slot,
+    kInt32x4Slot,
+    kInt64PairSlot,
+    kInt64Slot,
+    kInt32Slot,
+    kUint32Slot,
+  };
 
-  CatchEntryState(const CatchEntryState& state) { Copy(state); }
+  SourceKind source_kind() const {
+    return SourceKindField::decode(dest_and_kind_);
+  }
 
-  ~CatchEntryState() { Destroy(); }
+  intptr_t src_slot() const {
+    ASSERT(source_kind() != SourceKind::kInt64PairSlot);
+    return src_;
+  }
 
-  CatchEntryState& operator=(const CatchEntryState& state) {
+  intptr_t src_lo_slot() const {
+    ASSERT(source_kind() == SourceKind::kInt64PairSlot);
+    return LoSourceSlot::decode(src_);
+  }
+
+  intptr_t src_hi_slot() const {
+    ASSERT(source_kind() == SourceKind::kInt64PairSlot);
+    return HiSourceSlot::decode(src_);
+  }
+
+  intptr_t dest_slot() const {
+    return dest_and_kind_ >> SourceKindField::bitsize();
+  }
+
+  static CatchEntryMove FromConstant(intptr_t pool_id, intptr_t dest_slot) {
+    return FromSlot(SourceKind::kConstant, pool_id, dest_slot);
+  }
+
+  static CatchEntryMove FromSlot(SourceKind kind,
+                                 intptr_t src_slot,
+                                 intptr_t dest_slot) {
+    return CatchEntryMove(src_slot,
+                          SourceKindField::encode(kind) |
+                              (dest_slot << SourceKindField::bitsize()));
+  }
+
+  static intptr_t EncodePairSource(intptr_t src_lo_slot, intptr_t src_hi_slot) {
+    return LoSourceSlot::encode(src_lo_slot) |
+           HiSourceSlot::encode(src_hi_slot);
+  }
+
+  bool IsRedundant() const {
+    return (source_kind() == SourceKind::kTaggedSlot) &&
+           (dest_slot() == src_slot());
+  }
+
+  bool operator==(const CatchEntryMove& rhs) {
+    return src_ == rhs.src_ && dest_and_kind_ == rhs.dest_and_kind_;
+  }
+
+  static CatchEntryMove ReadFrom(ReadStream* stream);
+
+#if !defined(DART_PRECOMPILED_RUNTIME)
+  void WriteTo(WriteStream* stream);
+#endif
+
+ private:
+  CatchEntryMove(intptr_t src, intptr_t dest_and_kind)
+      : src_(src), dest_and_kind_(dest_and_kind) {}
+
+  // Note: BitField helper does not work with signed values of size that does
+  // not match the destination size - thus we don't use BitField for declaring
+  // DestinationField and instead encode and decode it manually.
+  using SourceKindField = BitField<intptr_t, SourceKind, 0, 4>;
+
+  static constexpr intptr_t kHalfSourceBits = kBitsPerWord / 2;
+  using LoSourceSlot = BitField<intptr_t, intptr_t, 0, kHalfSourceBits>;
+  using HiSourceSlot =
+      BitField<intptr_t, intptr_t, kHalfSourceBits, kHalfSourceBits>;
+
+  intptr_t src_;
+  intptr_t dest_and_kind_;
+};
+
+// A sequence of moves that needs to be executed to create a state expected
+// at the catch entry.
+// Note: this is a deserialized representation that is used by the runtime
+// system as a temporary representation and for caching. That is why this
+// object is allocated in the malloced heap and not in the Dart heap.
+class CatchEntryMoves {
+ public:
+  static CatchEntryMoves* Allocate(intptr_t num_moves) {
+    auto result = reinterpret_cast<CatchEntryMoves*>(
+        malloc(sizeof(CatchEntryMoves) + sizeof(CatchEntryMove) * num_moves));
+    result->count_ = num_moves;
+    return result;
+  }
+
+  static void Free(const CatchEntryMoves* moves) {
+    free(const_cast<CatchEntryMoves*>(moves));
+  }
+
+  intptr_t count() const { return count_; }
+  CatchEntryMove& At(intptr_t i) { return Moves()[i]; }
+  const CatchEntryMove& At(intptr_t i) const { return Moves()[i]; }
+
+ private:
+  CatchEntryMove* Moves() {
+    return reinterpret_cast<CatchEntryMove*>(this + 1);
+  }
+
+  const CatchEntryMove* Moves() const {
+    return reinterpret_cast<const CatchEntryMove*>(this + 1);
+  }
+
+  intptr_t count_;
+  // Followed by CatchEntryMove[count_]
+};
+
+// A simple reference counting wrapper for CatchEntryMoves.
+//
+// TODO(vegorov) switch this to intrusive reference counting.
+class CatchEntryMovesRefPtr {
+ public:
+  CatchEntryMovesRefPtr() : moves_(nullptr), ref_count_(nullptr) {}
+  explicit CatchEntryMovesRefPtr(const CatchEntryMoves* moves)
+      : moves_(moves), ref_count_(new intptr_t(1)) {}
+
+  CatchEntryMovesRefPtr(const CatchEntryMovesRefPtr& state) { Copy(state); }
+
+  ~CatchEntryMovesRefPtr() { Destroy(); }
+
+  CatchEntryMovesRefPtr& operator=(const CatchEntryMovesRefPtr& state) {
     Destroy();
     Copy(state);
     return *this;
   }
 
-  bool Empty() { return ref_count_ == NULL; }
+  bool IsEmpty() { return ref_count_ == nullptr; }
 
-  intptr_t Pairs() { return data_[0]; }
-
-  intptr_t Src(intptr_t i) { return data_[1 + 2 * i]; }
-
-  intptr_t Dest(intptr_t i) {
-    return data_[2 + 2 * i] >> kCatchEntryStateDestShift;
-  }
-
-  bool isMove(intptr_t i) { return data_[2 + 2 * i] & kCatchEntryStateIsMove; }
+  const CatchEntryMoves& moves() { return *moves_; }
 
  private:
   void Destroy() {
-    if (ref_count_ != NULL) {
+    if (ref_count_ != nullptr) {
       (*ref_count_)--;
       if (*ref_count_ == 0) {
         delete ref_count_;
-        delete[] data_;
+        CatchEntryMoves::Free(moves_);
       }
     }
   }
 
-  void Copy(const CatchEntryState& state) {
-    data_ = state.data_;
+  void Copy(const CatchEntryMovesRefPtr& state) {
+    moves_ = state.moves_;
     ref_count_ = state.ref_count_;
-    if (ref_count_ != NULL) {
+    if (ref_count_ != nullptr) {
       (*ref_count_)++;
     }
   }
 
-  // data_ has the following format:
-  // 0 - number of pairs in this state
-  // 1-2 - 1st encoded src,dest pair
-  // 3-4 - 2nd pair
-  // ....
-  intptr_t* data_;
+  const CatchEntryMoves* moves_;
   intptr_t* ref_count_;
 };
 
diff --git a/runtime/vm/flag_list.h b/runtime/vm/flag_list.h
index 83c1162..8ce163e 100644
--- a/runtime/vm/flag_list.h
+++ b/runtime/vm/flag_list.h
@@ -12,13 +12,6 @@
 #define USING_DBC false
 #endif
 
-// Don't use USING_KBC outside of this file.
-#if defined(DART_USE_INTERPRETER)
-#define USING_KBC true
-#else
-#define USING_KBC false
-#endif
-
 // Don't use USING_MULTICORE outside of this file.
 #if defined(ARCH_IS_MULTI_CORE)
 #define USING_MULTICORE true
@@ -132,7 +125,7 @@
     "Max size of new gen semi space in MB")                                    \
   P(new_gen_semi_initial_size, int, (kWordSize <= 4) ? 1 : 2,                  \
     "Initial size of new gen semi space in MB")                                \
-  P(optimization_counter_threshold, int, USING_KBC ? -1 : 30000,               \
+  P(optimization_counter_threshold, int, 30000,                                \
     "Function's usage-counter value before it is optimized, -1 means never")   \
   P(old_gen_heap_size, int, kDefaultMaxOldGenHeapSize,                         \
     "Max size of old gen heap size in MB, or 0 for unlimited,"                 \
@@ -163,13 +156,13 @@
   R(profiler, false, bool, false, "Enable the profiler.")                      \
   R(profiler_native_memory, false, bool, false,                                \
     "Enable native memory statistic collection.")                              \
-  P(reify_generic_functions, bool, false,                                      \
+  P(reify_generic_functions, bool, true,                                       \
     "Enable reification of generic functions (not yet supported).")            \
   P(reorder_basic_blocks, bool, true, "Reorder basic blocks")                  \
   C(stress_async_stacks, false, false, bool, false,                            \
     "Stress test async stack traces")                                          \
-  P(strong, bool, false, "Enable strong mode.")                                \
-  P(sync_async, bool, false, "Start `async` functions synchronously.")         \
+  P(strong, bool, true, "Enable strong mode.")                                 \
+  P(sync_async, bool, true, "Start `async` functions synchronously.")          \
   R(support_ast_printer, false, bool, true, "Support the AST printer.")        \
   R(support_compiler_stats, false, bool, true, "Support compiler stats.")      \
   R(support_disassembler, false, bool, true, "Support the disassembler.")      \
@@ -192,10 +185,11 @@
   D(trace_zones, bool, false, "Traces allocation sizes in the zone.")          \
   P(truncating_left_shift, bool, true,                                         \
     "Optimize left shift to truncate if possible")                             \
+  C(use_bytecode_compiler, false, false, bool, false, "Compile from bytecode") \
   P(use_compactor, bool, false, "Compact the heap during old-space GC.")       \
   P(use_cha_deopt, bool, true,                                                 \
     "Use class hierarchy analysis even if it can cause deoptimization.")       \
-  P(use_field_guards, bool, !USING_DBC && !USING_KBC,                          \
+  P(use_field_guards, bool, !USING_DBC,                                        \
     "Use field guards and track field types")                                  \
   C(use_osr, false, true, bool, true, "Use OSR")                               \
   P(use_strong_mode_types, bool, true, "Optimize based on strong mode types.") \
@@ -211,9 +205,12 @@
   P(enable_slow_path_sharing, bool, true, "Enable sharing of slow-path code.") \
   P(shared_slow_path_triggers_gc, bool, false,                                 \
     "TESTING: slow-path triggers a GC.")                                       \
-  P(enable_multiple_entrypoints, bool, true,                                   \
+  P(enable_multiple_entrypoints, bool, false,                                  \
     "Enable multiple entrypoints per-function and related optimizations.")     \
   R(enable_testing_pragmas, false, bool, false,                                \
-    "Enable magical pragmas for testing purposes. Use at your own risk!")
+    "Enable magical pragmas for testing purposes. Use at your own risk!")      \
+  R(eliminate_type_checks, true, bool, true,                                   \
+    "Eliminate type checks when allowed by static type analysis.")             \
+  P(enable_interpreter, bool, false, "Enable interpreting kernel bytecode.")
 
 #endif  // RUNTIME_VM_FLAG_LIST_H_
diff --git a/runtime/vm/globals.h b/runtime/vm/globals.h
index a261211..82f860c 100644
--- a/runtime/vm/globals.h
+++ b/runtime/vm/globals.h
@@ -85,6 +85,10 @@
 #define TAG_IC_DATA
 #endif
 
+#if !defined(TARGET_OS_MACOS_IOS) && !defined(TARGET_OS_ANDROID)
+#define CONCURRENT_MARKING 1
+#endif
+
 // The expression OFFSET_OF(type, field) computes the byte-offset of
 // the specified field relative to the containing type.
 //
diff --git a/runtime/vm/heap/heap.cc b/runtime/vm/heap/heap.cc
index de9911f..2b319e2 100644
--- a/runtime/vm/heap/heap.cc
+++ b/runtime/vm/heap/heap.cc
@@ -431,7 +431,7 @@
     NOT_IN_PRODUCT(PrintStatsToTimeline(&tds, reason));
     // Some Code objects may have been collected so invalidate handler cache.
     thread->isolate()->handler_info_cache()->Clear();
-    thread->isolate()->catch_entry_state_cache()->Clear();
+    thread->isolate()->catch_entry_moves_cache()->Clear();
     EndOldSpaceGC();
   }
 }
diff --git a/runtime/vm/instructions_arm64.cc b/runtime/vm/instructions_arm64.cc
index a08eda0..cbb8667 100644
--- a/runtime/vm/instructions_arm64.cc
+++ b/runtime/vm/instructions_arm64.cc
@@ -170,11 +170,7 @@
   return start;
 }
 
-// Decodes a load sequence ending at 'end' (the last instruction of the load
-// sequence is the instruction before the one at end).  Returns a pointer to
-// the first instruction in the sequence.  Returns the register being loaded
-// and the index in the pool being read from in the output parameters 'reg'
-// and 'index' respectively.
+// See comment in instructions_arm64.h
 uword InstructionPattern::DecodeLoadWordFromPool(uword end,
                                                  Register* reg,
                                                  intptr_t* index) {
@@ -242,6 +238,74 @@
   return start;
 }
 
+// See comment in instructions_arm64.h
+uword InstructionPattern::DecodeLoadDoubleWordFromPool(uword end,
+                                                       Register* reg1,
+                                                       Register* reg2,
+                                                       intptr_t* index) {
+  // Cases:
+  //
+  //   1. ldp reg1, reg2, [pp, offset]
+  //
+  //   2. add tmp, pp, #upper12
+  //      ldp reg1, reg2, [tmp, #lower12]
+  //
+  //   3. add tmp, pp, #upper12
+  //      add tmp, tmp, #lower12
+  //      ldp reg1, reg2, [tmp, 0]
+  //
+  // Note that the pp register is untagged!
+  //
+  uword start = end - Instr::kInstrSize;
+  Instr* ldr_instr = Instr::At(start);
+
+  // Last instruction is always an ldp into two 64-bit X registers.
+  RELEASE_ASSERT(ldr_instr->IsLoadStoreRegPairOp() &&
+                 (ldr_instr->Bit(22) == 1));
+
+  // Grab the destination register from the ldp instruction.
+  *reg1 = ldr_instr->RtField();
+  *reg2 = ldr_instr->Rt2Field();
+
+  Register base_reg = ldr_instr->RnField();
+  const int base_offset = 8 * ldr_instr->Imm7Field();
+
+  intptr_t pool_offset = 0;
+  if (base_reg == PP) {
+    // Case 1.
+    pool_offset = base_offset;
+  } else {
+    // Case 2 & 3.
+    RELEASE_ASSERT(base_reg == TMP);
+
+    pool_offset = base_offset;
+
+    start -= Instr::kInstrSize;
+    Instr* add_instr = Instr::At(start);
+    RELEASE_ASSERT(add_instr->IsAddSubImmOp());
+    RELEASE_ASSERT(add_instr->RdField() == TMP);
+
+    const auto shift = add_instr->Imm12ShiftField();
+    RELEASE_ASSERT(shift == 0 || shift == 1);
+    pool_offset += (add_instr->Imm12Field() << (shift == 1 ? 12 : 0));
+
+    if (add_instr->RnField() == TMP) {
+      start -= Instr::kInstrSize;
+      Instr* prev_add_instr = Instr::At(start);
+      RELEASE_ASSERT(prev_add_instr->IsAddSubImmOp());
+      RELEASE_ASSERT(prev_add_instr->RnField() == PP);
+
+      const auto shift = prev_add_instr->Imm12ShiftField();
+      RELEASE_ASSERT(shift == 0 || shift == 1);
+      pool_offset += (prev_add_instr->Imm12Field() << (shift == 1 ? 12 : 0));
+    } else {
+      RELEASE_ASSERT(add_instr->RnField() == PP);
+    }
+  }
+  *index = ObjectPool::IndexFromOffset(pool_offset - kHeapObjectTag);
+  return start;
+}
+
 bool DecodeLoadObjectFromPoolOrThread(uword pc, const Code& code, Object* obj) {
   ASSERT(code.ContainsInstructionAt(pc));
 
@@ -315,13 +379,15 @@
   // Last instruction: blr ip0.
   ASSERT(*(reinterpret_cast<uint32_t*>(pc) - 1) == 0xd63f0200);
 
-  Register reg;
-  uword data_load_end = InstructionPattern::DecodeLoadWordFromPool(
-      pc - Instr::kInstrSize, &reg, &data_pool_index_);
-  ASSERT(reg == R5);
-  InstructionPattern::DecodeLoadWordFromPool(data_load_end - Instr::kInstrSize,
-                                             &reg, &target_pool_index_);
-  ASSERT(reg == CODE_REG);
+  Register ic_data_reg, code_reg;
+  intptr_t pool_index;
+  InstructionPattern::DecodeLoadDoubleWordFromPool(
+      pc - 2 * Instr::kInstrSize, &ic_data_reg, &code_reg, &pool_index);
+  RELEASE_ASSERT(ic_data_reg == R5);
+  RELEASE_ASSERT(code_reg == CODE_REG);
+
+  data_pool_index_ = pool_index;
+  target_pool_index_ = pool_index + 1;
 }
 
 RawObject* SwitchableCallPattern::data() const {
diff --git a/runtime/vm/instructions_arm64.h b/runtime/vm/instructions_arm64.h
index 1355cfe..5a3936d 100644
--- a/runtime/vm/instructions_arm64.h
+++ b/runtime/vm/instructions_arm64.h
@@ -50,6 +50,20 @@
                                       Register* reg,
                                       intptr_t* index);
 
+  // Decodes a load sequence ending at 'end' (the last instruction of the
+  // load sequence is the instruction before the one at end).  Returns the
+  // address of the first instruction in the sequence.  Returns the registers
+  // being loaded and the index in the pool being read from in the output
+  // parameters 'reg1', 'reg2' and 'index' respectively.
+  // IMPORANT: When generating code loading values from pool on ARM64 use
+  // LoadDoubleWordFromPool macro instruction instead of emitting direct load.
+  // The macro instruction takes care of pool offsets that can't be
+  // encoded as immediates.
+  static uword DecodeLoadDoubleWordFromPool(uword end,
+                                            Register* reg1,
+                                            Register* reg2,
+                                            intptr_t* index);
+
   // Encodes a load sequence ending at 'end'. Encodes a fixed length two
   // instruction load from the pool pointer in PP using the destination
   // register reg as a temporary for the base address.
diff --git a/runtime/vm/instructions_kbc.cc b/runtime/vm/instructions_kbc.cc
new file mode 100644
index 0000000..e33ff4d
--- /dev/null
+++ b/runtime/vm/instructions_kbc.cc
@@ -0,0 +1,35 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+#include "vm/globals.h"
+#if !defined(DART_PRECOMPILED_RUNTIME)
+
+#include "vm/instructions.h"
+#include "vm/instructions_kbc.h"
+
+#include "vm/constants_kbc.h"
+#include "vm/native_entry.h"
+
+namespace dart {
+
+RawTypedData* KBCNativeCallPattern::GetNativeEntryDataAt(uword pc,
+                                                         const Code& bytecode) {
+  ASSERT(bytecode.ContainsInstructionAt(pc));
+  const uword call_pc = pc - sizeof(KBCInstr);
+  KBCInstr call_instr = KernelBytecode::At(call_pc);
+  ASSERT(KernelBytecode::DecodeOpcode(call_instr) ==
+         KernelBytecode::kNativeCall);
+  intptr_t native_entry_data_pool_index = KernelBytecode::DecodeD(call_instr);
+  const ObjectPool& object_pool = ObjectPool::Handle(bytecode.GetObjectPool());
+  TypedData& native_entry_data = TypedData::Handle();
+  native_entry_data ^= object_pool.ObjectAt(native_entry_data_pool_index);
+  // Native calls to recognized functions should never be patched.
+  ASSERT(NativeEntryData(native_entry_data).kind() ==
+         MethodRecognizer::kUnknown);
+  return native_entry_data.raw();
+}
+
+}  // namespace dart
+
+#endif  // !defined(DART_PRECOMPILED_RUNTIME)
diff --git a/runtime/vm/instructions_kbc.h b/runtime/vm/instructions_kbc.h
new file mode 100644
index 0000000..11f56fb
--- /dev/null
+++ b/runtime/vm/instructions_kbc.h
@@ -0,0 +1,25 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Classes that describe assembly patterns as used by inline caches.
+
+#ifndef RUNTIME_VM_INSTRUCTIONS_KBC_H_
+#define RUNTIME_VM_INSTRUCTIONS_KBC_H_
+
+#include "vm/globals.h"
+#if !defined(DART_PRECOMPILED_RUNTIME)
+
+#include "vm/object.h"
+
+namespace dart {
+
+class KBCNativeCallPattern : public AllStatic {
+ public:
+  static RawTypedData* GetNativeEntryDataAt(uword pc, const Code& bytecode);
+};
+
+#endif  // !defined(DART_PRECOMPILED_RUNTIME)
+
+}  // namespace dart
+
+#endif  // RUNTIME_VM_INSTRUCTIONS_KBC_H_
diff --git a/runtime/vm/interpreter.cc b/runtime/vm/interpreter.cc
index a12afa7..9650957 100644
--- a/runtime/vm/interpreter.cc
+++ b/runtime/vm/interpreter.cc
@@ -6,7 +6,7 @@
 #include <stdlib.h>
 
 #include "vm/globals.h"
-#if defined(DART_USE_INTERPRETER)
+#if !defined(DART_PRECOMPILED_RUNTIME) && !defined(TARGET_OS_WINDOWS)
 
 #include "vm/interpreter.h"
 
@@ -193,7 +193,8 @@
     RawSmi* index = static_cast<RawSmi*>(args[1]);
     RawArray* array = static_cast<RawArray*>(args[0]);
     if (CheckIndex(index, array->ptr()->length_)) {
-      array->StorePointer(array->ptr()->data() + Smi::Value(index), args[2]);
+      array->StorePointer(array->ptr()->data() + Smi::Value(index), args[2],
+                          thread);
       return true;
     }
     return false;
@@ -228,7 +229,8 @@
         static_cast<RawGrowableObjectArray*>(args[0]);
     if (CheckIndex(index, array->ptr()->length_)) {
       RawArray* data = array->ptr()->data_;
-      data->StorePointer(data->ptr()->data() + Smi::Value(index), args[2]);
+      data->StorePointer(data->ptr()->data() + Smi::Value(index), args[2],
+                         thread);
       return true;
     }
     return false;
@@ -888,7 +890,7 @@
   UNIMPLEMENTED();
 #endif
   ASSERT(Function::HasCode(function));
-  RawCode* code = function->ptr()->code_;
+  RawCode* volatile code = function->ptr()->code_;
   ASSERT(code != StubCode::LazyCompile_entry()->code());
   // TODO(regis): Once we share the same stack, try to invoke directly.
 #if defined(DEBUG)
@@ -900,9 +902,9 @@
   // On success, returns a RawInstance.  On failure, a RawError.
   typedef RawObject* (*invokestub)(RawCode * code, RawArray * argdesc,
                                    RawObject * *arg0, Thread * thread);
-  invokestub entrypoint = reinterpret_cast<invokestub>(
+  invokestub volatile entrypoint = reinterpret_cast<invokestub>(
       StubCode::InvokeDartCodeFromBytecode_entry()->EntryPoint());
-  RawObject* result;
+  RawObject* volatile result;
   Exit(thread, *FP, call_top + 1, *pc);
   {
     InterpreterSetjmpBuffer buffer(this);
@@ -967,11 +969,13 @@
       RawField* field = reinterpret_cast<RawField*>(function->ptr()->data_);
       intptr_t offset_in_words = Smi::Value(field->ptr()->value_.offset_);
       RawAbstractType* field_type = field->ptr()->type_;
-      const classid_t cid =
-          field_type->GetClassId() == kTypeCid
-              ? Smi::Value(reinterpret_cast<RawSmi*>(
-                    Type::RawCast(field_type)->ptr()->type_class_id_))
-              : kIllegalCid;  // Not really illegal, but not a Type to skip.
+      classid_t cid;
+      if (field_type->GetClassId() == kTypeCid) {
+        cid = Smi::Value(reinterpret_cast<RawSmi*>(
+            Type::RawCast(field_type)->ptr()->type_class_id_));
+      } else {
+        cid = kIllegalCid;  // Not really illegal, but not a Type to skip.
+      }
       // Perform type test of value if field type is not one of dynamic, object,
       // or void, and if the value is not null.
       RawObject* null_value = Object::null();
@@ -1042,7 +1046,7 @@
       }
       instance->StorePointer(
           reinterpret_cast<RawObject**>(instance->ptr()) + offset_in_words,
-          value);
+          value, thread);
       *SP = call_base;
       **SP = null_value;
       *invoked = true;
@@ -1160,6 +1164,9 @@
     case RawFunction::kNoSuchMethodDispatcher:
       // TODO(regis): Implement. For now, use jitted version.
       break;
+    case RawFunction::kDynamicInvocationForwarder:
+      // TODO(regis): Implement. For now, use jitted version.
+      break;
     default:
       break;
   }
@@ -1519,7 +1526,7 @@
                   exit_fp);                                                    \
       }                                                                        \
       ASSERT(reinterpret_cast<uword>(fp_) < stack_limit());                    \
-      return special_[kExceptionSpecialIndex];                                 \
+      return special_[KernelBytecode::kExceptionSpecialIndex];                 \
     }                                                                          \
     goto DispatchAfterException;                                               \
   } while (0)
@@ -1539,7 +1546,7 @@
       thread->set_top_exit_frame_info(exit_fp);                                \
       thread->set_top_resource(top_resource);                                  \
       thread->set_vm_tag(vm_tag);                                              \
-      return special_[kExceptionSpecialIndex];                                 \
+      return special_[KernelBytecode::kExceptionSpecialIndex];                 \
     }                                                                          \
     goto DispatchAfterException;                                               \
   } while (0)
@@ -2269,6 +2276,30 @@
   }
 
   {
+    BYTECODE(PushNull, 0);
+    *++SP = Object::null();
+    DISPATCH();
+  }
+
+  {
+    BYTECODE(PushTrue, 0);
+    *++SP = Object::bool_true().raw();
+    DISPATCH();
+  }
+
+  {
+    BYTECODE(PushFalse, 0);
+    *++SP = Object::bool_false().raw();
+    DISPATCH();
+  }
+
+  {
+    BYTECODE(PushInt, A_X);
+    *++SP = Smi::New(rD);
+    DISPATCH();
+  }
+
+  {
     BYTECODE(Push, A_X);
     *++SP = FP[rD];
     DISPATCH();
@@ -2484,9 +2515,8 @@
 
   {
     BYTECODE(NativeCall, __D);
-    RawNativeEntryData* native_entry =
-        static_cast<RawNativeEntryData*>(LOAD_CONSTANT(rD));
-    MethodRecognizer::Kind kind = native_entry->ptr()->kind_;
+    RawTypedData* data = static_cast<RawTypedData*>(LOAD_CONSTANT(rD));
+    MethodRecognizer::Kind kind = NativeEntryData::GetKind(data);
     switch (kind) {
       case MethodRecognizer::kObjectEquals: {
         SP[-1] = SP[-1] == SP[0] ? Bool::True().raw() : Bool::False().raw();
@@ -2625,9 +2655,9 @@
         *--SP = null_value;
       } break;
       default: {
-        NativeFunctionWrapper trampoline = native_entry->ptr()->trampoline_;
-        NativeFunction function = native_entry->ptr()->native_function_;
-        intptr_t argc_tag = native_entry->ptr()->argc_tag_;
+        NativeFunctionWrapper trampoline = NativeEntryData::GetTrampoline(data);
+        NativeFunction function = NativeEntryData::GetNativeFunction(data);
+        intptr_t argc_tag = NativeEntryData::GetArgcTag(data);
         const intptr_t num_arguments =
             NativeArguments::ArgcBits::decode(argc_tag);
 
@@ -3470,7 +3500,7 @@
     BYTECODE(StoreStaticTOS, A_D);
     RawField* field = reinterpret_cast<RawField*>(LOAD_CONSTANT(rD));
     RawInstance* value = static_cast<RawInstance*>(*SP--);
-    field->StorePointer(&field->ptr()->value_.static_value_, value);
+    field->StorePointer(&field->ptr()->value_.static_value_, value, thread);
     DISPATCH();
   }
 
@@ -3494,8 +3524,8 @@
     ASSERT(!thread->isolate()->use_field_guards());
 
     instance->StorePointer(
-        reinterpret_cast<RawObject**>(instance->ptr()) + offset_in_words,
-        value);
+        reinterpret_cast<RawObject**>(instance->ptr()) + offset_in_words, value,
+        thread);
     DISPATCH();
   }
 
@@ -3509,8 +3539,8 @@
     UNREACHABLE();  // TODO(regis): unused, remove.
 
     instance->StorePointer(
-        reinterpret_cast<RawObject**>(instance->ptr()) + offset_in_words,
-        value);
+        reinterpret_cast<RawObject**>(instance->ptr()) + offset_in_words, value,
+        thread);
     DISPATCH();
   }
 
@@ -3526,8 +3556,8 @@
     ASSERT(!thread->isolate()->use_field_guards());
 
     instance->StorePointer(
-        reinterpret_cast<RawObject**>(instance->ptr()) + offset_in_words,
-        value);
+        reinterpret_cast<RawObject**>(instance->ptr()) + offset_in_words, value,
+        thread);
 
     DISPATCH();
   }
@@ -3542,7 +3572,7 @@
 
     instance->StorePointer(
         reinterpret_cast<RawContext**>(instance->ptr()) + offset_in_words,
-        value);
+        value, thread);
 
     DISPATCH();
   }
@@ -3556,8 +3586,8 @@
     SP -= 2;  // Drop instance and value.
 
     instance->StorePointer(
-        reinterpret_cast<RawObject**>(instance->ptr()) + offset_in_words,
-        value);
+        reinterpret_cast<RawObject**>(instance->ptr()) + offset_in_words, value,
+        thread);
 
     DISPATCH();
   }
@@ -4487,7 +4517,8 @@
     RawSmi* index = RAW_CAST(Smi, SP[2]);
     RawObject* value = SP[3];
     ASSERT(InterpreterHelpers::CheckIndex(index, array->ptr()->length_));
-    array->StorePointer(array->ptr()->data() + Smi::Value(index), value);
+    array->StorePointer(array->ptr()->data() + Smi::Value(index), value,
+                        thread);
     DISPATCH();
   }
 
@@ -4497,7 +4528,8 @@
     RawSmi* index = RAW_CAST(Smi, FP[rB]);
     RawObject* value = FP[rC];
     ASSERT(InterpreterHelpers::CheckIndex(index, array->ptr()->length_));
-    array->StorePointer(array->ptr()->data() + Smi::Value(index), value);
+    array->StorePointer(array->ptr()->data() + Smi::Value(index), value,
+                        thread);
     DISPATCH();
   }
 
@@ -4831,8 +4863,8 @@
     ASSERT(raw_exception != Object::null());
     thread->set_active_exception(Object::null_object());
     thread->set_active_stacktrace(Object::null_object());
-    special_[kExceptionSpecialIndex] = raw_exception;
-    special_[kStackTraceSpecialIndex] = raw_stacktrace;
+    special_[KernelBytecode::kExceptionSpecialIndex] = raw_exception;
+    special_[KernelBytecode::kStackTraceSpecialIndex] = raw_stacktrace;
     pc_ = thread->resume_pc();
   } else {
     pc_ = pc;
@@ -4849,4 +4881,4 @@
 
 }  // namespace dart
 
-#endif  // defined(DART_USE_INTERPRETER)
+#endif  // !defined(DART_PRECOMPILED_RUNTIME) && !defined(TARGET_OS_WINDOWS)
diff --git a/runtime/vm/interpreter.h b/runtime/vm/interpreter.h
index d832205..3d98670 100644
--- a/runtime/vm/interpreter.h
+++ b/runtime/vm/interpreter.h
@@ -6,7 +6,7 @@
 #define RUNTIME_VM_INTERPRETER_H_
 
 #include "vm/globals.h"
-#if defined(DART_USE_INTERPRETER)
+#if !defined(DART_PRECOMPILED_RUNTIME)
 
 #include "vm/compiler/method_recognizer.h"
 #include "vm/constants_kbc.h"
@@ -91,12 +91,6 @@
     return intrinsics_[id] != NULL;
   }
 
-  enum SpecialIndex {
-    kExceptionSpecialIndex,
-    kStackTraceSpecialIndex,
-    kSpecialIndexCount
-  };
-
   void VisitObjectPointers(ObjectPointerVisitor* visitor);
 
  private:
@@ -113,7 +107,7 @@
   RawObjectPool* pp_;  // Pool Pointer.
   RawArray* argdesc_;  // Arguments Descriptor: used to pass information between
                        // call instruction and the function entry.
-  RawObject* special_[kSpecialIndexCount];
+  RawObject* special_[KernelBytecode::kSpecialIndexCount];
 
   static IntrinsicHandler intrinsics_[kIntrinsicCount];
 
@@ -221,6 +215,6 @@
 
 }  // namespace dart
 
-#endif  // defined(DART_USE_INTERPRETER)
+#endif  // !defined(DART_PRECOMPILED_RUNTIME)
 
 #endif  // RUNTIME_VM_INTERPRETER_H_
diff --git a/runtime/vm/interpreter_unsupported.cc b/runtime/vm/interpreter_unsupported.cc
new file mode 100644
index 0000000..b12ba4e
--- /dev/null
+++ b/runtime/vm/interpreter_unsupported.cc
@@ -0,0 +1,185 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+#include "vm/globals.h"
+#if !defined(DART_PRECOMPILED_RUNTIME) && defined(TARGET_OS_WINDOWS)
+
+#include "vm/interpreter.h"
+
+#include "platform/assert.h"
+#include "vm/object.h"
+
+namespace dart {
+
+IntrinsicHandler Interpreter::intrinsics_[Interpreter::kIntrinsicCount];
+
+void Interpreter::InitOnce() {
+  UNIMPLEMENTED();
+}
+
+Interpreter::Interpreter() {
+  UNIMPLEMENTED();
+}
+
+Interpreter::~Interpreter() {
+  UNIMPLEMENTED();
+}
+
+Interpreter* Interpreter::Current() {
+  UNIMPLEMENTED();
+  return NULL;
+}
+
+#if defined(DEBUG)
+bool Interpreter::IsTracingExecution() const {
+  UNIMPLEMENTED();
+  return false;
+}
+
+void Interpreter::TraceInstruction(uint32_t* pc) const {
+  UNIMPLEMENTED();
+}
+#endif  // defined(DEBUG)
+
+void Interpreter::Exit(Thread* thread,
+                       RawObject** base,
+                       RawObject** frame,
+                       uint32_t* pc) {
+  UNIMPLEMENTED();
+}
+
+void Interpreter::CallRuntime(Thread* thread,
+                              RawObject** base,
+                              RawObject** exit_frame,
+                              uint32_t* pc,
+                              intptr_t argc_tag,
+                              RawObject** args,
+                              RawObject** result,
+                              uword target) {
+  UNIMPLEMENTED();
+}
+
+bool Interpreter::InvokeCompiled(Thread* thread,
+                                 RawFunction* function,
+                                 RawObject** call_base,
+                                 RawObject** call_top,
+                                 uint32_t** pc,
+                                 RawObject*** FP,
+                                 RawObject*** SP) {
+  UNIMPLEMENTED();
+  return false;
+}
+
+bool Interpreter::ProcessInvocation(bool* invoked,
+                                    Thread* thread,
+                                    RawFunction* function,
+                                    RawObject** call_base,
+                                    RawObject** call_top,
+                                    uint32_t** pc,
+                                    RawObject*** FP,
+                                    RawObject*** SP) {
+  UNIMPLEMENTED();
+  return false;
+}
+
+bool Interpreter::Invoke(Thread* thread,
+                         RawObject** call_base,
+                         RawObject** call_top,
+                         uint32_t** pc,
+                         RawObject*** FP,
+                         RawObject*** SP) {
+  UNIMPLEMENTED();
+  return false;
+}
+
+void Interpreter::InlineCacheMiss(int checked_args,
+                                  Thread* thread,
+                                  RawICData* icdata,
+                                  RawObject** args,
+                                  RawObject** top,
+                                  uint32_t* pc,
+                                  RawObject** FP,
+                                  RawObject** SP) {
+  UNIMPLEMENTED();
+}
+
+bool Interpreter::InstanceCall1(Thread* thread,
+                                RawICData* icdata,
+                                RawObject** call_base,
+                                RawObject** top,
+                                uint32_t** pc,
+                                RawObject*** FP,
+                                RawObject*** SP,
+                                bool optimized) {
+  UNIMPLEMENTED();
+  return false;
+}
+
+bool Interpreter::InstanceCall2(Thread* thread,
+                                RawICData* icdata,
+                                RawObject** call_base,
+                                RawObject** top,
+                                uint32_t** pc,
+                                RawObject*** FP,
+                                RawObject*** SP,
+                                bool optimized) {
+  UNIMPLEMENTED();
+  return false;
+}
+
+void Interpreter::PrepareForTailCall(RawCode* code,
+                                     RawImmutableArray* args_desc,
+                                     RawObject** FP,
+                                     RawObject*** SP,
+                                     uint32_t** pc) {
+  UNIMPLEMENTED();
+}
+
+bool Interpreter::Deoptimize(Thread* thread,
+                             uint32_t** pc,
+                             RawObject*** FP,
+                             RawObject*** SP,
+                             bool is_lazy) {
+  UNIMPLEMENTED();
+  return false;
+}
+
+bool Interpreter::AssertAssignable(Thread* thread,
+                                   uint32_t* pc,
+                                   RawObject** FP,
+                                   RawObject** call_top,
+                                   RawObject** args,
+                                   RawSubtypeTestCache* cache) {
+  UNIMPLEMENTED();
+  return false;
+}
+
+RawObject* Interpreter::Call(const Function& function,
+                             const Array& arguments_descriptor,
+                             const Array& arguments,
+                             Thread* thread) {
+  UNIMPLEMENTED();
+  return NULL;
+}
+
+RawObject* Interpreter::Call(RawFunction* function,
+                             RawArray* argdesc,
+                             intptr_t argc,
+                             RawObject* const* argv,
+                             Thread* thread) {
+  UNIMPLEMENTED();
+  return NULL;
+}
+
+void Interpreter::JumpToFrame(uword pc, uword sp, uword fp, Thread* thread) {
+  UNIMPLEMENTED();
+}
+
+void Interpreter::VisitObjectPointers(ObjectPointerVisitor* visitor) {
+  UNIMPLEMENTED();
+}
+
+}  // namespace dart
+
+#endif  // !defined(DART_PRECOMPILED_RUNTIME) && defined(TARGET_OS_WINDOWS)
diff --git a/runtime/vm/isolate.cc b/runtime/vm/isolate.cc
index e31589f..1c155bd 100644
--- a/runtime/vm/isolate.cc
+++ b/runtime/vm/isolate.cc
@@ -911,7 +911,9 @@
       library_tag_handler_(NULL),
       api_state_(NULL),
       random_(),
+#if !defined(DART_PRECOMPILED_RUNTIME)
       interpreter_(NULL),
+#endif
       simulator_(NULL),
       mutex_(new Mutex(NOT_IN_PRODUCT("Isolate::mutex_"))),
       symbols_mutex_(new Mutex(NOT_IN_PRODUCT("Isolate::symbols_mutex_"))),
@@ -939,7 +941,7 @@
       spawn_count_monitor_(new Monitor()),
       spawn_count_(0),
       handler_info_cache_(),
-      catch_entry_state_cache_(),
+      catch_entry_moves_cache_(),
       embedder_entry_points_(NULL),
       obfuscation_map_(NULL) {
   FlagsCopyFrom(api_flags);
@@ -988,7 +990,7 @@
   delete heap_;
   delete object_store_;
   delete api_state_;
-#if defined(DART_USE_INTERPRETER)
+#if !defined(DART_PRECOMPILED_RUNTIME)
   delete interpreter_;
 #endif
 #if defined(USING_SIMULATOR)
@@ -1081,6 +1083,12 @@
   if (!Thread::EnterIsolate(result)) {
     // We failed to enter the isolate, it is possible the VM is shutting down,
     // return back a NULL so that CreateIsolate reports back an error.
+    if (KernelIsolate::IsKernelIsolate(result)) {
+      KernelIsolate::SetKernelIsolate(NULL);
+    }
+    if (ServiceIsolate::IsServiceIsolate(result)) {
+      ServiceIsolate::SetServiceIsolate(NULL);
+    }
     delete result;
     return NULL;
   }
@@ -1980,11 +1988,11 @@
   }
 #endif  // !defined(DART_PRECOMPILED_RUNTIME)
 
-#if defined(DART_USE_INTERPRETER)
+#if !defined(DART_PRECOMPILED_RUNTIME)
   if (interpreter() != NULL) {
     interpreter()->VisitObjectPointers(visitor);
   }
-#endif  // defined(DART_USE_INTERPRETER)
+#endif
 
 #if defined(TARGET_ARCH_DBC)
   if (simulator() != NULL) {
@@ -2763,6 +2771,8 @@
     thread = thread_registry()->GetFreeThreadLocked(this, is_mutator);
     ASSERT(thread != NULL);
 
+    thread->ResetHighWatermark();
+
     // Set up other values and set the TLS value.
     thread->isolate_ = this;
     ASSERT(heap() != NULL);
@@ -2784,8 +2794,6 @@
     }
     Thread::SetCurrent(thread);
     os_thread->EnableThreadInterrupts();
-
-    thread->ResetHighWatermark();
   }
   return thread;
 }
diff --git a/runtime/vm/isolate.h b/runtime/vm/isolate.h
index f8f7835..07e6197 100644
--- a/runtime/vm/isolate.h
+++ b/runtime/vm/isolate.h
@@ -39,7 +39,9 @@
 class HandleVisitor;
 class Heap;
 class ICData;
+#if !defined(DART_PRECOMPILED_RUNTIME)
 class Interpreter;
+#endif
 class IsolateProfilerData;
 class IsolateReloadContext;
 class IsolateSpawnState;
@@ -128,7 +130,7 @@
 // Fixed cache for exception handler lookup.
 typedef FixedCache<intptr_t, ExceptionHandlerInfo, 16> HandlerInfoCache;
 // Fixed cache for catch entry state lookup.
-typedef FixedCache<intptr_t, CatchEntryState, 16> CatchEntryStateCache;
+typedef FixedCache<intptr_t, CatchEntryMovesRefPtr, 16> CatchEntryMovesCache;
 
 // List of Isolate flags with corresponding members of Dart_IsolateFlags and
 // corresponding global command line flags.
@@ -139,10 +141,6 @@
   V(NONPRODUCT, type_checks, EnableTypeChecks, enable_type_checks,             \
     FLAG_enable_type_checks)                                                   \
   V(NONPRODUCT, asserts, EnableAsserts, enable_asserts, FLAG_enable_asserts)   \
-  V(PRODUCT, reify_generic_functions, ReifyGenericFunctions,                   \
-    reify_generic_functions, FLAG_reify_generic_functions)                     \
-  V(PRODUCT, sync_async, SyncAsync, sync_async, FLAG_sync_async)               \
-  V(PRODUCT, strong, Strong, strong, FLAG_strong)                              \
   V(NONPRODUCT, error_on_bad_type, ErrorOnBadType, enable_error_on_bad_type,   \
     FLAG_error_on_bad_type)                                                    \
   V(NONPRODUCT, error_on_bad_override, ErrorOnBadOverride,                     \
@@ -409,8 +407,10 @@
 
   Random* random() { return &random_; }
 
+#if !defined(DART_PRECOMPILED_RUNTIME)
   Interpreter* interpreter() const { return interpreter_; }
   void set_interpreter(Interpreter* value) { interpreter_ = value; }
+#endif
 
   Simulator* simulator() const { return simulator_; }
   void set_simulator(Simulator* value) { simulator_ = value; }
@@ -701,7 +701,7 @@
   }
 
   bool can_use_strong_mode_types() const {
-    return strong() && FLAG_use_strong_mode_types &&
+    return FLAG_strong && FLAG_use_strong_mode_types &&
            !unsafe_trust_strong_mode_types();
   }
 
@@ -765,7 +765,7 @@
   }
 
   bool should_emit_strong_mode_checks() const {
-    return strong() && !unsafe_trust_strong_mode_types();
+    return FLAG_strong && !unsafe_trust_strong_mode_types();
   }
 
   static void KillAllIsolates(LibMsgId msg_id);
@@ -784,8 +784,8 @@
 
   HandlerInfoCache* handler_info_cache() { return &handler_info_cache_; }
 
-  CatchEntryStateCache* catch_entry_state_cache() {
-    return &catch_entry_state_cache_;
+  CatchEntryMovesCache* catch_entry_moves_cache() {
+    return &catch_entry_moves_cache_;
   }
 
   void MaybeIncreaseReloadEveryNStackOverflowChecks();
@@ -880,9 +880,6 @@
   V(EnableAsserts)                                                             \
   V(ErrorOnBadType)                                                            \
   V(ErrorOnBadOverride)                                                        \
-  V(ReifyGenericFunctions)                                                     \
-  V(SyncAsync)                                                                 \
-  V(Strong)                                                                    \
   V(UseFieldGuards)                                                            \
   V(UseOsr)                                                                    \
   V(Obfuscate)                                                                 \
@@ -973,7 +970,9 @@
   Dart_LibraryTagHandler library_tag_handler_;
   ApiState* api_state_;
   Random random_;
+#if !defined(DART_PRECOMPILED_RUNTIME)
   Interpreter* interpreter_;
+#endif
   Simulator* simulator_;
   Mutex* mutex_;          // Protects compiler stats.
   Mutex* symbols_mutex_;  // Protects concurrent access to the symbol table.
@@ -1018,7 +1017,7 @@
   intptr_t spawn_count_;
 
   HandlerInfoCache handler_info_cache_;
-  CatchEntryStateCache catch_entry_state_cache_;
+  CatchEntryMovesCache catch_entry_moves_cache_;
 
   Dart_QualifiedFunctionName* embedder_entry_points_;
   const char** obfuscation_map_;
diff --git a/runtime/vm/isolate_reload.cc b/runtime/vm/isolate_reload.cc
index d138b12..4b784f1 100644
--- a/runtime/vm/isolate_reload.cc
+++ b/runtime/vm/isolate_reload.cc
@@ -7,6 +7,9 @@
 #include "vm/bit_vector.h"
 #include "vm/compiler/jit/compiler.h"
 #include "vm/dart_api_impl.h"
+#if !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
+#include "vm/hash.h"
+#endif
 #include "vm/hash_table.h"
 #include "vm/heap/become.h"
 #include "vm/heap/safepoint.h"
@@ -50,6 +53,8 @@
             false,
             "Assert that an isolate has reloaded at least once.")
 
+DECLARE_FLAG(bool, trace_deoptimization);
+
 #define I (isolate())
 #define Z (thread->zone())
 
@@ -328,7 +333,15 @@
   }
 
   static uword Hash(const Object& obj) {
-    return String::HashRawSymbol(Class::Cast(obj).Name());
+    uword class_name_hash = String::HashRawSymbol(Class::Cast(obj).Name());
+    RawLibrary* raw_library = Class::Cast(obj).library();
+    if (raw_library == Library::null()) {
+      return class_name_hash;
+    }
+    return FinalizeHash(
+        CombineHashes(class_name_hash,
+                      String::Hash(Library::Handle(raw_library).private_key())),
+        /* hashbits= */ 30);
   }
 };
 
@@ -896,7 +909,9 @@
     if (frame->IsDartFrame()) {
       func = frame->LookupDartFunction();
       ASSERT(!func.IsNull());
-      func.EnsureHasCompiledUnoptimizedCode();
+      if (!frame->is_interpreted()) {
+        func.EnsureHasCompiledUnoptimizedCode();
+      }
     }
   }
 }
@@ -1938,6 +1953,9 @@
 void IsolateReloadContext::InvalidateWorld() {
   TIR_Print("---- INVALIDATING WORLD\n");
   ResetMegamorphicCaches();
+  if (FLAG_trace_deoptimization) {
+    THR_Print("Deopt for reload\n");
+  }
   DeoptimizeFunctionsOnStack();
   ResetUnoptimizedICsOnStack();
   MarkAllFunctionsForRecompilation();
diff --git a/runtime/vm/isolate_reload_test.cc b/runtime/vm/isolate_reload_test.cc
index 171292f..2b0594e 100644
--- a/runtime/vm/isolate_reload_test.cc
+++ b/runtime/vm/isolate_reload_test.cc
@@ -1633,7 +1633,7 @@
         "Tried calling: C.foo()\n"
         "Found: C.foo(dynamic) => dynamic\n"
         "#0      Object.noSuchMethod "
-        "(dart:core/runtime/libobject_patch.dart:48:5)\n"
+        "(dart:core/runtime/libobject_patch.dart:50:5)\n"
         "#1      main (file:///test-lib:8:12)";
   } else {
     error =
@@ -1643,7 +1643,7 @@
         "Tried calling: C.foo()\n"
         "Found: C.foo(dynamic) => dynamic\n"
         "#0      Object.noSuchMethod "
-        "(dart:core-patch/dart:core/object_patch.dart:48)\n"
+        "(dart:core-patch/dart:core/object_patch.dart:50)\n"
         "#1      main (test-lib:8:12)";
   }
   EXPECT_ERROR(error_handle, error);
diff --git a/runtime/vm/kernel.cc b/runtime/vm/kernel.cc
index b3e05e6..7bbc8f8 100644
--- a/runtime/vm/kernel.cc
+++ b/runtime/vm/kernel.cc
@@ -593,7 +593,7 @@
 }
 
 bool NeedsDynamicInvocationForwarder(const Function& function) {
-  ASSERT(Isolate::Current()->strong());
+  ASSERT(FLAG_strong);
 
   Thread* thread = Thread::Current();
   Zone* zone = thread->zone();
diff --git a/runtime/vm/kernel_binary.h b/runtime/vm/kernel_binary.h
index 1580817..2ffb315 100644
--- a/runtime/vm/kernel_binary.h
+++ b/runtime/vm/kernel_binary.h
@@ -17,7 +17,7 @@
 // package:kernel/binary.md.
 
 static const uint32_t kMagicProgramFile = 0x90ABCDEFu;
-static const uint32_t kBinaryFormatVersion = 11;
+static const uint32_t kBinaryFormatVersion = 12;
 
 // Keep in sync with package:kernel/lib/binary/tag.dart
 #define KERNEL_TAG_LIST(V)                                                     \
@@ -138,12 +138,13 @@
   kIntConstant = 2,
   kDoubleConstant = 3,
   kStringConstant = 4,
-  kMapConstant = 5,
-  kListConstant = 6,
-  kInstanceConstant = 7,
-  kPartialInstantiationConstant = 8,
-  kTearOffConstant = 9,
-  kTypeLiteralConstant = 10,
+  kSymbolConstant = 5,
+  kMapConstant = 6,
+  kListConstant = 7,
+  kInstanceConstant = 8,
+  kPartialInstantiationConstant = 9,
+  kTearOffConstant = 10,
+  kTypeLiteralConstant = 11,
 };
 
 static const int SpecializedIntLiteralBias = 3;
diff --git a/runtime/vm/kernel_isolate.cc b/runtime/vm/kernel_isolate.cc
index 5a85178..7a132b5 100644
--- a/runtime/vm/kernel_isolate.cc
+++ b/runtime/vm/kernel_isolate.cc
@@ -93,12 +93,8 @@
     api_flags.enable_error_on_bad_type = false;
     api_flags.enable_error_on_bad_override = false;
     api_flags.use_dart_frontend = true;
-    api_flags.reify_generic_functions = true;
-    api_flags.strong = true;
     api_flags.unsafe_trust_strong_mode_types = false;
-    api_flags.sync_async = true;
-#if !defined(DART_PRECOMPILER) && !defined(TARGET_ARCH_DBC) &&                 \
-    !defined(DART_USE_INTERPRETER)
+#if !defined(DART_PRECOMPILER) && !defined(TARGET_ARCH_DBC)
     api_flags.use_field_guards = true;
 #endif
 #if !defined(DART_PRECOMPILER)
@@ -178,9 +174,6 @@
     if (FLAG_trace_kernel) {
       OS::PrintErr(DART_KERNEL_ISOLATE_NAME ": Shutdown.\n");
     }
-    // This should be the last line so the check
-    // IsKernelIsolate works during the shutdown process.
-    KernelIsolate::SetKernelIsolate(NULL);
   }
 
   bool RunMain(Isolate* I) {
@@ -452,7 +445,7 @@
 
     Dart_CObject dart_sync_async;
     dart_sync_async.type = Dart_CObject_kBool;
-    dart_sync_async.value.as_bool = isolate->sync_async();
+    dart_sync_async.value.as_bool = FLAG_sync_async;
 
     Dart_CObject* message_arr[] = {&tag,
                                    &send_port,
@@ -572,7 +565,7 @@
 
     Dart_CObject dart_sync_async;
     dart_sync_async.type = Dart_CObject_kBool;
-    dart_sync_async.value.as_bool = isolate->sync_async();
+    dart_sync_async.value.as_bool = FLAG_sync_async;
 
     Dart_CObject package_config_uri;
     if (package_config != NULL) {
diff --git a/runtime/vm/kernel_loader.cc b/runtime/vm/kernel_loader.cc
index a7dd4cd..8440522 100644
--- a/runtime/vm/kernel_loader.cc
+++ b/runtime/vm/kernel_loader.cc
@@ -182,6 +182,7 @@
       external_name_class_(Class::Handle(Z)),
       external_name_field_(Field::Handle(Z)),
       potential_natives_(GrowableObjectArray::Handle(Z)),
+      potential_pragma_functions_(GrowableObjectArray::Handle(Z)),
       potential_extension_libraries_(GrowableObjectArray::Handle(Z)),
       pragma_class_(Class::Handle(Z)),
       expression_evaluation_library_(Library::Handle(Z)),
@@ -345,6 +346,7 @@
       external_name_class_(Class::Handle(Z)),
       external_name_field_(Field::Handle(Z)),
       potential_natives_(GrowableObjectArray::Handle(Z)),
+      potential_pragma_functions_(GrowableObjectArray::Handle(Z)),
       potential_extension_libraries_(GrowableObjectArray::Handle(Z)),
       pragma_class_(Class::Handle(Z)),
       expression_evaluation_library_(Library::Handle(Z)),
@@ -381,6 +383,27 @@
   return helper.ReadConstantTable();
 }
 
+void KernelLoader::EvaluateDelayedPragmas() {
+  if (potential_pragma_functions_.IsNull()) return;
+  Thread* thread = Thread::Current();
+  NoOOBMessageScope no_msg_scope(thread);
+  NoReloadScope no_reload_scope(thread->isolate(), thread);
+
+  Function& function = Function::Handle();
+  Library& library = Library::Handle();
+  Class& klass = Class::Handle();
+  for (int i = 0; i < potential_pragma_functions_.Length(); ++i) {
+    function ^= potential_pragma_functions_.At(i);
+    klass = function.Owner();
+    library = klass.library();
+    library.GetMetadata(function);
+  }
+
+  potential_pragma_functions_ = GrowableObjectArray::null();
+  kernel_program_info_.set_potential_pragma_functions(
+      GrowableObjectArray::Handle(Z));
+}
+
 void KernelLoader::AnnotateNativeProcedures(const Array& constant_table_array) {
   KernelConstantsMap constant_table(constant_table_array.raw());
   potential_natives_ = kernel_program_info_.potential_natives();
@@ -603,6 +626,8 @@
     kernel_program_info_.set_constants(constants);
     kernel_program_info_.set_constants_table(ExternalTypedData::Handle(Z));
 
+    EvaluateDelayedPragmas();
+
     NameIndex main = program_->main_method();
     if (main == -1) {
       return Library::null();
@@ -1526,6 +1551,7 @@
         uint8_t tag = helper_.ReadTag();
         if (tag == kInstanceConstant) {
           *has_pragma_annotation =
+              *has_pragma_annotation ||
               IsClassName(helper_.ReadCanonicalNameReference(),
                           Symbols::DartCore(), Symbols::Pragma());
         }
@@ -1680,6 +1706,18 @@
     library.AddFunctionMetadata(function, TokenPosition::kNoSource,
                                 procedure_offset);
   }
+
+  if (has_pragma_annotation) {
+    if (kernel_program_info_.constants() == Array::null()) {
+      EnsurePotentialPragmaFunctions();
+      potential_pragma_functions_.Add(function);
+    } else {
+      Thread* thread = Thread::Current();
+      NoOOBMessageScope no_msg_scope(thread);
+      NoReloadScope no_reload_scope(thread->isolate(), thread);
+      library.GetMetadata(function);
+    }
+  }
 }
 
 const Object& KernelLoader::ClassForScriptAt(const Class& klass,
diff --git a/runtime/vm/kernel_loader.h b/runtime/vm/kernel_loader.h
index 4f573f8..f17681b 100644
--- a/runtime/vm/kernel_loader.h
+++ b/runtime/vm/kernel_loader.h
@@ -165,6 +165,7 @@
 
   void AnnotateNativeProcedures(const Array& constant_table);
   void LoadNativeExtensionLibraries(const Array& constant_table);
+  void EvaluateDelayedPragmas();
 
   void ReadVMAnnotations(intptr_t annotation_count,
                          String* native_name,
@@ -299,6 +300,18 @@
     }
   }
 
+  void EnsurePotentialPragmaFunctions() {
+    potential_pragma_functions_ =
+        kernel_program_info_.potential_pragma_functions();
+    if (potential_pragma_functions_.IsNull()) {
+      // To avoid too many grows in this array, we'll set it's initial size to
+      // something close to the actual number of potential native functions.
+      potential_pragma_functions_ = GrowableObjectArray::New(100, Heap::kNew);
+      kernel_program_info_.set_potential_pragma_functions(
+          potential_pragma_functions_);
+    }
+  }
+
   void EnsurePotentialExtensionLibraries() {
     if (potential_extension_libraries_.IsNull()) {
       potential_extension_libraries_ = GrowableObjectArray::New();
@@ -331,6 +344,7 @@
   Class& external_name_class_;
   Field& external_name_field_;
   GrowableObjectArray& potential_natives_;
+  GrowableObjectArray& potential_pragma_functions_;
   GrowableObjectArray& potential_extension_libraries_;
 
   Class& pragma_class_;
diff --git a/runtime/vm/mixin_test.cc b/runtime/vm/mixin_test.cc
index 04556da..0a10a17 100644
--- a/runtime/vm/mixin_test.cc
+++ b/runtime/vm/mixin_test.cc
@@ -84,11 +84,10 @@
     }};
   // clang-format on
 
-  Isolate* isolate = Isolate::Current();
   Dart_Handle lib = TestCase::LoadTestScriptWithDFE(
       sizeof(sourcefiles) / sizeof(Dart_SourceFile), sourcefiles,
       /* resolver= */ NULL, /* finalize= */ true, /* incrementally= */ true);
-  if (isolate->strong()) {
+  if (FLAG_strong) {
     EXPECT_ERROR(lib, "Error: Superclass has no method named '_bar'.");
   } else {
     EXPECT_VALID(lib);
diff --git a/runtime/vm/native_arguments.h b/runtime/vm/native_arguments.h
index 782fc6e..5b06627 100644
--- a/runtime/vm/native_arguments.h
+++ b/runtime/vm/native_arguments.h
@@ -182,7 +182,7 @@
     if (function.IsClosureFunction()) {
       function_bits |= kClosureFunctionBit;
     }
-    if (function.IsGeneric() && Isolate::Current()->reify_generic_functions()) {
+    if (function.IsGeneric() && FLAG_reify_generic_functions) {
       function_bits |= kGenericFunctionBit;
       argc++;
     }
@@ -213,10 +213,8 @@
   friend class Api;
   friend class BootstrapNatives;
   friend class Interpreter;
-  friend class NativeEntryData;
   friend class Simulator;
 
-#if defined(TARGET_ARCH_DBC) || defined(DART_USE_INTERPRETER)
   // Allow simulator and interpreter to create NativeArguments in reverse order
   // on the stack.
   NativeArguments(Thread* thread,
@@ -227,7 +225,6 @@
         argc_tag_(ReverseArgOrderBit::update(true, argc_tag)),
         argv_(argv),
         retval_(retval) {}
-#endif
 
   // Since this function is passed a RawObject directly, we need to be
   // exceedingly careful when we use it.  If there are any other side
diff --git a/runtime/vm/native_entry.cc b/runtime/vm/native_entry.cc
index 648d734..ee23b12 100644
--- a/runtime/vm/native_entry.cc
+++ b/runtime/vm/native_entry.cc
@@ -103,7 +103,6 @@
   UNREACHABLE();
 }
 
-#if defined(TARGET_ARCH_DBC) || defined(DART_USE_INTERPRETER)
 uword NativeEntry::BootstrapNativeCallWrapperEntry() {
   uword entry =
       reinterpret_cast<uword>(NativeEntry::BootstrapNativeCallWrapper);
@@ -114,7 +113,6 @@
                                              Dart_NativeFunction func) {
   func(args);
 }
-#endif
 
 uword NativeEntry::NoScopeNativeCallWrapperEntry() {
   uword entry = reinterpret_cast<uword>(NativeEntry::NoScopeNativeCallWrapper);
@@ -283,8 +281,21 @@
     ASSERT(target_function != NULL);
 
 #if defined(DEBUG) && !defined(TARGET_ARCH_DBC)
-    {
-      NativeFunction current_function = NULL;
+    NativeFunction current_function = NULL;
+    if (caller_frame->is_interpreted()) {
+#if !defined(DART_PRECOMPILED_RUNTIME)
+      ASSERT(FLAG_enable_interpreter);
+      NativeFunctionWrapper current_trampoline = KBCPatcher::GetNativeCallAt(
+          caller_frame->pc(), code, &current_function);
+      ASSERT(current_function ==
+             reinterpret_cast<NativeFunction>(LinkNativeCall));
+      ASSERT(current_trampoline == &BootstrapNativeCallWrapper ||
+             current_trampoline == &AutoScopeNativeCallWrapper ||
+             current_trampoline == &NoScopeNativeCallWrapper);
+#else
+      UNREACHABLE();
+#endif  // !defined(DART_PRECOMPILED_RUNTIME)
+    } else {
       const Code& current_trampoline =
           Code::Handle(zone, CodePatcher::GetNativeCallAt(
                                  caller_frame->pc(), code, &current_function));
@@ -313,25 +324,44 @@
     } else {
       trampoline = &NoScopeNativeCallWrapper;
     }
-#else
-    Code& trampoline = Code::Handle(zone);
-    if (is_bootstrap_native) {
-      trampoline = StubCode::CallBootstrapNative_entry()->code();
-#if defined(USING_SIMULATOR)
-      patch_target_function =
-          reinterpret_cast<NativeFunction>(Simulator::RedirectExternalReference(
-              reinterpret_cast<uword>(patch_target_function),
-              Simulator::kBootstrapNativeCall, NativeEntry::kNumArguments));
-#endif
-    } else if (is_auto_scope) {
-      trampoline = StubCode::CallAutoScopeNative_entry()->code();
-    } else {
-      trampoline = StubCode::CallNoScopeNative_entry()->code();
-    }
-#endif
-
     CodePatcher::PatchNativeCallAt(caller_frame->pc(), code,
                                    patch_target_function, trampoline);
+#else
+    if (caller_frame->is_interpreted()) {
+#if !defined(DART_PRECOMPILED_RUNTIME)
+      ASSERT(FLAG_enable_interpreter);
+      NativeFunctionWrapper trampoline;
+      if (is_bootstrap_native) {
+        trampoline = &BootstrapNativeCallWrapper;
+      } else if (is_auto_scope) {
+        trampoline = &AutoScopeNativeCallWrapper;
+      } else {
+        trampoline = &NoScopeNativeCallWrapper;
+      }
+      KBCPatcher::PatchNativeCallAt(caller_frame->pc(), code,
+                                    patch_target_function, trampoline);
+#else
+      UNREACHABLE();
+#endif  // !defined(DART_PRECOMPILED_RUNTIME)
+    } else {
+      Code& trampoline = Code::Handle(zone);
+      if (is_bootstrap_native) {
+        trampoline = StubCode::CallBootstrapNative_entry()->code();
+#if defined(USING_SIMULATOR)
+        patch_target_function = reinterpret_cast<NativeFunction>(
+            Simulator::RedirectExternalReference(
+                reinterpret_cast<uword>(patch_target_function),
+                Simulator::kBootstrapNativeCall, NativeEntry::kNumArguments));
+#endif  // defined USING_SIMULATOR
+      } else if (is_auto_scope) {
+        trampoline = StubCode::CallAutoScopeNative_entry()->code();
+      } else {
+        trampoline = StubCode::CallNoScopeNative_entry()->code();
+      }
+      CodePatcher::PatchNativeCallAt(caller_frame->pc(), code,
+                                     patch_target_function, trampoline);
+    }
+#endif  // defined TARGET_ARCH_DBC
 
     if (FLAG_trace_natives) {
       THR_Print("    -> %p (%s)\n", target_function,
@@ -356,4 +386,75 @@
   }
 }
 
+#if !defined(DART_PRECOMPILED_RUNTIME)
+
+// Note: not GC safe. Use with care.
+NativeEntryData::Payload* NativeEntryData::FromTypedArray(RawTypedData* data) {
+  return reinterpret_cast<Payload*>(data->ptr()->data());
+}
+
+MethodRecognizer::Kind NativeEntryData::kind() const {
+  return FromTypedArray(data_.raw())->kind;
+}
+
+void NativeEntryData::set_kind(MethodRecognizer::Kind value) const {
+  FromTypedArray(data_.raw())->kind = value;
+}
+
+MethodRecognizer::Kind NativeEntryData::GetKind(RawTypedData* data) {
+  return FromTypedArray(data)->kind;
+}
+
+NativeFunctionWrapper NativeEntryData::trampoline() const {
+  return FromTypedArray(data_.raw())->trampoline;
+}
+
+void NativeEntryData::set_trampoline(NativeFunctionWrapper value) const {
+  FromTypedArray(data_.raw())->trampoline = value;
+}
+
+NativeFunctionWrapper NativeEntryData::GetTrampoline(RawTypedData* data) {
+  return FromTypedArray(data)->trampoline;
+}
+
+NativeFunction NativeEntryData::native_function() const {
+  return FromTypedArray(data_.raw())->native_function;
+}
+
+void NativeEntryData::set_native_function(NativeFunction value) const {
+  FromTypedArray(data_.raw())->native_function = value;
+}
+
+NativeFunction NativeEntryData::GetNativeFunction(RawTypedData* data) {
+  return FromTypedArray(data)->native_function;
+}
+
+intptr_t NativeEntryData::argc_tag() const {
+  return FromTypedArray(data_.raw())->argc_tag;
+}
+
+void NativeEntryData::set_argc_tag(intptr_t value) const {
+  FromTypedArray(data_.raw())->argc_tag = value;
+}
+
+intptr_t NativeEntryData::GetArgcTag(RawTypedData* data) {
+  return FromTypedArray(data)->argc_tag;
+}
+
+RawTypedData* NativeEntryData::New(MethodRecognizer::Kind kind,
+                                   NativeFunctionWrapper trampoline,
+                                   NativeFunction native_function,
+                                   intptr_t argc_tag) {
+  const TypedData& data = TypedData::Handle(
+      TypedData::New(kTypedDataUint8ArrayCid, sizeof(Payload), Heap::kOld));
+  NativeEntryData native_entry(data);
+  native_entry.set_kind(kind);
+  native_entry.set_trampoline(trampoline);
+  native_entry.set_native_function(native_function);
+  native_entry.set_argc_tag(argc_tag);
+  return data.raw();
+}
+
+#endif  // !defined(DART_PRECOMPILED_RUNTIME)
+
 }  // namespace dart
diff --git a/runtime/vm/native_entry.h b/runtime/vm/native_entry.h
index 6c1e5ef..2b4ebb0 100644
--- a/runtime/vm/native_entry.h
+++ b/runtime/vm/native_entry.h
@@ -129,11 +129,9 @@
                                                uword pc);
   static const uint8_t* ResolveSymbol(uword pc);
 
-#if defined(TARGET_ARCH_DBC) || defined(DART_USE_INTERPRETER)
   static uword BootstrapNativeCallWrapperEntry();
   static void BootstrapNativeCallWrapper(Dart_NativeArguments args,
                                          Dart_NativeFunction func);
-#endif
 
   static uword NoScopeNativeCallWrapperEntry();
   static void NoScopeNativeCallWrapper(Dart_NativeArguments args,
@@ -156,6 +154,49 @@
   static void PropagateErrors(NativeArguments* arguments);
 };
 
+#if !defined(DART_PRECOMPILED_RUNTIME)
+
+class NativeEntryData : public ValueObject {
+ public:
+  explicit NativeEntryData(const TypedData& data) : data_(data) {}
+
+  MethodRecognizer::Kind kind() const;
+  void set_kind(MethodRecognizer::Kind value) const;
+  static MethodRecognizer::Kind GetKind(RawTypedData* data);
+
+  NativeFunctionWrapper trampoline() const;
+  void set_trampoline(NativeFunctionWrapper value) const;
+  static NativeFunctionWrapper GetTrampoline(RawTypedData* data);
+
+  NativeFunction native_function() const;
+  void set_native_function(NativeFunction value) const;
+  static NativeFunction GetNativeFunction(RawTypedData* data);
+
+  intptr_t argc_tag() const;
+  void set_argc_tag(intptr_t value) const;
+  static intptr_t GetArgcTag(RawTypedData* data);
+
+  static RawTypedData* New(MethodRecognizer::Kind kind,
+                           NativeFunctionWrapper trampoline,
+                           NativeFunction native_function,
+                           intptr_t argc_tag);
+
+ private:
+  struct Payload {
+    NativeFunctionWrapper trampoline;
+    NativeFunction native_function;
+    intptr_t argc_tag;
+    MethodRecognizer::Kind kind;
+  };
+
+  static Payload* FromTypedArray(RawTypedData* data);
+
+  const TypedData& data_;
+  DISALLOW_COPY_AND_ASSIGN(NativeEntryData);
+};
+
+#endif  // !defined(DART_PRECOMPILED_RUNTIME)
+
 }  // namespace dart
 
 #endif  // RUNTIME_VM_NATIVE_ENTRY_H_
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index c7cdf97..39c6839 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -120,8 +120,6 @@
 RawClass* Object::signature_data_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
 RawClass* Object::redirection_data_class_ =
     reinterpret_cast<RawClass*>(RAW_NULL);
-RawClass* Object::native_entry_data_class_ =
-    reinterpret_cast<RawClass*>(RAW_NULL);
 RawClass* Object::field_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
 RawClass* Object::literal_token_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
 RawClass* Object::token_stream_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
@@ -584,9 +582,6 @@
   cls = Class::New<RedirectionData>();
   redirection_data_class_ = cls.raw();
 
-  cls = Class::New<NativeEntryData>();
-  native_entry_data_class_ = cls.raw();
-
   cls = Class::New<Field>();
   field_class_ = cls.raw();
 
@@ -1027,7 +1022,6 @@
   SET_CLASS_NAME(closure_data, ClosureData);
   SET_CLASS_NAME(signature_data, SignatureData);
   SET_CLASS_NAME(redirection_data, RedirectionData);
-  SET_CLASS_NAME(native_entry_data, NativeEntryData);
   SET_CLASS_NAME(field, Field);
   SET_CLASS_NAME(literal_token, LiteralToken);
   SET_CLASS_NAME(token_stream, TokenStream);
@@ -3104,8 +3098,12 @@
 void Class::DisableCHAOptimizedCode(const Class& subclass) {
   ASSERT(Thread::Current()->IsMutatorThread());
   CHACodeArray a(*this);
-  if (FLAG_trace_deoptimization && a.HasCodes() && !subclass.IsNull()) {
-    THR_Print("Adding subclass %s\n", subclass.ToCString());
+  if (FLAG_trace_deoptimization && a.HasCodes()) {
+    if (subclass.IsNull()) {
+      THR_Print("Deopt for CHA (all)\n");
+    } else {
+      THR_Print("Deopt for CHA (new subclass %s)\n", subclass.ToCString());
+    }
   }
   a.DisableCode();
 }
@@ -3919,8 +3917,6 @@
       return Symbols::SignatureData().raw();
     case kRedirectionDataCid:
       return Symbols::RedirectionData().raw();
-    case kNativeEntryDataCid:
-      return Symbols::NativeEntryData().raw();
     case kFieldCid:
       return Symbols::Field().raw();
     case kLiteralTokenCid:
@@ -4335,7 +4331,6 @@
   // instead of recursing, reset it to the super class and loop.
   Thread* thread = Thread::Current();
   Zone* zone = thread->zone();
-  Isolate* isolate = thread->isolate();
   Class& this_class = Class::Handle(zone, cls.raw());
   while (true) {
     // Each occurrence of DynamicType in type T is interpreted as the dynamic
@@ -4351,13 +4346,12 @@
     }
     // Class FutureOr is mapped to dynamic in non-strong mode.
     // Detect snapshots compiled in strong mode and run in non-strong mode.
-    ASSERT(isolate->strong() || !other.IsFutureOrClass());
+    ASSERT(FLAG_strong || !other.IsFutureOrClass());
     // In strong mode, check if 'other' is 'FutureOr'.
     // If so, apply additional subtyping rules.
-    if (isolate->strong() &&
-        this_class.FutureOrTypeTest(zone, type_arguments, other,
-                                    other_type_arguments, bound_error,
-                                    bound_trail, space)) {
+    if (FLAG_strong && this_class.FutureOrTypeTest(
+                           zone, type_arguments, other, other_type_arguments,
+                           bound_error, bound_trail, space)) {
       return true;
     }
     // In the case of a subtype test, each occurrence of DynamicType in type S
@@ -4365,7 +4359,7 @@
     // strong mode.
     // However, DynamicType is not more specific than any type.
     if (this_class.IsDynamicClass()) {
-      return !isolate->strong() && (test_kind == Class::kIsSubtypeOf);
+      return !FLAG_strong && (test_kind == Class::kIsSubtypeOf);
     }
     // If other is neither Object, dynamic or void, then ObjectType/VoidType
     // can't be a subtype of other.
@@ -4392,14 +4386,14 @@
         // Other type can't be more specific than this one because for that
         // it would have to have all dynamic type arguments which is checked
         // above.
-        return !isolate->strong() && (test_kind == Class::kIsSubtypeOf);
+        return !FLAG_strong && (test_kind == Class::kIsSubtypeOf);
       }
       return type_arguments.TypeTest(test_kind, other_type_arguments,
                                      from_index, num_type_params, bound_error,
                                      bound_trail, space);
     }
     // In strong mode, subtyping rules of callable instances are restricted.
-    if (!isolate->strong() && other.IsDartFunctionClass()) {
+    if (!FLAG_strong && other.IsDartFunctionClass()) {
       // Check if type S has a call() method.
       const Function& call_function =
           Function::Handle(zone, this_class.LookupCallFunctionForTypeTest());
@@ -4459,7 +4453,7 @@
         }
       }
       // In Dart 2, implementing Function has no meaning.
-      if (isolate->strong() && interface_class.IsDartFunctionClass()) {
+      if (FLAG_strong && interface_class.IsDartFunctionClass()) {
         continue;
       }
       if (interface_class.TypeTest(test_kind, interface_args, other,
@@ -4505,7 +4499,7 @@
                              Heap::Space space) const {
   // In strong mode, there is no difference between 'is subtype of' and
   // 'is more specific than'.
-  ASSERT(Isolate::Current()->strong());
+  ASSERT(FLAG_strong);
   if (other.IsFutureOrClass()) {
     if (other_type_arguments.IsNull()) {
       return true;
@@ -5242,7 +5236,7 @@
       name = type.BuildName(name_visibility);
     } else {
       // Show dynamic type argument in strong mode.
-      ASSERT(thread->isolate()->strong());
+      ASSERT(FLAG_strong);
       name = Symbols::Dynamic().raw();
     }
     pieces.Add(name);
@@ -5959,15 +5953,19 @@
 bool Function::HasCode() const {
   NoSafepointScope no_safepoint;
   ASSERT(raw_ptr()->code_ != Code::null());
-#if defined(DART_USE_INTERPRETER)
-  return raw_ptr()->code_ != StubCode::LazyCompile_entry()->code() &&
-         raw_ptr()->code_ != StubCode::InterpretCall_entry()->code();
-#else
+#if defined(DART_PRECOMPILED_RUNTIME)
   return raw_ptr()->code_ != StubCode::LazyCompile_entry()->code();
-#endif
+#else
+  if (FLAG_enable_interpreter) {
+    return raw_ptr()->code_ != StubCode::LazyCompile_entry()->code() &&
+           raw_ptr()->code_ != StubCode::InterpretCall_entry()->code();
+  } else {
+    return raw_ptr()->code_ != StubCode::LazyCompile_entry()->code();
+  }
+#endif  // defined(DART_PRECOMPILED_RUNTIME)
 }
 
-#if defined(DART_USE_INTERPRETER)
+#if !defined(DART_PRECOMPILED_RUNTIME)
 void Function::AttachBytecode(const Code& value) const {
   DEBUG_ASSERT(IsMutatorOrAtSafepoint());
   // Finish setting up code before activating it.
@@ -5977,34 +5975,43 @@
   // We should not have loaded the bytecode if the function had code.
   ASSERT(!HasCode());
 
-  // Set the code entry_point to InterpretCall stub.
-  SetInstructions(Code::Handle(StubCode::InterpretCall_entry()->code()));
+  if (!FLAG_use_bytecode_compiler) {
+    // Set the code entry_point to InterpretCall stub.
+    SetInstructions(Code::Handle(StubCode::InterpretCall_entry()->code()));
+  }
 }
 
 bool Function::HasBytecode() const {
   return raw_ptr()->bytecode_ != Code::null();
 }
 
-bool Function::HasCode(RawFunction* function) {
-  NoSafepointScope no_safepoint;
-  ASSERT(function->ptr()->code_ != Code::null());
-  return function->ptr()->code_ != StubCode::LazyCompile_entry()->code() &&
-         function->ptr()->code_ != StubCode::InterpretCall_entry()->code();
-}
-
 bool Function::HasBytecode(RawFunction* function) {
   return function->ptr()->bytecode_ != Code::null();
 }
-#endif
+#endif  // !defined(DART_PRECOMPILED_RUNTIME)
+
+bool Function::HasCode(RawFunction* function) {
+  NoSafepointScope no_safepoint;
+  ASSERT(function->ptr()->code_ != Code::null());
+#if defined(DART_PRECOMPILED_RUNTIME)
+  return function->ptr()->code_ != StubCode::LazyCompile_entry()->code();
+#else
+  return function->ptr()->code_ != StubCode::LazyCompile_entry()->code() &&
+         function->ptr()->code_ != StubCode::InterpretCall_entry()->code();
+#endif  // !defined(DART_PRECOMPILED_RUNTIME)
+}
 
 void Function::ClearCode() const {
 #if defined(DART_PRECOMPILED_RUNTIME)
   UNREACHABLE();
 #else
   ASSERT(Thread::Current()->IsMutatorThread());
+
   StorePointer(&raw_ptr()->unoptimized_code_, Code::null());
+  StorePointer(&raw_ptr()->bytecode_, Code::null());
+
   SetInstructions(Code::Handle(StubCode::LazyCompile_entry()->code()));
-#endif
+#endif  // defined(DART_PRECOMPILED_RUNTIME)
 }
 
 void Function::EnsureHasCompiledUnoptimizedCode() const {
@@ -7047,7 +7054,7 @@
 bool Function::HasCompatibleParametersWith(const Function& other,
                                            Error* bound_error) const {
   ASSERT(Isolate::Current()->error_on_bad_override());
-  ASSERT(!Isolate::Current()->strong());
+  ASSERT(!FLAG_strong);
   ASSERT((bound_error != NULL) && bound_error->IsNull());
   // Check that this function's signature type is a subtype of the other
   // function's signature type.
@@ -7222,7 +7229,7 @@
                                  Error* bound_error,
                                  TrailPtr bound_trail,
                                  Heap::Space space) const {
-  if (Isolate::Current()->strong()) {
+  if (FLAG_strong) {
     const AbstractType& param_type =
         AbstractType::Handle(ParameterTypeAt(parameter_position));
     if (param_type.IsTopType()) {
@@ -7313,8 +7320,7 @@
       (num_opt_named_params < other_num_opt_named_params)) {
     return false;
   }
-  Isolate* isolate = Isolate::Current();
-  if (isolate->reify_generic_functions()) {
+  if (FLAG_reify_generic_functions) {
     // Check the type parameters and bounds of generic functions.
     if (!HasSameTypeParametersAndBounds(other)) {
       return false;
@@ -7325,7 +7331,7 @@
   // Check the result type.
   const AbstractType& other_res_type =
       AbstractType::Handle(zone, other.result_type());
-  if (isolate->strong()) {
+  if (FLAG_strong) {
     // In strong mode, 'void Function()' is a subtype of 'Object Function()'.
     if (!other_res_type.IsTopType()) {
       const AbstractType& res_type = AbstractType::Handle(zone, result_type());
@@ -7697,7 +7703,7 @@
   // In strong mode, change covariant parameter types to Object in the implicit
   // closure of a method compiled by kernel.
   // The VM's parser erases covariant types immediately in strong mode.
-  if (thread->isolate()->strong() && !is_static() && kernel_offset() > 0) {
+  if (FLAG_strong && !is_static() && kernel_offset() > 0) {
     const Script& function_script = Script::Handle(zone, script());
     kernel::TranslationHelper translation_helper(thread);
     translation_helper.InitFromScript(function_script);
@@ -7861,7 +7867,7 @@
   Zone* zone = thread->zone();
   GrowableHandlePtrArray<const String> pieces(zone, 4);
   String& name = String::Handle(zone);
-  if (Isolate::Current()->reify_generic_functions()) {
+  if (FLAG_reify_generic_functions) {
     const TypeArguments& type_params =
         TypeArguments::Handle(zone, type_parameters());
     if (!type_params.IsNull()) {
@@ -8208,6 +8214,7 @@
 void Function::SaveICDataMap(
     const ZoneGrowableArray<const ICData*>& deopt_id_to_ic_data,
     const Array& edge_counters_array) const {
+#if !defined(DART_PRECOMPILED_RUNTIME)
   // Compute number of ICData objects to save.
   // Store edge counter array in the first slot.
   intptr_t count = 1;
@@ -8227,11 +8234,15 @@
   }
   array.SetAt(0, edge_counters_array);
   set_ic_data_array(array);
+#else   // DART_PRECOMPILED_RUNTIME
+  UNREACHABLE();
+#endif  // DART_PRECOMPILED_RUNTIME
 }
 
 void Function::RestoreICDataMap(
     ZoneGrowableArray<const ICData*>* deopt_id_to_ic_data,
     bool clone_ic_data) const {
+#if !defined(DART_PRECOMPILED_RUNTIME)
   if (FLAG_force_clone_compiler_objects) {
     clone_ic_data = true;
   }
@@ -8265,6 +8276,9 @@
       (*deopt_id_to_ic_data)[ic_data.deopt_id()] = &ic_data;
     }
   }
+#else   // DART_PRECOMPILED_RUNTIME
+  UNREACHABLE();
+#endif  // DART_PRECOMPILED_RUNTIME
 }
 
 void Function::set_ic_data_array(const Array& value) const {
@@ -8496,37 +8510,6 @@
                      target_fun.IsNull() ? "null" : target_fun.ToCString());
 }
 
-RawNativeEntryData* NativeEntryData::New() {
-  ASSERT(Object::native_entry_data_class() != Class::null());
-  RawObject* raw = Object::Allocate(
-      NativeEntryData::kClassId, NativeEntryData::InstanceSize(), Heap::kOld);
-  return reinterpret_cast<RawNativeEntryData*>(raw);
-}
-
-const char* NativeEntryData::ToCString() const {
-#if defined(DART_USE_INTERPRETER)
-  if (IsNull()) {
-    return "NativeEntryData: null";
-  }
-  if (kind() != MethodRecognizer::kUnknown) {
-    return OS::SCreate(Thread::Current()->zone(), "NativeEntryData %s",
-                       MethodRecognizer::KindToCString(kind()));
-  }
-  return OS::SCreate(
-      Thread::Current()->zone(),
-      "NativeEntryData argc: %d, trampoline: %s, function: 0x%" Px,
-      NativeArguments::ArgcBits::decode(argc_tag()),
-      trampoline() == &NativeEntry::BootstrapNativeCallWrapper
-          ? "BootstrapNativeCallWrapper"
-          : trampoline() == &NativeEntry::AutoScopeNativeCallWrapper
-                ? "AutoScopeNativeCallWrapper"
-                : "NoScopeNativeCallWrapper",
-      reinterpret_cast<uword>(native_function()));
-#else
-  UNREACHABLE();
-#endif  // defined(DART_USE_INTERPRETER)
-}
-
 RawField* Field::CloneFromOriginal() const {
   return this->Clone(*this);
 }
@@ -9028,6 +9011,9 @@
   ASSERT(Thread::Current()->IsMutatorThread());
   ASSERT(IsOriginal());
   FieldDependentArray a(*this);
+  if (FLAG_trace_deoptimization && a.HasCodes()) {
+    THR_Print("Deopt for field guard (field %s)\n", ToCString());
+  }
   a.DisableCode();
 }
 
@@ -11007,6 +10993,13 @@
   UNREACHABLE();
 }
 
+bool Library::IsAnyCoreLibrary() const {
+  String& url_str = Thread::Current()->StringHandle();
+  url_str = url();
+  return url_str.StartsWith(Symbols::DartScheme()) ||
+         url_str.StartsWith(Symbols::DartSchemePrivate());
+}
+
 void Library::set_num_imports(intptr_t value) const {
   if (!Utils::IsUint(16, value)) {
     ReportTooManyImports(*this);
@@ -11286,7 +11279,6 @@
 }
 
 RawField* Library::GetMetadataField(const String& metaname) const {
-  ASSERT(Thread::Current()->IsMutatorThread());
   const GrowableObjectArray& metadata =
       GrowableObjectArray::Handle(this->metadata());
   Field& entry = Field::Handle();
@@ -12983,6 +12975,9 @@
 
 void LibraryPrefix::InvalidateDependentCode() const {
   PrefixDependentArray a(*this);
+  if (FLAG_trace_deoptimization && a.HasCodes()) {
+    THR_Print("Deopt for lazy load (prefix %s)\n", ToCString());
+  }
   a.DisableCode();
   set_is_loaded();
 }
@@ -13259,6 +13254,11 @@
   StorePointer(&raw_ptr()->potential_natives_, candidates.raw());
 }
 
+void KernelProgramInfo::set_potential_pragma_functions(
+    const GrowableObjectArray& candidates) const {
+  StorePointer(&raw_ptr()->potential_pragma_functions_, candidates.raw());
+}
+
 RawError* Library::CompileAll() {
   Thread* thread = Thread::Current();
   Zone* zone = thread->zone();
@@ -15416,8 +15416,8 @@
   StorePointer(&raw_ptr()->catch_entry_.variables_, smi.raw());
 }
 #else
-void Code::set_catch_entry_state_maps(const TypedData& maps) const {
-  StorePointer(&raw_ptr()->catch_entry_.catch_entry_state_maps_, maps.raw());
+void Code::set_catch_entry_moves_maps(const TypedData& maps) const {
+  StorePointer(&raw_ptr()->catch_entry_.catch_entry_moves_maps_, maps.raw());
 }
 #endif
 
@@ -15814,9 +15814,7 @@
 #endif  // !PRODUCT
   return FinalizeCode("", compiler, assembler, optimized, stats);
 }
-#endif  // !defined(DART_PRECOMPILED_RUNTIME)
 
-#if defined(DART_USE_INTERPRETER)
 RawCode* Code::FinalizeBytecode(const void* bytecode_data,
                                 intptr_t bytecode_size,
                                 const ObjectPool& object_pool,
@@ -15874,7 +15872,8 @@
            code.comments().comments_.Length());
   return code.raw();
 }
-#endif  // defined(DART_USE_INTERPRETER)
+
+#endif  // !defined(DART_PRECOMPILED_RUNTIME)
 
 bool Code::SlowFindRawCodeVisitor::FindObject(RawObject* raw_obj) const {
   return RawCode::ContainsPC(raw_obj, pc_);
@@ -17231,7 +17230,6 @@
   }
   Thread* thread = Thread::Current();
   Zone* zone = thread->zone();
-  Isolate* isolate = thread->isolate();
   const Class& cls = Class::Handle(zone, clazz());
   if (cls.IsClosureClass()) {
     if (other.IsTopType() || other.IsDartFunctionType() ||
@@ -17256,7 +17254,7 @@
         return true;
       }
     }
-    if (isolate->strong() &&
+    if (FLAG_strong &&
         IsFutureOrInstanceOf(zone, instantiated_other, bound_error)) {
       return true;
     }
@@ -17306,7 +17304,7 @@
   other_type_arguments = instantiated_other.arguments();
   const bool other_is_dart_function = instantiated_other.IsDartFunctionType();
   // In strong mode, subtyping rules of callable instances are restricted.
-  if (!isolate->strong() &&
+  if (!FLAG_strong &&
       (other_is_dart_function || instantiated_other.IsFunctionType())) {
     // Check if this instance understands a call() method of a compatible type.
     Function& sig_fun =
@@ -17342,7 +17340,7 @@
     ASSERT(cls.IsNullClass());
     // As of Dart 1.5, the null instance and Null type are handled differently.
     // We already checked other for dynamic and void.
-    if (isolate->strong() &&
+    if (FLAG_strong &&
         IsFutureOrInstanceOf(zone, instantiated_other, bound_error)) {
       return true;
     }
@@ -17355,7 +17353,7 @@
 bool Instance::IsFutureOrInstanceOf(Zone* zone,
                                     const AbstractType& other,
                                     Error* bound_error) const {
-  ASSERT(Isolate::Current()->strong());
+  ASSERT(FLAG_strong);
   if (other.IsType() &&
       Class::Handle(zone, other.type_class()).IsFutureOrClass()) {
     if (other.arguments() == TypeArguments::null()) {
@@ -17934,7 +17932,7 @@
       } else {
         ASSERT(num_args == 0);  // Type is raw.
         // No need to fill up with "dynamic", unless running in strong mode.
-        if (!thread->isolate()->strong()) {
+        if (!FLAG_strong) {
           num_type_params = 0;
         }
       }
@@ -17955,8 +17953,7 @@
   GrowableHandlePtrArray<const String> pieces(zone, 4);
   pieces.Add(class_name);
   if ((num_type_params == 0) ||
-      (!thread->isolate()->strong() &&
-       args.IsRaw(first_type_param_index, num_type_params))) {
+      (!FLAG_strong && args.IsRaw(first_type_param_index, num_type_params))) {
     // Do nothing.
   } else {
     const String& args_name = String::Handle(
@@ -18007,7 +18004,27 @@
     return false;
   }
   classid_t cid = type_class_id();
-  return (cid == kDynamicCid) || (cid == kInstanceCid);
+  if ((cid == kDynamicCid) || (cid == kInstanceCid)) {
+    return true;
+  }
+  // In strong mode, FutureOr<T> where T is a top type behaves as a top type.
+  if (FLAG_strong) {
+    Thread* thread = Thread::Current();
+    Zone* zone = thread->zone();
+    if (Class::Handle(zone, type_class()).IsFutureOrClass()) {
+      if (arguments() == TypeArguments::null()) {
+        return true;
+      }
+      const TypeArguments& type_arguments =
+          TypeArguments::Handle(zone, arguments());
+      const AbstractType& type_arg =
+          AbstractType::Handle(zone, type_arguments.TypeAt(0));
+      if (type_arg.IsTopType()) {
+        return true;
+      }
+    }
+  }
+  return false;
 }
 
 bool AbstractType::IsNullType() const {
@@ -18119,7 +18136,6 @@
   }
   Thread* thread = Thread::Current();
   Zone* zone = thread->zone();
-  Isolate* isolate = thread->isolate();
   if (IsBoundedType() || other.IsBoundedType()) {
     if (Equals(other)) {
       return true;
@@ -18199,7 +18215,7 @@
     }
     // In strong mode, check if 'other' is 'FutureOr'.
     // If so, apply additional subtyping rules.
-    if (isolate->strong() &&
+    if (FLAG_strong &&
         FutureOrTypeTest(zone, other, bound_error, bound_trail, space)) {
       return true;
     }
@@ -18226,7 +18242,7 @@
                           space);
     }
     // In strong mode, subtyping rules of callable instances are restricted.
-    if (!isolate->strong()) {
+    if (!FLAG_strong) {
       // Check if type S has a call() method of function type T.
       const Function& call_function =
           Function::Handle(zone, type_cls.LookupCallFunctionForTypeTest());
@@ -18264,7 +18280,7 @@
   if (IsFunctionType()) {
     // In strong mode, check if 'other' is 'FutureOr'.
     // If so, apply additional subtyping rules.
-    if (isolate->strong() &&
+    if (FLAG_strong &&
         FutureOrTypeTest(zone, other, bound_error, bound_trail, space)) {
       return true;
     }
@@ -18283,7 +18299,7 @@
                                     Heap::Space space) const {
   // In strong mode, there is no difference between 'is subtype of' and
   // 'is more specific than'.
-  ASSERT(Isolate::Current()->strong());
+  ASSERT(FLAG_strong);
   if (other.IsType() &&
       Class::Handle(zone, other.type_class()).IsFutureOrClass()) {
     if (other.arguments() == TypeArguments::null()) {
@@ -18764,7 +18780,7 @@
   const Function& other_sig_fun =
       Function::Handle(zone, other_type.signature());
 
-  if (Isolate::Current()->reify_generic_functions()) {
+  if (FLAG_reify_generic_functions) {
     // Compare function type parameters and their bounds.
     // Check the type parameters and bounds of generic functions.
     if (!sig_fun.HasSameTypeParametersAndBounds(other_sig_fun)) {
diff --git a/runtime/vm/object.h b/runtime/vm/object.h
index 6fbd389..11ea398 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -420,9 +420,6 @@
   static RawClass* closure_data_class() { return closure_data_class_; }
   static RawClass* signature_data_class() { return signature_data_class_; }
   static RawClass* redirection_data_class() { return redirection_data_class_; }
-  static RawClass* native_entry_data_class() {
-    return native_entry_data_class_;
-  }
   static RawClass* field_class() { return field_class_; }
   static RawClass* literal_token_class() { return literal_token_class_; }
   static RawClass* token_stream_class() { return token_stream_class_; }
@@ -688,7 +685,6 @@
   static RawClass* closure_data_class_;    // Class of ClosureData vm obj.
   static RawClass* signature_data_class_;  // Class of SignatureData vm obj.
   static RawClass* redirection_data_class_;  // Class of RedirectionData vm obj.
-  static RawClass* native_entry_data_class_;  // Class of NativeEntryData.
   static RawClass* field_class_;             // Class of the Field vm object.
   static RawClass* literal_token_class_;     // Class of LiteralToken vm object.
   static RawClass* token_stream_class_;  // Class of the TokenStream vm object.
@@ -697,7 +693,7 @@
   static RawClass* namespace_class_;     // Class of Namespace vm object.
   static RawClass* kernel_program_info_class_;  // Class of KernelProgramInfo vm
                                                 // object.
-  static RawClass* code_class_;          // Class of the Code vm object.
+  static RawClass* code_class_;                 // Class of the Code vm object.
   static RawClass* instructions_class_;  // Class of the Instructions vm object.
   static RawClass* object_pool_class_;   // Class of the ObjectPool vm object.
   static RawClass* pc_descriptors_class_;   // Class of PcDescriptors vm object.
@@ -2364,8 +2360,8 @@
   }
   void set_unoptimized_code(const Code& value) const;
   bool HasCode() const;
-#if defined(DART_USE_INTERPRETER)
   static bool HasCode(RawFunction* function);
+#if !defined(DART_PRECOMPILED_RUNTIME)
   static bool HasBytecode(RawFunction* function);
 #endif
 
@@ -2379,7 +2375,7 @@
     return OFFSET_OF(RawFunction, unchecked_entry_point_);
   }
 
-#if defined(DART_USE_INTERPRETER)
+#if !defined(DART_PRECOMPILED_RUNTIME)
   void AttachBytecode(const Code& bytecode) const;
   RawCode* Bytecode() const { return raw_ptr()->bytecode_; }
   bool HasBytecode() const;
@@ -2537,7 +2533,7 @@
   bool IsInFactoryScope() const;
 
   bool NeedsArgumentTypeChecks(Isolate* I) const {
-    if (I->strong()) {
+    if (FLAG_strong) {
       if (!I->should_emit_strong_mode_checks()) {
         return false;
       }
@@ -3216,39 +3212,6 @@
   friend class HeapProfiler;
 };
 
-class NativeEntryData : public Object {
- public:
-  static intptr_t InstanceSize() {
-    return RoundedAllocationSize(sizeof(RawNativeEntryData));
-  }
-
-  MethodRecognizer::Kind kind() const { return raw_ptr()->kind_; }
-  void set_kind(MethodRecognizer::Kind value) const {
-    StoreNonPointer(&raw_ptr()->kind_, value);
-  }
-
-  NativeFunctionWrapper trampoline() const { return raw_ptr()->trampoline_; }
-  void set_trampoline(NativeFunctionWrapper value) const {
-    StoreNonPointer(&raw_ptr()->trampoline_, value);
-  }
-
-  NativeFunction native_function() const { return raw_ptr()->native_function_; }
-  void set_native_function(NativeFunction value) const {
-    StoreNonPointer(&raw_ptr()->native_function_, value);
-  }
-
-  intptr_t argc_tag() const { return raw_ptr()->argc_tag_; }
-  void set_argc_tag(intptr_t value) const {
-    StoreNonPointer(&raw_ptr()->argc_tag_, value);
-  }
-
-  static RawNativeEntryData* New();
-
-  FINAL_HEAP_OBJECT_IMPLEMENTATION(NativeEntryData, Object);
-  friend class Class;
-  friend class HeapProfiler;
-};
-
 class Field : public Object {
  public:
   RawField* Original() const;
@@ -4093,6 +4056,9 @@
 
   bool IsCoreLibrary() const { return raw() == CoreLibrary(); }
 
+  // Includes 'dart:async', 'dart:typed_data', etc.
+  bool IsAnyCoreLibrary() const;
+
   inline intptr_t UrlHash() const;
 
   RawExternalTypedData* kernel_data() const { return raw_ptr()->kernel_data_; }
@@ -4314,6 +4280,12 @@
   }
   void set_potential_natives(const GrowableObjectArray& candidates) const;
 
+  RawGrowableObjectArray* potential_pragma_functions() const {
+    return raw_ptr()->potential_pragma_functions_;
+  }
+  void set_potential_pragma_functions(
+      const GrowableObjectArray& candidates) const;
+
   RawScript* ScriptAt(intptr_t index) const;
 
  private:
@@ -4486,11 +4458,11 @@
   static const intptr_t kCheckedEntryOffset = 15;
   static const intptr_t kUncheckedEntryOffset = 34;
 #elif defined(TARGET_ARCH_ARM)
-  static const intptr_t kCheckedEntryOffset = 8;
-  static const intptr_t kUncheckedEntryOffset = 32;
+  static const intptr_t kCheckedEntryOffset = 0;
+  static const intptr_t kUncheckedEntryOffset = 20;
 #elif defined(TARGET_ARCH_ARM64)
-  static const intptr_t kCheckedEntryOffset = 16;
-  static const intptr_t kUncheckedEntryOffset = 40;
+  static const intptr_t kCheckedEntryOffset = 8;
+  static const intptr_t kUncheckedEntryOffset = 28;
 #elif defined(TARGET_ARCH_DBC)
   static const intptr_t kCheckedEntryOffset = 0;
   static const intptr_t kUncheckedEntryOffset = 0;
@@ -5073,10 +5045,10 @@
   RawSmi* variables() const { return raw_ptr()->catch_entry_.variables_; }
   void set_variables(const Smi& smi) const;
 #else
-  RawTypedData* catch_entry_state_maps() const {
-    return raw_ptr()->catch_entry_.catch_entry_state_maps_;
+  RawTypedData* catch_entry_moves_maps() const {
+    return raw_ptr()->catch_entry_.catch_entry_moves_maps_;
   }
-  void set_catch_entry_state_maps(const TypedData& maps) const;
+  void set_catch_entry_moves_maps(const TypedData& maps) const;
 #endif
 
   RawArray* stackmaps() const { return raw_ptr()->stackmaps_; }
@@ -5263,13 +5235,11 @@
                                Assembler* assembler,
                                bool optimized,
                                CodeStatistics* stats = nullptr);
-#if defined(DART_USE_INTERPRETER)
   static RawCode* FinalizeBytecode(const void* bytecode_data,
                                    intptr_t bytecode_size,
                                    const ObjectPool& object_pool,
                                    CodeStatistics* stats = nullptr);
 #endif
-#endif
   static RawCode* LookupCode(uword pc);
   static RawCode* LookupCodeInVmIsolate(uword pc);
   static RawCode* FindCode(uword pc, int64_t timestamp);
diff --git a/runtime/vm/object_reload.cc b/runtime/vm/object_reload.cc
index 0474419..9159e97 100644
--- a/runtime/vm/object_reload.cc
+++ b/runtime/vm/object_reload.cc
@@ -591,7 +591,6 @@
   if (is_prefinalized()) {
     if (!CanReloadPreFinalized(replacement, context)) return;
   }
-  ASSERT(is_finalized() == replacement.is_finalized());
   TIR_Print("Class `%s` can be reloaded (%" Pd " and %" Pd ")\n", ToCString(),
             id(), replacement.id());
 }
diff --git a/runtime/vm/object_service.cc b/runtime/vm/object_service.cc
index 4b99e44..502e0ed 100644
--- a/runtime/vm/object_service.cc
+++ b/runtime/vm/object_service.cc
@@ -346,10 +346,6 @@
   Object::PrintJSONImpl(stream, ref);
 }
 
-void NativeEntryData::PrintJSONImpl(JSONStream* stream, bool ref) const {
-  Object::PrintJSONImpl(stream, ref);
-}
-
 void Field::PrintJSONImpl(JSONStream* stream, bool ref) const {
   JSONObject jsobj(stream);
   Class& cls = Class::Handle(Owner());
@@ -458,11 +454,11 @@
   }
 
   // Print the line number table
-  if (!source.IsNull()) {
+  const GrowableObjectArray& lineNumberArray =
+      GrowableObjectArray::Handle(GenerateLineNumberArray());
+  if (!lineNumberArray.IsNull()) {
     JSONArray tokenPosTable(&jsobj, "tokenPosTable");
 
-    const GrowableObjectArray& lineNumberArray =
-        GrowableObjectArray::Handle(GenerateLineNumberArray());
     Object& value = Object::Handle();
     intptr_t pos = 0;
 
diff --git a/runtime/vm/parser.cc b/runtime/vm/parser.cc
index d55273e..0e7670e 100644
--- a/runtime/vm/parser.cc
+++ b/runtime/vm/parser.cc
@@ -197,7 +197,7 @@
   current_context_var_ = temp;
 
   const bool reify_generic_argument =
-      function.IsGeneric() && Isolate::Current()->reify_generic_functions();
+      function.IsGeneric() && FLAG_reify_generic_functions;
 
   const bool load_optional_arguments = function.HasOptionalParameters();
 
@@ -337,7 +337,8 @@
   // parameters array, which can be used to access the raw parameters (i.e. not
   // the potentially variables which are in the context)
 
-  for (intptr_t param = 0; param < function().NumParameters(); ++param) {
+  raw_parameters_ = new (Z) ZoneGrowableArray<LocalVariable*>(Z, num_params);
+  for (intptr_t param = 0; param < num_params; ++param) {
     LocalVariable* raw_parameter = scope->VariableAt(param);
     if (raw_parameter->is_captured()) {
       String& tmp = String::ZoneHandle(Z);
@@ -366,7 +367,7 @@
             VariableIndex(function().NumParameters() - param));
       }
     }
-    raw_parameters_.Add(raw_parameter);
+    raw_parameters_->Add(raw_parameter);
   }
   if (function_type_arguments_ != NULL) {
     LocalVariable* raw_type_args_parameter = function_type_arguments_;
@@ -445,6 +446,12 @@
   num_stack_locals_ = num_stack_locals;
 }
 
+void ParsedFunction::AllocateBytecodeVariables(intptr_t num_stack_locals) {
+  ASSERT(!function().IsIrregexpFunction());
+  first_parameter_index_ = VariableIndex(function().num_fixed_parameters());
+  num_stack_locals_ = num_stack_locals;
+}
+
 struct Parser::Block : public ZoneAllocated {
   Block(Block* outer_block, LocalScope* local_scope, SequenceNode* seq)
       : parent(outer_block), scope(local_scope), statements(seq) {
@@ -1247,7 +1254,7 @@
     }
   }
   // ParseFunc has recorded the generic function type arguments variable.
-  ASSERT(!Isolate::Current()->reify_generic_functions() ||
+  ASSERT(!FLAG_reify_generic_functions ||
          !parser.current_function().IsGeneric() ||
          (parsed_function->function_type_arguments() != NULL));
 }
@@ -1573,7 +1580,7 @@
   const Function& parent = Function::Handle(func.parent_function());
   intptr_t type_args_len = 0;  // Length of type args vector passed to parent.
   LocalVariable* type_args_var = NULL;
-  if (Isolate::Current()->reify_generic_functions()) {
+  if (FLAG_reify_generic_functions) {
     // The parent function of an implicit closure is the original function, i.e.
     // non-closurized. It is not an enclosing function in the usual sense of a
     // parent function. Do not set parent_type_arguments() in parsed_function_.
@@ -3545,7 +3552,7 @@
     current_block_->scope->AddVariable(parsed_function_->arg_desc_var());
   }
 
-  if (Isolate::Current()->reify_generic_functions()) {
+  if (FLAG_reify_generic_functions) {
     // Lookup function type arguments variable in parent function scope, if any.
     if (func.HasGenericParent()) {
       const String* variable_name = &Symbols::FunctionTypeArgumentsVar();
@@ -3802,7 +3809,7 @@
          func.end_token_pos() == end_token_pos);
   func.set_end_token_pos(end_token_pos);
   SequenceNode* body = CloseBlock();
-  if (Isolate::Current()->reify_generic_functions() && func.IsGeneric() &&
+  if (FLAG_reify_generic_functions && func.IsGeneric() &&
       !generated_body_closure.IsNull()) {
     LocalVariable* existing_var = body->scope()->LookupVariable(
         Symbols::FunctionTypeArgumentsVar(), false);
@@ -7629,7 +7636,7 @@
   const TokenPosition token_pos = ST(closure_body->token_pos());
 
   Function& completer_constructor = Function::ZoneHandle(Z);
-  if (I->sync_async()) {
+  if (FLAG_sync_async) {
     const Class& completer_class = Class::Handle(
         Z, async_lib.LookupClassAllowPrivate(Symbols::_AsyncAwaitCompleter()));
     ASSERT(!completer_class.IsNull());
@@ -7739,7 +7746,7 @@
 
   current_block_->statements->Add(store_async_catch_error_callback);
 
-  if (I->sync_async()) {
+  if (FLAG_sync_async) {
     // Add to AST:
     //   :async_completer.start(:async_op);
     ArgumentListNode* arguments = new (Z) ArgumentListNode(token_pos);
@@ -7823,7 +7830,6 @@
 // with the formal parameter types and names.
 void Parser::AddFormalParamsToFunction(const ParamList* params,
                                        const Function& func) {
-  Isolate* isolate = Isolate::Current();
   ASSERT((params != NULL) && (params->parameters != NULL));
   ASSERT((params->num_optional_parameters > 0) ==
          (params->has_optional_positional_parameters ||
@@ -7859,7 +7865,7 @@
       }
       // In non-strong mode, the covariant keyword is ignored. In strong mode,
       // the parameter type is changed to Object.
-      if (isolate->strong()) {
+      if (FLAG_strong) {
         param_type = Type::ObjectType();
       }
     }
@@ -7940,7 +7946,7 @@
 void Parser::CaptureFunctionTypeArguments() {
   ASSERT(InGenericFunctionScope());
   ASSERT(FunctionLevel() > 0);
-  if (!Isolate::Current()->reify_generic_functions()) {
+  if (!FLAG_reify_generic_functions) {
     return;
   }
   const String* variable_name = &Symbols::FunctionTypeArgumentsVar();
@@ -11971,7 +11977,7 @@
     type_parameter ^= CanonicalizeType(type_parameter);
   } else {
     ASSERT(type_parameter.IsFunctionTypeParameter());
-    if (!Isolate::Current()->reify_generic_functions()) {
+    if (!FLAG_reify_generic_functions) {
       Type& type = Type::ZoneHandle(Z, Type::DynamicType());
       return new (Z) TypeNode(primary_pos, type);
     }
@@ -12016,7 +12022,7 @@
         if (CurrentToken() == Token::kLT) {
           // Type arguments.
           func_type_args = ParseTypeArguments(ClassFinalizer::kCanonicalize);
-          if (Isolate::Current()->reify_generic_functions()) {
+          if (FLAG_reify_generic_functions) {
             if (!func_type_args.IsNull() && !func_type_args.IsInstantiated() &&
                 (FunctionLevel() > 0)) {
               // Make sure that the instantiators are captured.
@@ -12112,7 +12118,7 @@
       if (CurrentToken() == Token::kLT) {
         // Type arguments.
         func_type_args = ParseTypeArguments(ClassFinalizer::kCanonicalize);
-        if (Isolate::Current()->reify_generic_functions()) {
+        if (FLAG_reify_generic_functions) {
           if (!func_type_args.IsNull() && !func_type_args.IsInstantiated() &&
               (FunctionLevel() > 0)) {
             // Make sure that the instantiators are captured.
@@ -12338,7 +12344,7 @@
                 String::Handle(Z, type_parameter.name()).ToCString());
             return;
           }
-          if (Isolate::Current()->reify_generic_functions()) {
+          if (FLAG_reify_generic_functions) {
             ASSERT(!type_parameter.IsMalformed());
             *type = type_parameter.raw();
           } else {
@@ -12943,7 +12949,7 @@
       if ((resolved == NULL) || (resolved_func_level < type_param_func_level)) {
         // The identifier is a function type parameter, possibly shadowing
         // 'resolved'.
-        if (!Isolate::Current()->reify_generic_functions()) {
+        if (!FLAG_reify_generic_functions) {
           Type& type = Type::ZoneHandle(Z, Type::DynamicType());
           return new (Z) TypeNode(ident_pos, type);
         }
@@ -14414,7 +14420,7 @@
         if (CurrentToken() == Token::kLT) {
           // Type arguments.
           func_type_args = ParseTypeArguments(ClassFinalizer::kCanonicalize);
-          if (Isolate::Current()->reify_generic_functions()) {
+          if (FLAG_reify_generic_functions) {
             if (!func_type_args.IsNull() && !func_type_args.IsInstantiated() &&
                 (FunctionLevel() > 0)) {
               // Make sure that the instantiators are captured.
diff --git a/runtime/vm/parser.h b/runtime/vm/parser.h
index 2383ce2..712e5c3 100644
--- a/runtime/vm/parser.h
+++ b/runtime/vm/parser.h
@@ -200,6 +200,7 @@
 
   void AllocateVariables();
   void AllocateIrregexpVariables(intptr_t num_stack_locals);
+  void AllocateBytecodeVariables(intptr_t num_stack_locals);
 
   void record_await() { have_seen_await_expr_ = true; }
   bool have_seen_await() const { return have_seen_await_expr_; }
@@ -229,8 +230,16 @@
     return raw_type_arguments_var_;
   }
 
+  void SetRawTypeArgumentsVariable(LocalVariable* raw_type_arguments_var) {
+    raw_type_arguments_var_ = raw_type_arguments_var;
+  }
+
+  void SetRawParameters(ZoneGrowableArray<LocalVariable*>* raw_parameters) {
+    raw_parameters_ = raw_parameters;
+  }
+
   LocalVariable* RawParameterVariable(intptr_t i) const {
-    return raw_parameters_[i];
+    return raw_parameters_->At(i);
   }
 
  private:
@@ -252,7 +261,7 @@
   ZoneGrowableArray<const Instance*>* default_parameter_values_;
 
   LocalVariable* raw_type_arguments_var_;
-  ZoneGrowableArray<LocalVariable*> raw_parameters_;
+  ZoneGrowableArray<LocalVariable*>* raw_parameters_ = nullptr;
 
   VariableIndex first_parameter_index_;
   int num_stack_locals_;
diff --git a/runtime/vm/program_visitor.cc b/runtime/vm/program_visitor.cc
index a6400e8..2fe8841 100644
--- a/runtime/vm/program_visitor.cc
+++ b/runtime/vm/program_visitor.cc
@@ -380,51 +380,51 @@
 #endif  // !defined(DART_PRECOMPILED_RUNTIME)
 
 #if defined(DART_PRECOMPILER)
-void ProgramVisitor::DedupCatchEntryStateMaps() {
+void ProgramVisitor::DedupCatchEntryMovesMaps() {
   if (!FLAG_precompiled_mode) {
     return;
   }
-  class DedupCatchEntryStateMapsVisitor : public FunctionVisitor {
+  class DedupCatchEntryMovesMapsVisitor : public FunctionVisitor {
    public:
-    explicit DedupCatchEntryStateMapsVisitor(Zone* zone)
+    explicit DedupCatchEntryMovesMapsVisitor(Zone* zone)
         : zone_(zone),
-          canonical_catch_entry_state_maps_(),
+          canonical_catch_entry_moves_maps_(),
           code_(Code::Handle(zone)),
-          catch_entry_state_maps_(TypedData::Handle(zone)) {}
+          catch_entry_moves_maps_(TypedData::Handle(zone)) {}
 
     void Visit(const Function& function) {
       if (!function.HasCode()) {
         return;
       }
       code_ = function.CurrentCode();
-      catch_entry_state_maps_ = code_.catch_entry_state_maps();
-      catch_entry_state_maps_ =
-          DedupCatchEntryStateMaps(catch_entry_state_maps_);
-      code_.set_catch_entry_state_maps(catch_entry_state_maps_);
+      catch_entry_moves_maps_ = code_.catch_entry_moves_maps();
+      catch_entry_moves_maps_ =
+          DedupCatchEntryMovesMaps(catch_entry_moves_maps_);
+      code_.set_catch_entry_moves_maps(catch_entry_moves_maps_);
     }
 
-    RawTypedData* DedupCatchEntryStateMaps(
-        const TypedData& catch_entry_state_maps) {
-      const TypedData* canonical_catch_entry_state_maps =
-          canonical_catch_entry_state_maps_.LookupValue(
-              &catch_entry_state_maps);
-      if (canonical_catch_entry_state_maps == NULL) {
-        canonical_catch_entry_state_maps_.Insert(
-            &TypedData::ZoneHandle(zone_, catch_entry_state_maps.raw()));
-        return catch_entry_state_maps.raw();
+    RawTypedData* DedupCatchEntryMovesMaps(
+        const TypedData& catch_entry_moves_maps) {
+      const TypedData* canonical_catch_entry_moves_maps =
+          canonical_catch_entry_moves_maps_.LookupValue(
+              &catch_entry_moves_maps);
+      if (canonical_catch_entry_moves_maps == NULL) {
+        canonical_catch_entry_moves_maps_.Insert(
+            &TypedData::ZoneHandle(zone_, catch_entry_moves_maps.raw()));
+        return catch_entry_moves_maps.raw();
       } else {
-        return canonical_catch_entry_state_maps->raw();
+        return canonical_catch_entry_moves_maps->raw();
       }
     }
 
    private:
     Zone* zone_;
-    TypedDataSet canonical_catch_entry_state_maps_;
+    TypedDataSet canonical_catch_entry_moves_maps_;
     Code& code_;
-    TypedData& catch_entry_state_maps_;
+    TypedData& catch_entry_moves_maps_;
   };
 
-  DedupCatchEntryStateMapsVisitor visitor(Thread::Current()->zone());
+  DedupCatchEntryMovesMapsVisitor visitor(Thread::Current()->zone());
   ProgramVisitor::VisitFunctions(&visitor);
 }
 #endif  // !defined(DART_PRECOMPILER)
@@ -724,7 +724,7 @@
   DedupPcDescriptors();
   NOT_IN_PRECOMPILED(DedupDeoptEntries());
 #if defined(DART_PRECOMPILER)
-  DedupCatchEntryStateMaps();
+  DedupCatchEntryMovesMaps();
 #endif
   DedupCodeSourceMaps();
   DedupLists();
diff --git a/runtime/vm/program_visitor.h b/runtime/vm/program_visitor.h
index 4125f71..f2b255a 100644
--- a/runtime/vm/program_visitor.h
+++ b/runtime/vm/program_visitor.h
@@ -35,7 +35,7 @@
   static void DedupPcDescriptors();
   NOT_IN_PRECOMPILED(static void DedupDeoptEntries());
 #if defined(DART_PRECOMPILER)
-  static void DedupCatchEntryStateMaps();
+  static void DedupCatchEntryMovesMaps();
 #endif
   static void DedupCodeSourceMaps();
   static void DedupLists();
diff --git a/runtime/vm/raw_object.cc b/runtime/vm/raw_object.cc
index 5db35fb..41d4e2c 100644
--- a/runtime/vm/raw_object.cc
+++ b/runtime/vm/raw_object.cc
@@ -380,7 +380,6 @@
 REGULAR_VISITOR(ClosureData)
 REGULAR_VISITOR(SignatureData)
 REGULAR_VISITOR(RedirectionData)
-NULL_VISITOR(NativeEntryData)
 REGULAR_VISITOR(Field)
 REGULAR_VISITOR(LiteralToken)
 REGULAR_VISITOR(TokenStream)
diff --git a/runtime/vm/raw_object.h b/runtime/vm/raw_object.h
index c6e3669..f8dacf3 100644
--- a/runtime/vm/raw_object.h
+++ b/runtime/vm/raw_object.h
@@ -28,7 +28,6 @@
   V(ClosureData)                                                               \
   V(SignatureData)                                                             \
   V(RedirectionData)                                                           \
-  V(NativeEntryData)                                                           \
   V(Field)                                                                     \
   V(LiteralToken)                                                              \
   V(TokenStream)                                                               \
@@ -309,6 +308,8 @@
 #endif
   };
 
+  static const intptr_t kGenerationalBarrierMask = 1 << kNewBit;
+  static const intptr_t kIncrementalBarrierMask = 1 << kOldAndNotMarkedBit;
   static const intptr_t kBarrierOverlapShift = 2;
   COMPILE_ASSERT(kOldAndNotMarkedBit + kBarrierOverlapShift == kOldBit);
   COMPILE_ASSERT(kNewBit + kBarrierOverlapShift == kOldAndNotRememberedBit);
@@ -474,19 +475,10 @@
     ASSERT(!IsRemembered());
     UpdateTagBit<OldAndNotRememberedBit>(false);
   }
-  void SetRememberedBitUnsynchronized() {
-    ASSERT(!IsRemembered());
-    uint32_t tags = ptr()->tags_;
-    ptr()->tags_ = OldAndNotRememberedBit::update(false, tags);
-  }
   void ClearRememberedBit() {
     ASSERT(IsOldObject());
     UpdateTagBit<OldAndNotRememberedBit>(true);
   }
-  void ClearRememberedBitUnsynchronized() {
-    uint32_t tags = ptr()->tags_;
-    ptr()->tags_ = OldAndNotRememberedBit::update(true, tags);
-  }
 
 #define DEFINE_IS_CID(clazz)                                                   \
   bool Is##clazz() const { return ((GetClassId() == k##clazz##Cid)); }
@@ -698,11 +690,51 @@
   template <typename type>
   void StorePointer(type const* addr, type value) {
     *const_cast<type*>(addr) = value;
-    // Filter stores based on source and target.
+
     if (!value->IsHeapObject()) return;
-    if (value->IsNewObject() && this->IsOldObject() && !this->IsRemembered()) {
-      this->SetRememberedBit();
-      Thread::Current()->StoreBufferAddObject(this);
+
+    uint32_t source_tags = this->ptr()->tags_;
+    uint32_t target_tags = value->ptr()->tags_;
+    Thread* thread = Thread::Current();
+    if (((source_tags >> kBarrierOverlapShift) & target_tags &
+         thread->write_barrier_mask()) != 0) {
+      if (value->IsNewObject()) {
+        // Generational barrier: record when a store creates an
+        // old-and-not-remembered -> new reference.
+        ASSERT(!this->IsRemembered());
+        this->SetRememberedBit();
+        thread->StoreBufferAddObject(this);
+      } else {
+        // Incremental barrier: record when a store creates an
+        // old -> old-and-not-marked reference.
+        ASSERT(value->IsOldObject());
+        UNREACHABLE();
+      }
+    }
+  }
+
+  template <typename type>
+  void StorePointer(type const* addr, type value, Thread* thread) {
+    *const_cast<type*>(addr) = value;
+
+    if (!value->IsHeapObject()) return;
+
+    uint32_t source_tags = this->ptr()->tags_;
+    uint32_t target_tags = value->ptr()->tags_;
+    if (((source_tags >> kBarrierOverlapShift) & target_tags &
+         thread->write_barrier_mask()) != 0) {
+      if (value->IsNewObject()) {
+        // Generational barrier: record when a store creates an
+        // old-and-not-remembered -> new reference.
+        ASSERT(!this->IsRemembered());
+        this->SetRememberedBit();
+        thread->StoreBufferAddObject(this);
+      } else {
+        // Incremental barrier: record when a store creates an
+        // old -> old-and-not-marked reference.
+        ASSERT(value->IsOldObject());
+        UNREACHABLE();
+      }
     }
   }
 
@@ -983,10 +1015,8 @@
   RawObject** to_no_code() {
     return reinterpret_cast<RawObject**>(&ptr()->ic_data_array_);
   }
-#if defined(DART_USE_INTERPRETER)
-  RawCode* bytecode_;
-#endif
   RawCode* code_;  // Currently active code. Accessed from generated code.
+  NOT_IN_PRECOMPILED(RawCode* bytecode_);
   NOT_IN_PRECOMPILED(RawCode* unoptimized_code_);  // Unoptimized code, keep it
                                                    // after optimization.
 #if defined(DART_PRECOMPILED_RUNTIME)
@@ -1076,23 +1106,6 @@
   VISIT_TO(RawObject*, target_);
 };
 
-// Forward declarations.
-class NativeArguments;
-typedef void (*NativeFunction)(NativeArguments* arguments);
-typedef void (*NativeFunctionWrapper)(Dart_NativeArguments args,
-                                      Dart_NativeFunction func);
-
-class RawNativeEntryData : public RawObject {
- private:
-  RAW_HEAP_OBJECT_IMPLEMENTATION(NativeEntryData);
-  VISIT_NOTHING();
-
-  NativeFunctionWrapper trampoline_;
-  NativeFunction native_function_;
-  intptr_t argc_tag_;
-  MethodRecognizer::Kind kind_;
-};
-
 class RawField : public RawObject {
   RAW_HEAP_OBJECT_IMPLEMENTATION(Field);
 
@@ -1133,11 +1146,11 @@
     UNREACHABLE();
     return NULL;
   }
-#if defined(DART_USE_INTERPRETER)
+#if defined(DART_PRECOMPILED_RUNTIME)
+  VISIT_TO(RawObject*, dependent_code_);
+#else
   RawSubtypeTestCache* type_test_cache_;  // For type test in implicit setter.
   VISIT_TO(RawObject*, type_test_cache_);
-#else
-  VISIT_TO(RawObject*, dependent_code_);
 #endif
   TokenPosition token_pos_;
   TokenPosition end_token_pos_;
@@ -1318,6 +1331,7 @@
   RawArray* scripts_;
   RawArray* constants_;
   RawGrowableObjectArray* potential_natives_;
+  RawGrowableObjectArray* potential_pragma_functions_;
   RawExternalTypedData* constants_table_;
   VISIT_TO(RawObject*, constants_table_);
 
@@ -1377,7 +1391,7 @@
   RawExceptionHandlers* exception_handlers_;
   RawPcDescriptors* pc_descriptors_;
   union {
-    RawTypedData* catch_entry_state_maps_;
+    RawTypedData* catch_entry_moves_maps_;
     RawSmi* variables_;
   } catch_entry_;
   RawArray* stackmaps_;
@@ -2304,13 +2318,14 @@
   const uint8_t* data() const { OPEN_ARRAY_START(uint8_t, uint8_t); }
 
   friend class Api;
-  friend class Object;
   friend class Instance;
-  friend class SnapshotReader;
+  friend class NativeEntryData;
+  friend class Object;
   friend class ObjectPool;
-  friend class RawObjectPool;
-  friend class ObjectPoolSerializationCluster;
   friend class ObjectPoolDeserializationCluster;
+  friend class ObjectPoolSerializationCluster;
+  friend class RawObjectPool;
+  friend class SnapshotReader;
 };
 
 class RawExternalTypedData : public RawInstance {
diff --git a/runtime/vm/raw_object_snapshot.cc b/runtime/vm/raw_object_snapshot.cc
index 8c021bb..279d28e 100644
--- a/runtime/vm/raw_object_snapshot.cc
+++ b/runtime/vm/raw_object_snapshot.cc
@@ -746,22 +746,6 @@
   visitor.VisitPointers(from(), to());
 }
 
-RawNativeEntryData* NativeEntryData::ReadFrom(SnapshotReader* reader,
-                                              intptr_t object_id,
-                                              intptr_t tags,
-                                              Snapshot::Kind kind,
-                                              bool as_reference) {
-  UNREACHABLE();
-  return NativeEntryData::null();
-}
-
-void RawNativeEntryData::WriteTo(SnapshotWriter* writer,
-                                 intptr_t object_id,
-                                 Snapshot::Kind kind,
-                                 bool as_reference) {
-  UNREACHABLE();
-}
-
 RawFunction* Function::ReadFrom(SnapshotReader* reader,
                                 intptr_t object_id,
                                 intptr_t tags,
diff --git a/runtime/vm/report.cc b/runtime/vm/report.cc
index ac3989d..f681530 100644
--- a/runtime/vm/report.cc
+++ b/runtime/vm/report.cc
@@ -44,7 +44,7 @@
       UNREACHABLE();
   }
   String& result = String::Handle();
-  if (!script.IsNull()) {
+  if (!script.IsNull() && !String::Handle(script.Source()).IsNull()) {
     const String& script_url = String::Handle(script.url());
     if (token_pos.IsReal()) {
       intptr_t line, column, token_len;
diff --git a/runtime/vm/runtime_entry.cc b/runtime/vm/runtime_entry.cc
index 3731a08..eca3f35 100644
--- a/runtime/vm/runtime_entry.cc
+++ b/runtime/vm/runtime_entry.cc
@@ -63,6 +63,7 @@
 DEFINE_FLAG(bool, trace_runtime_calls, false, "Trace runtime calls");
 DEFINE_FLAG(bool, trace_type_checks, false, "Trace runtime type checks.");
 
+DECLARE_FLAG(bool, enable_interpreter);
 DECLARE_FLAG(int, max_deoptimization_counter_threshold);
 DECLARE_FLAG(bool, enable_inlining_annotations);
 DECLARE_FLAG(bool, trace_compiler);
@@ -391,13 +392,9 @@
          instantiator_type_arguments.IsInstantiated());
   ASSERT(function_type_arguments.IsNull() ||
          function_type_arguments.IsInstantiated());
-#if !defined(DART_USE_INTERPRETER)
   // Code inlined in the caller should have optimized the case where the
   // instantiator can be reused as type argument vector.
-  // However, it is non-trivial for the bytecode generator to implement this
-  // optimization, so we do not require it when the interpreter is used.
   ASSERT(!type_arguments.IsUninstantiatedIdentity());
-#endif
   if (isolate->type_checks()) {
     Error& bound_error = Error::Handle(zone);
     type_arguments = type_arguments.InstantiateAndCanonicalizeFrom(
@@ -462,11 +459,8 @@
 // Allocate a new SubtypeTestCache for use in interpreted implicit setters.
 // Return value: newly allocated SubtypeTestCache.
 DEFINE_RUNTIME_ENTRY(AllocateSubtypeTestCache, 0) {
-#if defined(DART_USE_INTERPRETER)
+  ASSERT(FLAG_enable_interpreter);
   arguments.SetReturn(SubtypeTestCache::Handle(zone, SubtypeTestCache::New()));
-#else
-  UNREACHABLE();
-#endif  // defined(DART_USE_INTERPRETER)
 }
 
 // Allocate a new context large enough to hold the given number of variables.
@@ -504,7 +498,7 @@
 // Arg1: method.
 // Return value: newly allocated Closure.
 DEFINE_RUNTIME_ENTRY(ExtractMethod, 2) {
-#if defined(DART_USE_INTERPRETER)
+  ASSERT(FLAG_enable_interpreter);
   const Instance& receiver = Instance::CheckedHandle(zone, arguments.ArgAt(0));
   const Function& method = Function::CheckedHandle(zone, arguments.ArgAt(1));
   const TypeArguments& instantiator_type_arguments =
@@ -519,9 +513,6 @@
       Closure::New(instantiator_type_arguments, Object::null_type_arguments(),
                    Object::empty_type_arguments(), method, context));
   arguments.SetReturn(closure);
-#else
-  UNREACHABLE();
-#endif  // defined(DART_USE_INTERPRETER)
 }
 
 // Result of an invoke may be an unhandled exception, in which case we
@@ -537,7 +528,7 @@
 // Arg1: field name.
 // Return value: field value.
 DEFINE_RUNTIME_ENTRY(GetFieldForDispatch, 2) {
-#if defined(DART_USE_INTERPRETER)
+  ASSERT(FLAG_enable_interpreter);
   const Instance& receiver = Instance::CheckedHandle(zone, arguments.ArgAt(0));
   const String& name = String::CheckedHandle(zone, arguments.ArgAt(1));
   const Class& receiver_class = Class::Handle(zone, receiver.clazz());
@@ -556,16 +547,13 @@
       Object::Handle(zone, DartEntry::InvokeFunction(getter, args));
   CheckResultError(result);
   arguments.SetReturn(result);
-#else
-  UNREACHABLE();
-#endif  // defined(DART_USE_INTERPRETER)
 }
 
 // Resolve 'call' function of receiver.
 // Arg0: receiver (not a closure).
 // Return value: 'call' function'.
 DEFINE_RUNTIME_ENTRY(ResolveCallFunction, 1) {
-#if defined(DART_USE_INTERPRETER)
+  ASSERT(FLAG_enable_interpreter);
   const Instance& receiver = Instance::CheckedHandle(zone, arguments.ArgAt(0));
   ASSERT(!receiver.IsClosure());  // Interpreter tests for closure.
   Class& cls = Class::Handle(zone, receiver.clazz());
@@ -578,9 +566,6 @@
     cls = cls.SuperClass();
   } while (!cls.IsNull());
   arguments.SetReturn(call_function);
-#else
-  UNREACHABLE();
-#endif  // defined(DART_USE_INTERPRETER)
 }
 
 // Helper routine for tracing a type check.
@@ -918,14 +903,14 @@
 
   if (should_update_cache) {
     if (cache.IsNull()) {
-#if defined(DART_USE_INTERPRETER)
-      // TODO(regis): Remove this workaround once the interpreter can provide a
-      // non-null cache for the type test in an implicit setter.
-      if (mode == kTypeCheckFromInline) {
-        arguments.SetReturn(src_instance);
-        return;
+      if (FLAG_enable_interpreter) {
+        // TODO(regis): Remove this workaround once the interpreter can provide
+        // a non-null cache for the type test in an implicit setter.
+        if (mode == kTypeCheckFromInline) {
+          arguments.SetReturn(src_instance);
+          return;
+        }
       }
-#endif  // defined(DART_USE_INTERPRETER)
 
 #if !defined(TARGET_ARCH_DBC) && !defined(TARGET_ARCH_IA32)
       ASSERT(mode == kTypeCheckFromSlowStub);
@@ -1995,9 +1980,13 @@
     for (intptr_t i = 0; i < num_frames; i++) {
       ActivationFrame* frame = stack->FrameAt(i);
 #ifndef DART_PRECOMPILED_RUNTIME
-      // Ensure that we have unoptimized code.
-      frame->function().EnsureHasCompiledUnoptimizedCode();
-      const int num_vars = frame->NumLocalVariables();
+      if (!frame->is_interpreted()) {
+        // Ensure that we have unoptimized code.
+        frame->function().EnsureHasCompiledUnoptimizedCode();
+      }
+      // TODO(regis): Provide var descriptors in kernel bytecode.
+      const int num_vars =
+          frame->is_interpreted() ? 0 : frame->NumLocalVariables();
 #else
       // Variable locations and number are unknown when precompiling.
       const int num_vars = 0;
@@ -2090,14 +2079,16 @@
   }
 
   bool interpreter_stack_overflow = false;
-#if defined(DART_USE_INTERPRETER)
-  // Do not allocate an interpreter, if none is allocated yet.
-  Interpreter* interpreter = Isolate::Current()->interpreter();
-  if (interpreter != NULL) {
-    interpreter_stack_overflow =
-        interpreter->get_sp() >= interpreter->stack_limit();
+#if !defined(DART_PRECOMPILED_RUNTIME)
+  if (FLAG_enable_interpreter) {
+    // Do not allocate an interpreter, if none is allocated yet.
+    Interpreter* interpreter = Isolate::Current()->interpreter();
+    if (interpreter != NULL) {
+      interpreter_stack_overflow =
+          interpreter->get_sp() >= interpreter->stack_limit();
+    }
   }
-#endif
+#endif  // !defined(DART_PRECOMPILED_RUNTIME)
 
   // If an interrupt happens at the same time as a stack overflow, we
   // process the stack overflow now and leave the interrupt for next
@@ -2731,7 +2722,10 @@
                                        intptr_t argc,
                                        RawObject** argv,
                                        Thread* thread) {
-#if defined(DART_USE_INTERPRETER)
+#if defined(DART_PRECOMPILED_RUNTIME)
+  UNREACHABLE();
+#else
+  ASSERT(FLAG_enable_interpreter);
   Interpreter* interpreter = Interpreter::Current();
 #if defined(DEBUG)
   uword exit_fp = thread->top_exit_frame_info();
@@ -2754,9 +2748,7 @@
     Exceptions::PropagateError(Error::Cast(result));
   }
   return result.raw();
-#else
-  UNREACHABLE();
-#endif  // defined(DART_USE_INTERPRETER)
+#endif  // defined(DART_PRECOMPILED_RUNTIME)
 }
 
 }  // namespace dart
diff --git a/runtime/vm/service/service.md b/runtime/vm/service/service.md
index 2810f99..8222047 100644
--- a/runtime/vm/service/service.md
+++ b/runtime/vm/service/service.md
@@ -1021,7 +1021,7 @@
 ```
 class BoundVariable {
   string name;
-  @Instance|Sentinel value;
+  @Instance|@TypeArguments|Sentinel value;
 
   // The token position where this variable was declared.
   int declarationTokenPos;
diff --git a/runtime/vm/service/service_dev.md b/runtime/vm/service/service_dev.md
index 3649b6c..2c4909e 100644
--- a/runtime/vm/service/service_dev.md
+++ b/runtime/vm/service/service_dev.md
@@ -1021,7 +1021,7 @@
 ```
 class BoundVariable {
   string name;
-  @Instance|Sentinel value;
+  @Instance|@TypeArguments|Sentinel value;
 
   // The token position where this variable was declared.
   int declarationTokenPos;
diff --git a/runtime/vm/simulator_arm.cc b/runtime/vm/simulator_arm.cc
index 1fb6ddb..db660f8 100644
--- a/runtime/vm/simulator_arm.cc
+++ b/runtime/vm/simulator_arm.cc
@@ -1386,7 +1386,7 @@
           THR_Print("Call to host function at 0x%" Pd "\n", external);
         }
         if (redirection->call_kind() == kRuntimeCall) {
-          NativeArguments arguments;
+          NativeArguments arguments(NULL, 0, NULL, NULL);
           ASSERT(sizeof(NativeArguments) == 4 * kWordSize);
           arguments.thread_ = reinterpret_cast<Thread*>(get_register(R0));
           arguments.argc_tag_ = get_register(R1);
@@ -1592,8 +1592,8 @@
             // Registers rd, rn, rm, ra are encoded as rn, rm, rs, rd.
             // Format(instr, "mls'cond's 'rn, 'rm, 'rs, 'rd");
             rd_val = get_register(rd);
-            // fall through
           }
+          /* Falls through */
           case 0: {
             // Registers rd, rn, rm are encoded as rn, rm, rs.
             // Format(instr, "mul'cond's 'rn, 'rm, 'rs");
@@ -1650,6 +1650,7 @@
               // umaal is only in ARMv6 and above.
               UnimplementedInstruction(instr);
             }
+            /* Falls through */
           case 5:
           // Registers rd_lo, rd_hi, rn, rm are encoded as rd, rn, rm, rs.
           // Format(instr, "umlal'cond's 'rd, 'rn, 'rm, 'rs");
diff --git a/runtime/vm/simulator_dbc.cc b/runtime/vm/simulator_dbc.cc
index 024d8b1..c9bb744 100644
--- a/runtime/vm/simulator_dbc.cc
+++ b/runtime/vm/simulator_dbc.cc
@@ -202,7 +202,8 @@
     RawSmi* index = static_cast<RawSmi*>(args[1]);
     RawArray* array = static_cast<RawArray*>(args[0]);
     if (CheckIndex(index, array->ptr()->length_)) {
-      array->StorePointer(array->ptr()->data() + Smi::Value(index), args[2]);
+      array->StorePointer(array->ptr()->data() + Smi::Value(index), args[2],
+                          thread);
       return true;
     }
     return false;
@@ -237,7 +238,8 @@
         static_cast<RawGrowableObjectArray*>(args[0]);
     if (CheckIndex(index, array->ptr()->length_)) {
       RawArray* data = array->ptr()->data_;
-      data->StorePointer(data->ptr()->data() + Smi::Value(index), args[2]);
+      data->StorePointer(data->ptr()->data() + Smi::Value(index), args[2],
+                         thread);
       return true;
     }
     return false;
@@ -2627,7 +2629,7 @@
     BYTECODE(StoreStaticTOS, A_D);
     RawField* field = reinterpret_cast<RawField*>(LOAD_CONSTANT(rD));
     RawInstance* value = static_cast<RawInstance*>(*SP--);
-    field->StorePointer(&field->ptr()->value_.static_value_, value);
+    field->StorePointer(&field->ptr()->value_.static_value_, value, thread);
     DISPATCH();
   }
 
@@ -2648,8 +2650,8 @@
     RawObject* value = FP[value_reg];
 
     instance->StorePointer(
-        reinterpret_cast<RawObject**>(instance->ptr()) + offset_in_words,
-        value);
+        reinterpret_cast<RawObject**>(instance->ptr()) + offset_in_words, value,
+        thread);
     DISPATCH();
   }
 
@@ -2661,8 +2663,8 @@
     RawObject* value = FP[rD];
 
     instance->StorePointer(
-        reinterpret_cast<RawObject**>(instance->ptr()) + offset_in_words,
-        value);
+        reinterpret_cast<RawObject**>(instance->ptr()) + offset_in_words, value,
+        thread);
     DISPATCH();
   }
 
@@ -2673,8 +2675,8 @@
     RawObject* value = reinterpret_cast<RawObject*>(SP[0]);
     SP -= 2;  // Drop instance and value.
     instance->StorePointer(
-        reinterpret_cast<RawObject**>(instance->ptr()) + offset_in_words,
-        value);
+        reinterpret_cast<RawObject**>(instance->ptr()) + offset_in_words, value,
+        thread);
 
     DISPATCH();
   }
@@ -3632,7 +3634,8 @@
     RawSmi* index = RAW_CAST(Smi, SP[2]);
     RawObject* value = SP[3];
     ASSERT(SimulatorHelpers::CheckIndex(index, array->ptr()->length_));
-    array->StorePointer(array->ptr()->data() + Smi::Value(index), value);
+    array->StorePointer(array->ptr()->data() + Smi::Value(index), value,
+                        thread);
     DISPATCH();
   }
 
@@ -3642,7 +3645,8 @@
     RawSmi* index = RAW_CAST(Smi, FP[rB]);
     RawObject* value = FP[rC];
     ASSERT(SimulatorHelpers::CheckIndex(index, array->ptr()->length_));
-    array->StorePointer(array->ptr()->data() + Smi::Value(index), value);
+    array->StorePointer(array->ptr()->data() + Smi::Value(index), value,
+                        thread);
     DISPATCH();
   }
 
diff --git a/runtime/vm/source_report.cc b/runtime/vm/source_report.cc
index 2012a2b..50b44d9 100644
--- a/runtime/vm/source_report.cc
+++ b/runtime/vm/source_report.cc
@@ -383,6 +383,11 @@
   const TokenPosition end_pos = func.end_token_pos();
 
   Code& code = Code::Handle(zone(), func.unoptimized_code());
+#if !defined(DART_PRECOMPILED_RUNTIME)
+  if (FLAG_enable_interpreter && code.IsNull() && func.HasBytecode()) {
+    code = func.Bytecode();
+  }
+#endif  // !defined(DART_PRECOMPILED_RUNTIME)
   if (code.IsNull()) {
     if (func.HasCode() || (compile_mode_ == kForceCompile)) {
       const Error& err =
@@ -398,6 +403,11 @@
         return;
       }
       code = func.unoptimized_code();
+#if !defined(DART_PRECOMPILED_RUNTIME)
+      if (FLAG_enable_interpreter && code.IsNull() && func.HasBytecode()) {
+        code = func.Bytecode();
+      }
+#endif  // !defined(DART_PRECOMPILED_RUNTIME)
     } else {
       // This function has not been compiled yet.
       JSONObject range(jsarr);
diff --git a/runtime/vm/stack_frame.cc b/runtime/vm/stack_frame.cc
index 8535bcd..2104353 100644
--- a/runtime/vm/stack_frame.cc
+++ b/runtime/vm/stack_frame.cc
@@ -21,6 +21,8 @@
 
 namespace dart {
 
+DECLARE_FLAG(bool, enable_interpreter);
+
 const FrameLayout invalid_frame_layout = {
     /*.first_object_from_fp = */ -1,
     /*.last_fixed_object_from_fp = */ -1,
@@ -428,9 +430,9 @@
   ASSERT(thread_ != NULL);
   uword exit_marker = thread_->top_exit_frame_info();
   frames_.fp_ = exit_marker;
-#if defined(DART_USE_INTERPRETER)
-  frames_.CheckIfInterpreted(exit_marker);
-#endif
+  if (FLAG_enable_interpreter) {
+    frames_.CheckIfInterpreted(exit_marker);
+  }
 }
 
 void StackFrameIterator::SetupNextExitFrameData() {
@@ -442,9 +444,9 @@
   frames_.fp_ = exit_marker;
   frames_.sp_ = 0;
   frames_.pc_ = 0;
-#if defined(DART_USE_INTERPRETER)
-  frames_.CheckIfInterpreted(exit_marker);
-#endif
+  if (FLAG_enable_interpreter) {
+    frames_.CheckIfInterpreted(exit_marker);
+  }
 }
 
 // Tell MemorySanitizer that generated code initializes part of the stack.
@@ -484,9 +486,9 @@
   frames_.fp_ = last_fp;
   frames_.sp_ = 0;
   frames_.pc_ = 0;
-#if defined(DART_USE_INTERPRETER)
-  frames_.CheckIfInterpreted(last_fp);
-#endif
+  if (FLAG_enable_interpreter) {
+    frames_.CheckIfInterpreted(last_fp);
+  }
 }
 
 #if !defined(TARGET_ARCH_DBC)
@@ -507,9 +509,9 @@
   frames_.fp_ = fp;
   frames_.sp_ = sp;
   frames_.pc_ = pc;
-#if defined(DART_USE_INTERPRETER)
-  frames_.CheckIfInterpreted(fp);
-#endif
+  if (FLAG_enable_interpreter) {
+    frames_.CheckIfInterpreted(fp);
+  }
 }
 #endif
 
@@ -575,16 +577,17 @@
   return current_frame_;
 }
 
-#if defined(DART_USE_INTERPRETER)
 void StackFrameIterator::FrameSetIterator::CheckIfInterpreted(
     uword exit_marker) {
+#if !defined(DART_PRECOMPILED_RUNTIME)
   // TODO(regis): We should rely on a new thread vm_tag to identify an
   // interpreter frame and not need the HasFrame() method.
+  ASSERT(FLAG_enable_interpreter);
   Isolate* isolate = thread_->isolate();
   Interpreter* interpreter = isolate != NULL ? isolate->interpreter() : NULL;
   is_interpreted_ = (interpreter != NULL) && interpreter->HasFrame(exit_marker);
+#endif  // !defined(DART_PRECOMPILED_RUNTIME)
 }
-#endif
 
 StackFrame* StackFrameIterator::FrameSetIterator::NextFrame(bool validate) {
   StackFrame* frame;
@@ -593,15 +596,11 @@
   frame->sp_ = sp_;
   frame->fp_ = fp_;
   frame->pc_ = pc_;
-#if defined(DART_USE_INTERPRETER)
   frame->is_interpreted_ = is_interpreted_;
-#endif
   sp_ = frame->GetCallerSp();
   fp_ = frame->GetCallerFp();
   pc_ = frame->GetCallerPc();
-#if defined(DART_USE_INTERPRETER)
   ASSERT(is_interpreted_ == frame->is_interpreted_);
-#endif
   ASSERT(!validate || frame->IsValid());
   return frame;
 }
@@ -610,15 +609,11 @@
   exit_.sp_ = frames_.sp_;
   exit_.fp_ = frames_.fp_;
   exit_.pc_ = frames_.pc_;
-#if defined(DART_USE_INTERPRETER)
   exit_.is_interpreted_ = frames_.is_interpreted_;
-#endif
   frames_.sp_ = exit_.GetCallerSp();
   frames_.fp_ = exit_.GetCallerFp();
   frames_.pc_ = exit_.GetCallerPc();
-#if defined(DART_USE_INTERPRETER)
   ASSERT(frames_.is_interpreted_ == exit_.is_interpreted_);
-#endif
   ASSERT(!validate_ || exit_.IsValid());
   return &exit_;
 }
@@ -628,9 +623,7 @@
   entry_.sp_ = frames_.sp_;
   entry_.fp_ = frames_.fp_;
   entry_.pc_ = frames_.pc_;
-#if defined(DART_USE_INTERPRETER)
   entry_.is_interpreted_ = frames_.is_interpreted_;
-#endif
   SetupNextExitFrameData();  // Setup data for next exit frame in chain.
   ASSERT(!validate_ || entry_.IsValid());
   return &entry_;
diff --git a/runtime/vm/stack_frame.h b/runtime/vm/stack_frame.h
index 92ceedb..58dcc56 100644
--- a/runtime/vm/stack_frame.h
+++ b/runtime/vm/stack_frame.h
@@ -161,11 +161,7 @@
   virtual bool IsStubFrame() const;
   virtual bool IsEntryFrame() const { return false; }
   virtual bool IsExitFrame() const { return false; }
-#if defined(DART_USE_INTERPRETER)
   virtual bool is_interpreted() const { return is_interpreted_; }
-#else
-  virtual bool is_interpreted() const { return false; }
-#endif
 
   RawFunction* LookupDartFunction() const;
   RawCode* LookupDartCode() const;
@@ -179,13 +175,8 @@
 
  protected:
   explicit StackFrame(Thread* thread)
-#if defined(DART_USE_INTERPRETER)
       : fp_(0), sp_(0), pc_(0), thread_(thread), is_interpreted_(false) {
   }
-#else
-      : fp_(0), sp_(0), pc_(0), thread_(thread) {
-  }
-#endif
 
   // Name of the frame, used for generic frame printing functionality.
   virtual const char* GetName() const {
@@ -229,9 +220,7 @@
   uword sp_;
   uword pc_;
   Thread* thread_;
-#if defined(DART_USE_INTERPRETER)
   bool is_interpreted_;
-#endif
 
   // The iterators FrameSetIterator and StackFrameIterator set the private
   // fields fp_ and sp_ when they return the respective frame objects.
@@ -349,7 +338,6 @@
     StackFrame* NextFrame(bool validate);
 
    private:
-#if defined(DART_USE_INTERPRETER)
     explicit FrameSetIterator(Thread* thread)
         : fp_(0),
           sp_(0),
@@ -359,20 +347,13 @@
           is_interpreted_(false) {}
     bool is_interpreted() const { return is_interpreted_; }
     void CheckIfInterpreted(uword exit_marker);
-#else
-    explicit FrameSetIterator(Thread* thread)
-        : fp_(0), sp_(0), pc_(0), stack_frame_(thread), thread_(thread) {}
-    bool is_interpreted() const { return false; }
-#endif
 
     uword fp_;
     uword sp_;
     uword pc_;
     StackFrame stack_frame_;  // Singleton frame returned by NextFrame().
     Thread* thread_;
-#if defined(DART_USE_INTERPRETER)
     bool is_interpreted_;
-#endif
 
     friend class StackFrameIterator;
     DISALLOW_COPY_AND_ASSIGN(FrameSetIterator);
@@ -393,9 +374,7 @@
   void SetupLastExitFrameData();
   void SetupNextExitFrameData();
 
-#if defined(DART_USE_INTERPRETER)
   void CheckInterpreterExitFrame(uword exit_marker);
-#endif
 
   bool validate_;     // Validate each frame as we traverse the frames.
   EntryFrame entry_;  // Singleton entry frame returned by NextEntryFrame().
diff --git a/runtime/vm/stack_frame_kbc.h b/runtime/vm/stack_frame_kbc.h
index 8a6063e..8bfe809 100644
--- a/runtime/vm/stack_frame_kbc.h
+++ b/runtime/vm/stack_frame_kbc.h
@@ -46,6 +46,7 @@
 static const int kKBCCallerSpSlotFromFp = -kKBCDartFrameFixedSize - 1;
 static const int kKBCPcMarkerSlotFromFp = -3;
 static const int kKBCFunctionSlotFromFp = -4;
+static const int kKBCParamEndSlotFromFp = 4;
 
 // Entry and exit frame layout.
 static const int kKBCEntrySavedSlots = 3;
diff --git a/runtime/vm/stub_code.cc b/runtime/vm/stub_code.cc
index 8b1a357..759469a 100644
--- a/runtime/vm/stub_code.cc
+++ b/runtime/vm/stub_code.cc
@@ -20,6 +20,8 @@
 
 DEFINE_FLAG(bool, disassemble_stubs, false, "Disassemble generated stubs.");
 
+DECLARE_FLAG(bool, enable_interpreter);
+
 StubEntry* StubCode::entries_[kNumStubEntries] = {
 #define STUB_CODE_DECLARE(name) NULL,
     VM_STUB_CODE_LIST(STUB_CODE_DECLARE)
@@ -90,25 +92,30 @@
 bool StubCode::InInvocationStub(uword pc, bool is_interpreted_frame) {
 #if !defined(TARGET_ARCH_DBC)
   ASSERT(HasBeenInitialized());
-#if defined(DART_USE_INTERPRETER)
-  if (is_interpreted_frame) {
-    // Recognize special marker set up by interpreter in entry frame.
-    return (pc & 2) != 0;
-  }
-  {
-    uword entry = StubCode::InvokeDartCodeFromBytecode_entry()->EntryPoint();
-    uword size = StubCode::InvokeDartCodeFromBytecodeSize();
-    if ((pc >= entry) && (pc < (entry + size))) {
-      return true;
+#if !defined(DART_PRECOMPILED_RUNTIME)
+  if (FLAG_enable_interpreter) {
+    if (is_interpreted_frame) {
+      // Recognize special marker set up by interpreter in entry frame.
+      return (pc & 2) != 0;
+    }
+    {
+      uword entry = StubCode::InvokeDartCodeFromBytecode_entry()->EntryPoint();
+      uword size = StubCode::InvokeDartCodeFromBytecodeSize();
+      if ((pc >= entry) && (pc < (entry + size))) {
+        return true;
+      }
     }
   }
-#endif
+#endif  // !defined(DART_PRECOMPILED_RUNTIME)
   uword entry = StubCode::InvokeDartCode_entry()->EntryPoint();
   uword size = StubCode::InvokeDartCodeSize();
   return (pc >= entry) && (pc < (entry + size));
-#elif defined(DART_USE_INTERPRETER)
-#error "Simultaneous usage of DBC simulator and interpreter not yet supported."
 #else
+  if (FLAG_enable_interpreter) {
+    FATAL(
+        "Simultaneous usage of DBC simulator "
+        "and interpreter not yet supported.");
+  }
   // On DBC we use a special marker PC to signify entry frame because there is
   // no such thing as invocation stub.
   return (pc & 2) != 0;
diff --git a/runtime/vm/stub_code.h b/runtime/vm/stub_code.h
index 5dc798b..73ff3dd 100644
--- a/runtime/vm/stub_code.h
+++ b/runtime/vm/stub_code.h
@@ -21,13 +21,13 @@
 // List of stubs created in the VM isolate, these stubs are shared by different
 // isolates running in this dart process.
 #if !defined(TARGET_ARCH_DBC)
-#define VM_STUB_CODE_LIST_ARCH_INDEPENDENT(V)                                  \
+#define VM_STUB_CODE_LIST(V)                                                   \
   V(GetCStackPointer)                                                          \
   V(JumpToFrame)                                                               \
   V(RunExceptionHandler)                                                       \
   V(DeoptForRewind)                                                            \
-  V(UpdateStoreBuffer)                                                         \
-  V(UpdateStoreBufferWrappers)                                                 \
+  V(WriteBarrier)                                                              \
+  V(WriteBarrierWrappers)                                                      \
   V(PrintStopMessage)                                                          \
   V(AllocateArray)                                                             \
   V(AllocateContext)                                                           \
@@ -83,22 +83,11 @@
   V(NullErrorSharedWithFPURegs)                                                \
   V(NullErrorSharedWithoutFPURegs)                                             \
   V(StackOverflowSharedWithFPURegs)                                            \
-  V(StackOverflowSharedWithoutFPURegs)
-
-#if defined(TARGET_ARCH_X64)
-#define VM_STUB_CODE_LIST_ARCH_SPECIFIC(V)                                     \
+  V(StackOverflowSharedWithoutFPURegs)                                         \
   V(OneArgCheckInlineCacheWithExactnessCheck)                                  \
   V(OneArgOptimizedCheckInlineCacheWithExactnessCheck)
 
 #else
-#define VM_STUB_CODE_LIST_ARCH_SPECIFIC(V)
-#endif
-
-#define VM_STUB_CODE_LIST(V)                                                   \
-  VM_STUB_CODE_LIST_ARCH_INDEPENDENT(V)                                        \
-  VM_STUB_CODE_LIST_ARCH_SPECIFIC(V)
-
-#else
 #define VM_STUB_CODE_LIST(V)                                                   \
   V(LazyCompile)                                                               \
   V(OptimizeFunction)                                                          \
@@ -116,7 +105,9 @@
   V(SlowTypeTest)                                                              \
   V(LazySpecializeTypeTest)                                                    \
   V(FrameAwaitingMaterialization)                                              \
-  V(AsynchronousGapMarker)
+  V(AsynchronousGapMarker)                                                     \
+  V(InvokeDartCodeFromBytecode)                                                \
+  V(InterpretCall)
 
 #endif  // !defined(TARGET_ARCH_DBC)
 
diff --git a/runtime/vm/stub_code_arm.cc b/runtime/vm/stub_code_arm.cc
index 89b2acf..d00c0f6 100644
--- a/runtime/vm/stub_code_arm.cc
+++ b/runtime/vm/stub_code_arm.cc
@@ -121,11 +121,6 @@
 
   // We want the saved registers to appear like part of the caller's frame, so
   // we push them before calling EnterStubFrame.
-  //
-  // TODO(sjindel): We could skip saving LR (and thus remove one bit from the
-  // stackmap of the callsite), but this would add ARM-specific complexity to
-  // FlowGraphCompiler::RecordSafepoint and
-  // FlowGraphCompiler::SlowPathEnvironmentFor.
   RegisterSet all_registers;
   all_registers.AddAllNonReservedRegisters(save_fpu_registers);
   __ PushRegisters(all_registers);
@@ -399,8 +394,7 @@
   __ LeaveStubFrame();
   // Jump to the dart function.
   __ mov(CODE_REG, Operand(R0));
-  __ ldr(R0, FieldAddress(R0, Code::entry_point_offset()));
-  __ bx(R0);
+  __ Branch(FieldAddress(R0, Code::entry_point_offset()));
 }
 
 // Called from a static call only when an invalid code has been entered
@@ -424,8 +418,7 @@
   __ LeaveStubFrame();
   // Jump to the dart function.
   __ mov(CODE_REG, Operand(R0));
-  __ ldr(R0, FieldAddress(R0, Code::entry_point_offset()));
-  __ bx(R0);
+  __ Branch(FieldAddress(R0, Code::entry_point_offset()));
 }
 
 // Called from object allocate instruction when the allocation stub has been
@@ -446,8 +439,7 @@
   __ LeaveStubFrame();
   // Jump to the dart function.
   __ mov(CODE_REG, Operand(R0));
-  __ ldr(R0, FieldAddress(R0, Code::entry_point_offset()));
-  __ bx(R0);
+  __ Branch(FieldAddress(R0, Code::entry_point_offset()));
 }
 
 // Input parameters:
@@ -471,9 +463,9 @@
   __ b(&enter);
   Label loop;
   __ Bind(&loop);
-  __ ldr(IP, Address(R1, kWordSize, Address::PreIndex));
+  __ ldr(R8, Address(R1, kWordSize, Address::PreIndex));
   // Generational barrier is needed, array is not necessarily in new space.
-  __ StoreIntoObject(R0, Address(R3, R2, LSL, 1), IP);
+  __ StoreIntoObject(R0, Address(R3, R2, LSL, 1), R8);
   __ Bind(&enter);
   __ subs(R2, R2, Operand(Smi::RawValue(1)));  // R2 is Smi.
   __ b(&loop, PL);
@@ -509,18 +501,7 @@
                                            DeoptStubKind kind) {
   // DeoptimizeCopyFrame expects a Dart frame, i.e. EnterDartFrame(0), but there
   // is no need to set the correct PC marker or load PP, since they get patched.
-
-  // IP has the potentially live LR value. LR was clobbered by the call with
-  // the return address, so move it into IP to set up the Dart frame.
-  __ eor(IP, IP, Operand(LR));
-  __ eor(LR, IP, Operand(LR));
-  __ eor(IP, IP, Operand(LR));
-
-  // Set up the frame manually with return address now stored in IP.
-  COMPILE_ASSERT(PP < CODE_REG);
-  COMPILE_ASSERT(CODE_REG < FP);
-  COMPILE_ASSERT(FP < IP);
-  __ EnterFrame((1 << PP) | (1 << CODE_REG) | (1 << FP) | (1 << IP), 0);
+  __ EnterDartFrame(0);
   __ LoadPoolPointer();
 
   // The code in this frame may not cause GC. kDeoptimizeCopyFrameRuntimeEntry
@@ -739,8 +720,7 @@
 
   // Tail-call to target function.
   __ ldr(CODE_REG, FieldAddress(R0, Function::code_offset()));
-  __ ldr(R2, FieldAddress(R0, Function::entry_point_offset()));
-  __ bx(R2);
+  __ Branch(FieldAddress(R0, Function::entry_point_offset()));
 }
 
 // Called for inline allocation of arrays.
@@ -754,7 +734,7 @@
   // Compute the size to be allocated, it is based on the array length
   // and is computed as:
   // RoundedAllocationSize((array_length * kwordSize) + sizeof(RawArray)).
-  __ MoveRegister(R3, R2);  // Array length.
+  __ mov(R3, Operand(R2));  // Array length.
   // Check that length is a positive Smi.
   __ tst(R3, Operand(kSmiTagMask));
   if (FLAG_use_slow_path) {
@@ -1116,7 +1096,7 @@
   __ Ret();
 }
 
-void StubCode::GenerateUpdateStoreBufferWrappersStub(Assembler* assembler) {
+void StubCode::GenerateWriteBarrierWrappersStub(Assembler* assembler) {
   RegList saved = (1 << LR) | (1 << R0);
   for (intptr_t i = 0; i < kNumberOfCpuRegisters; ++i) {
     if ((kDartAvailableCpuRegs & (1 << i)) == 0) continue;
@@ -1125,7 +1105,7 @@
     intptr_t start = __ CodeSize();
     __ PushList(saved);
     __ mov(R0, Operand(reg));
-    __ ldr(LR, Address(THR, Thread::update_store_buffer_entry_point_offset()));
+    __ ldr(LR, Address(THR, Thread::write_barrier_entry_point_offset()));
     __ blx(LR);
     __ PopList(saved);
     __ bx(LR);
@@ -1137,8 +1117,16 @@
 
 // Helper stub to implement Assembler::StoreIntoObject.
 // Input parameters:
-//   R0: address (i.e. object) being stored into.
-void StubCode::GenerateUpdateStoreBufferStub(Assembler* assembler) {
+//   R0: Source object (old)
+//  TMP: Target object (old or new)
+// If TMP is new, add R0 to the store buffer. Otherwise TMP is old, mark TMP
+// and add it to the mark list.
+void StubCode::GenerateWriteBarrierStub(Assembler* assembler) {
+#if defined(CONCURRENT_MARKING)
+  Label add_to_mark_stack;
+  __ tst(TMP, Operand(1 << kNewObjectBitPosition));
+  __ b(&add_to_mark_stack, ZERO);
+#else
   Label add_to_buffer;
   // Check whether this object has already been remembered. Skip adding to the
   // store buffer if the object is in the store buffer already.
@@ -1150,16 +1138,17 @@
   __ Ret();
 
   __ Bind(&add_to_buffer);
+#endif
 
   // Save values being destroyed.
   __ PushList((1 << R1) | (1 << R2) | (1 << R3));
 
-  // R2: Header word.
   if (TargetCPUFeatures::arm_version() == ARMv5TE) {
 // TODO(21263): Implement 'swp' and use it below.
 #if !defined(USING_SIMULATOR)
     ASSERT(OS::NumberOfAvailableProcessors() <= 1);
 #endif
+    __ ldr(R2, FieldAddress(R0, Object::tags_offset()));
     __ bic(R2, R2, Operand(1 << RawObject::kOldAndNotRememberedBit));
     __ str(R2, FieldAddress(R0, Object::tags_offset()));
   } else {
@@ -1180,7 +1169,7 @@
   // StoreBufferBlock and add the address to the pointers_.
   __ ldr(R1, Address(THR, Thread::store_buffer_block_offset()));
   __ ldr(R2, Address(R1, StoreBufferBlock::top_offset()));
-  __ add(R3, R1, Operand(R2, LSL, 2));
+  __ add(R3, R1, Operand(R2, LSL, kWordSizeLog2));
   __ str(R0, Address(R3, StoreBufferBlock::pointers_offset()));
 
   // Increment top_ and check for overflow.
@@ -1200,7 +1189,7 @@
   // Setup frame, push callee-saved registers.
 
   __ Push(CODE_REG);
-  __ ldr(CODE_REG, Address(THR, Thread::update_store_buffer_code_offset()));
+  __ ldr(CODE_REG, Address(THR, Thread::write_barrier_code_offset()));
   __ EnterCallRuntimeFrame(0 * kWordSize);
   __ mov(R0, Operand(THR));
   __ CallRuntime(kStoreBufferBlockProcessRuntimeEntry, 1);
@@ -1208,6 +1197,11 @@
   __ LeaveCallRuntimeFrame();
   __ Pop(CODE_REG);
   __ Ret();
+
+#if defined(CONCURRENT_MARKING)
+  __ Bind(&add_to_mark_stack);
+  __ Stop("Incremental barrier");
+#endif
 }
 
 // Called for inline allocation of objects.
@@ -1220,126 +1214,103 @@
   const bool is_cls_parameterized = cls.NumTypeArguments() > 0;
   ASSERT(!is_cls_parameterized ||
          (cls.type_arguments_field_offset() != Class::kNoTypeArguments));
+
+  const Register kNullReg = R8;
+  const Register kOtherNullReg = R9;
+  const Register kTypeArgumentsReg = R3;
+  const Register kInstanceReg = R0;
+  const Register kEndReg = R1;
+  const Register kEndOfInstanceReg = R2;
+
   // kInlineInstanceSize is a constant used as a threshold for determining
   // when the object initialization should be done as a loop or as
   // straight line code.
   const int kInlineInstanceSize = 12;
   const intptr_t instance_size = cls.instance_size();
   ASSERT(instance_size > 0);
+  ASSERT(instance_size % kObjectAlignment == 0);
+  if (is_cls_parameterized) {
+    __ ldr(kTypeArgumentsReg, Address(SP, 0));
+  }
   Isolate* isolate = Isolate::Current();
+
+  __ LoadObject(kNullReg, Object::null_object());
   if (FLAG_inline_alloc && Heap::IsAllocatableInNewSpace(instance_size) &&
       !cls.TraceAllocation(isolate)) {
     Label slow_case;
+
     // Allocate the object and update top to point to
     // next object start and initialize the allocated object.
     NOT_IN_PRODUCT(Heap::Space space = Heap::kNew);
-    __ ldr(R0, Address(THR, Thread::top_offset()));
-    __ AddImmediate(R1, R0, instance_size);
-    // Check if the allocation fits into the remaining space.
-    // R0: potential new object start.
-    // R1: potential next object start.
-    __ ldr(IP, Address(THR, Thread::end_offset()));
-    __ cmp(R1, Operand(IP));
+
+    RELEASE_ASSERT((Thread::top_offset() + kWordSize) == Thread::end_offset());
+    __ ldrd(kInstanceReg, kEndReg, THR, Thread::top_offset());
+    __ AddImmediate(kEndOfInstanceReg, kInstanceReg, instance_size);
+    __ cmp(kEndOfInstanceReg, Operand(kEndReg));
     if (FLAG_use_slow_path) {
       __ b(&slow_case);
     } else {
       __ b(&slow_case, CS);  // Unsigned higher or equal.
     }
-    __ str(R1, Address(THR, Thread::top_offset()));
+    __ str(kEndOfInstanceReg, Address(THR, Thread::top_offset()));
 
     // Load the address of the allocation stats table. We split up the load
     // and the increment so that the dependent load is not too nearby.
-    NOT_IN_PRODUCT(__ LoadAllocationStatsAddress(R9, cls.id()));
+    NOT_IN_PRODUCT(static Register kAllocationStatsReg = R4);
+    NOT_IN_PRODUCT(
+        __ LoadAllocationStatsAddress(kAllocationStatsReg, cls.id()));
 
-    // R0: new object start.
-    // R1: next object start.
-    // R9: allocation stats table.
     // Set the tags.
     uint32_t tags = 0;
     tags = RawObject::SizeTag::update(instance_size, tags);
     ASSERT(cls.id() != kIllegalCid);
     tags = RawObject::ClassIdTag::update(cls.id(), tags);
     tags = RawObject::NewBit::update(true, tags);
-    __ LoadImmediate(R2, tags);
-    __ str(R2, Address(R0, Instance::tags_offset()));
-    __ add(R0, R0, Operand(kHeapObjectTag));
+    __ LoadImmediate(R1, tags);
+    __ str(R1, Address(kInstanceReg, Instance::tags_offset()));
+    __ add(kInstanceReg, kInstanceReg, Operand(kHeapObjectTag));
 
-    // Initialize the remaining words of the object.
-    __ LoadObject(R2, Object::null_object());
-
-    // R2: raw null.
-    // R0: new object (tagged).
-    // R1: next object start.
-    // R9: allocation stats table.
     // First try inlining the initialization without a loop.
     if (instance_size < (kInlineInstanceSize * kWordSize)) {
-      // Small objects are initialized using a consecutive set of writes.
       intptr_t begin_offset = Instance::NextFieldOffset() - kHeapObjectTag;
       intptr_t end_offset = instance_size - kHeapObjectTag;
-      // Save one move if less than two fields.
       if ((end_offset - begin_offset) >= (2 * kWordSize)) {
-        __ mov(R3, Operand(R2));
+        __ mov(kOtherNullReg, Operand(kNullReg));
       }
-      __ InitializeFieldsNoBarrierUnrolled(R0, R0, begin_offset, end_offset, R2,
-                                           R3);
+      __ InitializeFieldsNoBarrierUnrolled(kInstanceReg, kInstanceReg,
+                                           begin_offset, end_offset, kNullReg,
+                                           kOtherNullReg);
     } else {
-      // There are more than kInlineInstanceSize(12) fields
-      __ add(R4, R0, Operand(Instance::NextFieldOffset() - kHeapObjectTag));
-      __ mov(R3, Operand(R2));
-      // Loop until the whole object is initialized.
-      // R2: raw null.
-      // R3: raw null.
-      // R0: new object (tagged).
-      // R1: next object start.
-      // R4: next word to be initialized.
-      // R9: allocation stats table.
-      __ InitializeFieldsNoBarrier(R0, R4, R1, R2, R3);
+      __ add(R1, kInstanceReg,
+             Operand(Instance::NextFieldOffset() - kHeapObjectTag));
+      __ mov(kOtherNullReg, Operand(kNullReg));
+      __ InitializeFieldsNoBarrier(kInstanceReg, R1, kEndOfInstanceReg,
+                                   kNullReg, kOtherNullReg);
     }
     if (is_cls_parameterized) {
-      // Set the type arguments in the new object.
-      __ ldr(R4, Address(SP, 0));
-      FieldAddress type_args(R0, cls.type_arguments_field_offset());
-      __ StoreIntoObjectNoBarrier(R0, type_args, R4);
+      __ StoreIntoObjectNoBarrier(
+          kInstanceReg,
+          FieldAddress(kInstanceReg, cls.type_arguments_field_offset()),
+          kTypeArgumentsReg);
     }
 
-    // Done allocating and initializing the instance.
-    // R0: new object (tagged).
-    // R9: allocation stats table.
-
     // Update allocation stats.
-    NOT_IN_PRODUCT(__ IncrementAllocationStats(R9, cls.id(), space));
+    NOT_IN_PRODUCT(
+        __ IncrementAllocationStats(kAllocationStatsReg, cls.id(), space));
 
-    // R0: new object (tagged).
     __ Ret();
-
     __ Bind(&slow_case);
   }
-  if (is_cls_parameterized) {
-    // Load the type arguments.
-    __ ldr(R4, Address(SP, 0));
-  }
-  // If is_cls_parameterized:
-  // R4: new object type arguments.
   // Create a stub frame as we are pushing some objects on the stack before
   // calling into the runtime.
   __ EnterStubFrame();  // Uses pool pointer to pass cls to runtime.
-  __ LoadObject(R2, Object::null_object());
-  __ Push(R2);         // Setup space on stack for return value.
-  __ PushObject(cls);  // Push class of object to be allocated.
-  if (is_cls_parameterized) {
-    // Push type arguments.
-    __ Push(R4);
-  } else {
-    // Push null type arguments.
-    __ Push(R2);
-  }
+  __ LoadObject(R1, cls);
+  __ PushList(1 << kNullReg | 1 << R1);  // Pushes cls, result slot.
+  __ Push(is_cls_parameterized ? kTypeArgumentsReg : kNullReg);
   __ CallRuntime(kAllocateObjectRuntimeEntry, 2);  // Allocate object.
-  __ Drop(2);                                      // Pop arguments.
-  __ Pop(R0);  // Pop result (newly allocated object).
-  // R0: new object
-  // Restore the frame pointer.
-  __ LeaveStubFrame();
-  __ Ret();
+  __ ldr(kInstanceReg,
+         Address(SP, 2 * kWordSize));  // Pop result (newly allocated object).
+  __ LeaveDartFrameAndReturn();        // Restores correct SP.
 }
 
 // Called for invoking "dynamic noSuchMethod(Invocation invocation)" function
@@ -1639,9 +1610,8 @@
   __ Comment("Call target");
   __ Bind(&call_target_function);
   // R0: target function.
-  __ ldr(R2, FieldAddress(R0, Function::entry_point_offset()));
   __ ldr(CODE_REG, FieldAddress(R0, Function::code_offset()));
-  __ bx(R2);
+  __ Branch(FieldAddress(R0, Function::entry_point_offset()));
 
 #if !defined(PRODUCT)
   if (!optimized) {
@@ -1673,6 +1643,11 @@
       assembler, 1, kInlineCacheMissHandlerOneArgRuntimeEntry, Token::kILLEGAL);
 }
 
+void StubCode::GenerateOneArgCheckInlineCacheWithExactnessCheckStub(
+    Assembler* assembler) {
+  __ Stop("Unimplemented");
+}
+
 void StubCode::GenerateTwoArgsCheckInlineCacheStub(Assembler* assembler) {
   GenerateUsageCounterIncrement(assembler, R8);
   GenerateNArgsCheckInlineCacheStub(assembler, 2,
@@ -1706,6 +1681,11 @@
                                     Token::kILLEGAL, true /* optimized */);
 }
 
+void StubCode::GenerateOneArgOptimizedCheckInlineCacheWithExactnessCheckStub(
+    Assembler* assembler) {
+  __ Stop("Unimplemented");
+}
+
 void StubCode::GenerateTwoArgsOptimizedCheckInlineCacheStub(
     Assembler* assembler) {
   GenerateOptimizedUsageCounterIncrement(assembler);
@@ -1765,8 +1745,7 @@
   // Get function and call it, if possible.
   __ LoadFromOffset(kWord, R0, R8, target_offset);
   __ ldr(CODE_REG, FieldAddress(R0, Function::code_offset()));
-  __ ldr(R2, FieldAddress(R0, Function::entry_point_offset()));
-  __ bx(R2);
+  __ Branch(FieldAddress(R0, Function::entry_point_offset()));
 
 #if !defined(PRODUCT)
   __ Bind(&stepping);
@@ -1805,8 +1784,7 @@
   // When using the interpreter, the function's code may now point to the
   // InterpretCall stub. Make sure R0, R4, and R9 are preserved.
   __ ldr(CODE_REG, FieldAddress(R0, Function::code_offset()));
-  __ ldr(R2, FieldAddress(R0, Function::entry_point_offset()));
-  __ bx(R2);
+  __ Branch(FieldAddress(R0, Function::entry_point_offset()));
 }
 
 void StubCode::GenerateInterpretCallStub(Assembler* assembler) {
@@ -1823,8 +1801,7 @@
   __ PopList((1 << R0) | (1 << R9));
   __ LeaveStubFrame();
   __ mov(CODE_REG, Operand(R0));
-  __ ldr(R0, FieldAddress(CODE_REG, Code::entry_point_offset()));
-  __ bx(R0);
+  __ Branch(FieldAddress(CODE_REG, Code::entry_point_offset()));
 }
 
 void StubCode::GenerateRuntimeCallBreakpointStub(Assembler* assembler) {
@@ -1835,8 +1812,7 @@
   __ CallRuntime(kBreakpointRuntimeHandlerRuntimeEntry, 0);
   __ PopList((1 << CODE_REG));
   __ LeaveStubFrame();
-  __ ldr(R0, FieldAddress(CODE_REG, Code::entry_point_offset()));
-  __ bx(R0);
+  __ Branch(FieldAddress(CODE_REG, Code::entry_point_offset()));
 }
 
 // Called only from unoptimized code. All relevant registers have been saved.
@@ -2064,8 +2040,7 @@
   __ BranchIf(EQUAL, &done);
 
   __ ldr(CODE_REG, Address(THR, Thread::slow_type_test_stub_offset()));
-  __ ldr(R9, FieldAddress(CODE_REG, Code::entry_point_offset()));
-  __ bx(R9);
+  __ Branch(FieldAddress(CODE_REG, Code::entry_point_offset()));
 
   __ Bind(&done);
   __ Ret();
@@ -2097,8 +2072,7 @@
                                       kInstanceReg, kClassIdReg);
 
   __ ldr(CODE_REG, Address(THR, Thread::slow_type_test_stub_offset()));
-  __ ldr(TMP, FieldAddress(CODE_REG, Code::entry_point_offset()));
-  __ bx(TMP);
+  __ Branch(FieldAddress(CODE_REG, Code::entry_point_offset()));
 }
 
 void TypeTestingStubGenerator::
@@ -2364,8 +2338,7 @@
   __ Pop(R4);  // Restore argument descriptor.
   __ LeaveStubFrame();
   __ ldr(CODE_REG, FieldAddress(R0, Function::code_offset()));
-  __ ldr(R1, FieldAddress(R0, Function::entry_point_offset()));
-  __ bx(R1);
+  __ Branch(FieldAddress(R0, Function::entry_point_offset()));
   __ bkpt(0);
 }
 
@@ -2510,9 +2483,8 @@
   // be invoked as a normal Dart function.
   __ ldr(R0, FieldAddress(IP, base + kWordSize));
   __ ldr(R4, FieldAddress(R9, MegamorphicCache::arguments_descriptor_offset()));
-  __ ldr(R1, FieldAddress(R0, Function::entry_point_offset()));
   __ ldr(CODE_REG, FieldAddress(R0, Function::code_offset()));
-  __ bx(R1);
+  __ Branch(FieldAddress(R0, Function::entry_point_offset()));
 
   // Probe failed, check if it is a miss.
   __ Bind(&probe_failed);
@@ -2555,15 +2527,13 @@
   __ Bind(&found);
   const intptr_t target_offset = ICData::TargetIndexFor(1) * kWordSize;
   __ LoadFromOffset(kWord, R0, R8, target_offset);
-  __ ldr(R1, FieldAddress(R0, Function::entry_point_offset()));
   __ ldr(CODE_REG, FieldAddress(R0, Function::code_offset()));
-  __ bx(R1);
+  __ Branch(FieldAddress(R0, Function::entry_point_offset()));
 
   __ Bind(&miss);
   __ LoadIsolate(R2);
   __ ldr(CODE_REG, Address(R2, Isolate::ic_miss_code_offset()));
-  __ ldr(R1, FieldAddress(CODE_REG, Code::entry_point_offset()));
-  __ bx(R1);
+  __ Branch(FieldAddress(CODE_REG, Code::entry_point_offset()));
 }
 
 void StubCode::GenerateICCallThroughCodeStub(Assembler* assembler) {
@@ -2590,15 +2560,13 @@
   __ Bind(&found);
   const intptr_t code_offset = ICData::CodeIndexFor(1) * kWordSize;
   const intptr_t entry_offset = ICData::EntryPointIndexFor(1) * kWordSize;
-  __ ldr(R1, Address(R8, entry_offset));
   __ ldr(CODE_REG, Address(R8, code_offset));
-  __ bx(R1);
+  __ Branch(Address(R8, entry_offset));
 
   __ Bind(&miss);
   __ LoadIsolate(R2);
   __ ldr(CODE_REG, Address(R2, Isolate::ic_miss_code_offset()));
-  __ ldr(R1, FieldAddress(CODE_REG, Code::entry_point_offset()));
-  __ bx(R1);
+  __ Branch(FieldAddress(CODE_REG, Code::entry_point_offset()));
 }
 
 // Called from switchable IC calls.
@@ -2620,9 +2588,8 @@
   __ LeaveStubFrame();
 
   __ ldr(CODE_REG, Address(THR, Thread::ic_lookup_through_code_stub_offset()));
-  __ ldr(R1, FieldAddress(CODE_REG, Code::entry_point_offset(
-                                        Code::EntryKind::kMonomorphic)));
-  __ bx(R1);
+  __ Branch(FieldAddress(
+      CODE_REG, Code::entry_point_offset(Code::EntryKind::kMonomorphic)));
 }
 
 // Called from switchable IC calls.
@@ -2641,9 +2608,8 @@
   __ cmp(R1, Operand(R3));
   __ b(&miss, GT);
 
-  __ ldr(R1, FieldAddress(R9, SingleTargetCache::entry_point_offset()));
   __ ldr(CODE_REG, FieldAddress(R9, SingleTargetCache::target_offset()));
-  __ bx(R1);
+  __ Branch(FieldAddress(R9, SingleTargetCache::entry_point_offset()));
 
   __ Bind(&miss);
   __ EnterStubFrame();
@@ -2660,9 +2626,8 @@
   __ LeaveStubFrame();
 
   __ ldr(CODE_REG, Address(THR, Thread::ic_lookup_through_code_stub_offset()));
-  __ ldr(R1, FieldAddress(CODE_REG, Code::entry_point_offset(
-                                        Code::EntryKind::kMonomorphic)));
-  __ bx(R1);
+  __ Branch(FieldAddress(
+      CODE_REG, Code::entry_point_offset(Code::EntryKind::kMonomorphic)));
 }
 
 // Called from the monomorphic checked entry.
@@ -2683,9 +2648,8 @@
   __ LeaveStubFrame();
 
   __ ldr(CODE_REG, Address(THR, Thread::ic_lookup_through_code_stub_offset()));
-  __ ldr(R1, FieldAddress(CODE_REG, Code::entry_point_offset(
-                                        Code::EntryKind::kMonomorphic)));
-  __ bx(R1);
+  __ Branch(FieldAddress(
+      CODE_REG, Code::entry_point_offset(Code::EntryKind::kMonomorphic)));
 }
 
 void StubCode::GenerateFrameAwaitingMaterializationStub(Assembler* assembler) {
diff --git a/runtime/vm/stub_code_arm64.cc b/runtime/vm/stub_code_arm64.cc
index 306900e..c63f0e8 100644
--- a/runtime/vm/stub_code_arm64.cc
+++ b/runtime/vm/stub_code_arm64.cc
@@ -28,6 +28,7 @@
             false,
             "Set to true for debugging & verifying the slow paths.");
 DECLARE_FLAG(bool, trace_optimized_ic_calls);
+DECLARE_FLAG(bool, enable_interpreter);
 
 // Input parameters:
 //   LR : return address.
@@ -112,6 +113,9 @@
   __ mov(SP, CSP);
   __ mov(CSP, R25);
 
+  // Refresh write barrier mask.
+  __ ldr(BARRIER_MASK, Address(THR, Thread::write_barrier_mask_offset()));
+
   // Retval is next to 1st argument.
   // Mark that the thread is executing Dart code.
   __ LoadImmediate(R2, VMTag::kDartTagId);
@@ -301,6 +305,9 @@
   __ mov(SP, CSP);
   __ mov(CSP, R25);
 
+  // Refresh write barrier mask.
+  __ ldr(BARRIER_MASK, Address(THR, Thread::write_barrier_mask_offset()));
+
   // Mark that the thread is executing Dart code.
   __ LoadImmediate(R2, VMTag::kDartTagId);
   __ StoreToOffset(R2, THR, Thread::vm_tag_offset());
@@ -403,6 +410,9 @@
   __ mov(SP, CSP);
   __ mov(CSP, R25);
 
+  // Refresh write barrier mask.
+  __ ldr(BARRIER_MASK, Address(THR, Thread::write_barrier_mask_offset()));
+
   // Mark that the thread is executing Dart code.
   __ LoadImmediate(R2, VMTag::kDartTagId);
   __ StoreToOffset(R2, THR, Thread::vm_tag_offset());
@@ -946,6 +956,8 @@
   if (THR != R3) {
     __ mov(THR, R3);
   }
+  // Refresh write barrier mask.
+  __ ldr(BARRIER_MASK, Address(THR, Thread::write_barrier_mask_offset()));
 
   // Save the current VMTag on the stack.
   __ LoadFromOffset(R4, THR, Thread::vm_tag_offset());
@@ -1051,7 +1063,13 @@
 //   R2 : address of first argument.
 //   R3 : current thread.
 void StubCode::GenerateInvokeDartCodeFromBytecodeStub(Assembler* assembler) {
-#if defined(DART_USE_INTERPRETER)
+#if defined(DART_PRECOMPILED_RUNTIME)
+  __ Stop("Not using interpreter");
+#else
+  if (!FLAG_enable_interpreter) {
+    __ Stop("Not using interpreter");
+    return;
+  }
   // Copy the C stack pointer (R31) into the stack pointer we'll actually use
   // to access the stack.
   __ SetupDartSP();
@@ -1081,6 +1099,8 @@
   if (THR != R3) {
     __ mov(THR, R3);
   }
+  // Refresh write barrier mask.
+  __ ldr(BARRIER_MASK, Address(THR, Thread::write_barrier_mask_offset()));
 
   // Save the current VMTag on the stack.
   __ LoadFromOffset(R4, THR, Thread::vm_tag_offset());
@@ -1172,9 +1192,7 @@
   __ LeaveFrame();
   __ RestoreCSP();
   __ ret();
-#else
-  __ Stop("Not using interpreter");
-#endif  // defined(DART_USE_INTERPRETER)
+#endif  // defined(DART_PRECOMPILED_RUNTIME)
 }
 
 // Called for inline allocation of contexts.
@@ -1291,7 +1309,7 @@
   __ ret();
 }
 
-void StubCode::GenerateUpdateStoreBufferWrappersStub(Assembler* assembler) {
+void StubCode::GenerateWriteBarrierWrappersStub(Assembler* assembler) {
   for (intptr_t i = 0; i < kNumberOfCpuRegisters; ++i) {
     if ((kDartAvailableCpuRegs & (1 << i)) == 0) continue;
 
@@ -1300,7 +1318,7 @@
     __ Push(LR);
     __ Push(R0);
     __ mov(R0, reg);
-    __ ldr(LR, Address(THR, Thread::update_store_buffer_entry_point_offset()));
+    __ ldr(LR, Address(THR, Thread::write_barrier_entry_point_offset()));
     __ blr(LR);
     __ Pop(R0);
     __ Pop(LR);
@@ -1313,8 +1331,15 @@
 
 // Helper stub to implement Assembler::StoreIntoObject.
 // Input parameters:
-//   R0: Address being stored
-void StubCode::GenerateUpdateStoreBufferStub(Assembler* assembler) {
+//   R0: Source object (old)
+//   TMP2: Target object (old or new)
+// If TMP2 is new, add R0 to the store buffer. Otherwise TMP2 is old, mark TMP2
+// and add it to the mark list.
+void StubCode::GenerateWriteBarrierStub(Assembler* assembler) {
+#if defined(CONCURRENT_MARKING)
+  Label add_to_mark_stack;
+  __ tbz(&add_to_mark_stack, TMP2, kNewObjectBitPosition);
+#else
   Label add_to_buffer;
   // Check whether this object has already been remembered. Skip adding to the
   // store buffer if the object is in the store buffer already.
@@ -1323,6 +1348,8 @@
   __ ret();
 
   __ Bind(&add_to_buffer);
+#endif
+
   // Save values being destroyed.
   __ Push(R1);
   __ Push(R2);
@@ -1345,7 +1372,7 @@
   // StoreBufferBlock and add the address to the pointers_.
   __ LoadFromOffset(R1, THR, Thread::store_buffer_block_offset());
   __ LoadFromOffset(R2, R1, StoreBufferBlock::top_offset(), kUnsignedWord);
-  __ add(R3, R1, Operand(R2, LSL, 3));
+  __ add(R3, R1, Operand(R2, LSL, kWordSizeLog2));
   __ StoreToOffset(R0, R3, StoreBufferBlock::pointers_offset());
 
   // Increment top_ and check for overflow.
@@ -1367,7 +1394,7 @@
   // Setup frame, push callee-saved registers.
 
   __ Push(CODE_REG);
-  __ ldr(CODE_REG, Address(THR, Thread::update_store_buffer_code_offset()));
+  __ ldr(CODE_REG, Address(THR, Thread::write_barrier_code_offset()));
   __ EnterCallRuntimeFrame(0 * kWordSize);
   __ mov(R0, THR);
   __ CallRuntime(kStoreBufferBlockProcessRuntimeEntry, 1);
@@ -1375,6 +1402,11 @@
   __ LeaveCallRuntimeFrame();
   __ Pop(CODE_REG);
   __ ret();
+
+#if defined(CONCURRENT_MARKING)
+  __ Bind(&add_to_mark_stack);
+  __ Stop("Incremental barrier");
+#endif
 }
 
 // Called for inline allocation of objects.
@@ -1387,6 +1419,13 @@
   const bool is_cls_parameterized = cls.NumTypeArguments() > 0;
   ASSERT(!is_cls_parameterized ||
          (cls.type_arguments_field_offset() != Class::kNoTypeArguments));
+
+  const Register kTypeArgumentsReg = R1;
+  const Register kInstanceReg = R0;
+  const Register kNullReg = R3;
+  const Register kTempReg = R4;
+  const Register kTopReg = R5;
+
   // kInlineInstanceSize is a constant used as a threshold for determining
   // when the object initialization should be done as a loop or as
   // straight line code.
@@ -1394,111 +1433,62 @@
   const intptr_t instance_size = cls.instance_size();
   ASSERT(instance_size > 0);
   if (is_cls_parameterized) {
-    __ ldr(R1, Address(SP));
-    // R1: instantiated type arguments.
+    __ ldr(kTypeArgumentsReg, Address(SP));
   }
   Isolate* isolate = Isolate::Current();
+
+  __ LoadObject(kNullReg, Object::null_object());
   if (FLAG_inline_alloc && Heap::IsAllocatableInNewSpace(instance_size) &&
       !cls.TraceAllocation(isolate)) {
     Label slow_case;
-    // Allocate the object and update top to point to
-    // next object start and initialize the allocated object.
-    // R1: instantiated type arguments (if is_cls_parameterized).
-    NOT_IN_PRODUCT(Heap::Space space = Heap::kNew);
-    __ ldr(R2, Address(THR, Thread::top_offset()));
-    __ AddImmediate(R3, R2, instance_size);
-    // Check if the allocation fits into the remaining space.
-    // R2: potential new object start.
-    // R3: potential next object start.
-    __ ldr(TMP, Address(THR, Thread::end_offset()));
-    __ CompareRegisters(R3, TMP);
-    if (FLAG_use_slow_path) {
-      __ b(&slow_case);
-    } else {
-      __ b(&slow_case, CS);  // Unsigned higher or equal.
-    }
-    __ str(R3, Address(THR, Thread::top_offset()));
-    NOT_IN_PRODUCT(__ UpdateAllocationStats(cls.id(), space));
-
-    // R2: new object start.
-    // R3: next object start.
-    // R1: new object type arguments (if is_cls_parameterized).
-    // Set the tags.
-    uint32_t tags = 0;
-    tags = RawObject::SizeTag::update(instance_size, tags);
-    ASSERT(cls.id() != kIllegalCid);
-    tags = RawObject::ClassIdTag::update(cls.id(), tags);
-    tags = RawObject::NewBit::update(true, tags);
-    __ LoadImmediate(R0, tags);
-    // 64 bit store also zeros the hash_field.
-    __ StoreToOffset(R0, R2, Instance::tags_offset());
+    // Allocate the object & initialize header word.
+    __ TryAllocate(cls, &slow_case, kInstanceReg, kTopReg,
+                   /*tag_result=*/false);
 
     // Initialize the remaining words of the object.
-    __ LoadObject(R0, Object::null_object());
-
-    // R0: raw null.
-    // R2: new object start.
-    // R3: next object start.
-    // R1: new object type arguments (if is_cls_parameterized).
-    // First try inlining the initialization without a loop.
     if (instance_size < (kInlineInstanceSize * kWordSize)) {
-      // Check if the object contains any non-header fields.
-      // Small objects are initialized using a consecutive set of writes.
-      for (intptr_t current_offset = Instance::NextFieldOffset();
-           current_offset < instance_size; current_offset += kWordSize) {
-        __ StoreToOffset(R0, R2, current_offset);
+      intptr_t current_offset = Instance::NextFieldOffset();
+      while ((current_offset + kWordSize) < instance_size) {
+        __ stp(kNullReg, kNullReg,
+               Address(kInstanceReg, current_offset, Address::PairOffset));
+        current_offset += 2 * kWordSize;
+      }
+      while (current_offset < instance_size) {
+        __ str(kNullReg, Address(kInstanceReg, current_offset));
+        current_offset += kWordSize;
       }
     } else {
-      __ AddImmediate(R4, R2, Instance::NextFieldOffset());
-      // Loop until the whole object is initialized.
-      // R0: raw null.
-      // R2: new object.
-      // R3: next object start.
-      // R4: next word to be initialized.
-      // R1: new object type arguments (if is_cls_parameterized).
-      Label init_loop;
-      Label done;
+      __ AddImmediate(kTempReg, kInstanceReg, Instance::NextFieldOffset());
+      Label done, init_loop;
       __ Bind(&init_loop);
-      __ CompareRegisters(R4, R3);
+      __ CompareRegisters(kTempReg, kTopReg);
       __ b(&done, CS);
-      __ str(R0, Address(R4));
-      __ AddImmediate(R4, kWordSize);
+      __ str(kNullReg, Address(kTempReg, kWordSize, Address::PostIndex));
       __ b(&init_loop);
+
       __ Bind(&done);
     }
     if (is_cls_parameterized) {
-      // R1: new object type arguments.
-      // Set the type arguments in the new object.
-      __ StoreToOffset(R1, R2, cls.type_arguments_field_offset());
+      __ StoreToOffset(kTypeArgumentsReg, kInstanceReg,
+                       cls.type_arguments_field_offset());
     }
-    // Done allocating and initializing the instance.
-    // R2: new object still missing its heap tag.
-    __ add(R0, R2, Operand(kHeapObjectTag));
-    // R0: new object.
+    __ add(kInstanceReg, kInstanceReg, Operand(kHeapObjectTag));
     __ ret();
 
     __ Bind(&slow_case);
   }
+
   // If is_cls_parameterized:
-  // R1: new object type arguments.
   // Create a stub frame as we are pushing some objects on the stack before
   // calling into the runtime.
   __ EnterStubFrame();  // Uses pool pointer to pass cls to runtime.
-  __ Push(ZR);          // Result slot.
-  __ PushObject(cls);   // Push class of object to be allocated.
-  if (is_cls_parameterized) {
-    // Push type arguments.
-    __ Push(R1);
-  } else {
-    // Push null type arguments.
-    __ PushObject(Object::null_object());
-  }
+  __ LoadObject(R0, cls);
+  __ PushPair(R0, kNullReg);  // Pushes cls, result slot.
+  __ Push(is_cls_parameterized ? kTypeArgumentsReg : kNullReg);
   __ CallRuntime(kAllocateObjectRuntimeEntry, 2);  // Allocate object.
-  __ Drop(2);                                      // Pop arguments.
-  __ Pop(R0);  // Pop result (newly allocated object).
-  // R0: new object
-  // Restore the frame pointer.
-  __ LeaveStubFrame();
+  __ ldr(kInstanceReg,
+         Address(SP, 2 * kWordSize));  // Pop result (newly allocated object).
+  __ LeaveStubFrame();                 // Restores correct SP.
   __ ret();
 }
 
@@ -1848,6 +1838,11 @@
       assembler, 1, kInlineCacheMissHandlerOneArgRuntimeEntry, Token::kILLEGAL);
 }
 
+void StubCode::GenerateOneArgCheckInlineCacheWithExactnessCheckStub(
+    Assembler* assembler) {
+  __ Stop("Unimplemented");
+}
+
 void StubCode::GenerateTwoArgsCheckInlineCacheStub(Assembler* assembler) {
   GenerateUsageCounterIncrement(assembler, R6);
   GenerateNArgsCheckInlineCacheStub(assembler, 2,
@@ -1881,6 +1876,11 @@
                                     Token::kILLEGAL, true /* optimized */);
 }
 
+void StubCode::GenerateOneArgOptimizedCheckInlineCacheWithExactnessCheckStub(
+    Assembler* assembler) {
+  __ Stop("Unimplemented");
+}
+
 void StubCode::GenerateTwoArgsOptimizedCheckInlineCacheStub(
     Assembler* assembler) {
   GenerateOptimizedUsageCounterIncrement(assembler);
@@ -1989,7 +1989,13 @@
 // R4: Arguments descriptor.
 // R0: Function.
 void StubCode::GenerateInterpretCallStub(Assembler* assembler) {
-#if defined(DART_USE_INTERPRETER)
+#if defined(DART_PRECOMPILED_RUNTIME)
+  __ Stop("Not using interpreter")
+#else
+  if (!FLAG_enable_interpreter) {
+    __ Stop("Not using interpreter");
+    return;
+  }
 
   __ SetPrologueOffset();
   __ EnterStubFrame();
@@ -2051,6 +2057,9 @@
   __ mov(SP, CSP);
   __ mov(CSP, R25);
 
+  // Refresh write barrier mask.
+  __ ldr(BARRIER_MASK, Address(THR, Thread::write_barrier_mask_offset()));
+
   // Mark that the thread is executing Dart code.
   __ LoadImmediate(R2, VMTag::kDartTagId);
   __ StoreToOffset(R2, THR, Thread::vm_tag_offset());
@@ -2060,9 +2069,7 @@
 
   __ LeaveStubFrame();
   __ ret();
-#else
-  __ Stop("Not using interpreter");
-#endif  // defined(DART_USE_INTERPRETER)
+#endif  // defined(DART_PRECOMPILED_RUNTIME)
 }
 
 // R5: Contains an ICData.
@@ -2540,6 +2547,7 @@
   __ mov(SP, R1);  // Stack pointer.
   __ mov(FP, R2);  // Frame_pointer.
   __ mov(THR, R3);
+  __ ldr(BARRIER_MASK, Address(THR, Thread::write_barrier_mask_offset()));
   // Set the tag.
   __ LoadImmediate(R2, VMTag::kDartTagId);
   __ StoreToOffset(R2, THR, Thread::vm_tag_offset());
diff --git a/runtime/vm/stub_code_dbc.cc b/runtime/vm/stub_code_dbc.cc
index a6e6a76..c1fbc5e 100644
--- a/runtime/vm/stub_code_dbc.cc
+++ b/runtime/vm/stub_code_dbc.cc
@@ -121,6 +121,14 @@
   __ Trap();
 }
 
+void StubCode::GenerateInterpretCallStub(Assembler* assembler) {
+  __ Trap();
+}
+
+void StubCode::GenerateInvokeDartCodeFromBytecodeStub(Assembler* assembler) {
+  __ Trap();
+}
+
 }  // namespace dart
 
 #endif  // defined TARGET_ARCH_DBC
diff --git a/runtime/vm/stub_code_ia32.cc b/runtime/vm/stub_code_ia32.cc
index cecf6c2..369dad7 100644
--- a/runtime/vm/stub_code_ia32.cc
+++ b/runtime/vm/stub_code_ia32.cc
@@ -972,7 +972,7 @@
   __ ret();
 }
 
-void StubCode::GenerateUpdateStoreBufferWrappersStub(Assembler* assembler) {
+void StubCode::GenerateWriteBarrierWrappersStub(Assembler* assembler) {
   // Not used on IA32.
   __ Breakpoint();
 }
@@ -980,7 +980,7 @@
 // Helper stub to implement Assembler::StoreIntoObject.
 // Input parameters:
 //   EDX: Address being stored
-void StubCode::GenerateUpdateStoreBufferStub(Assembler* assembler) {
+void StubCode::GenerateWriteBarrierStub(Assembler* assembler) {
   // Save values being destroyed.
   __ pushl(EAX);
   __ pushl(ECX);
@@ -1510,6 +1510,11 @@
       assembler, 1, kInlineCacheMissHandlerOneArgRuntimeEntry, Token::kILLEGAL);
 }
 
+void StubCode::GenerateOneArgCheckInlineCacheWithExactnessCheckStub(
+    Assembler* assembler) {
+  __ Stop("Unimplemented");
+}
+
 void StubCode::GenerateTwoArgsCheckInlineCacheStub(Assembler* assembler) {
   GenerateUsageCounterIncrement(assembler, EBX);
   GenerateNArgsCheckInlineCacheStub(assembler, 2,
@@ -1554,6 +1559,11 @@
                                     Token::kILLEGAL, true /* optimized */);
 }
 
+void StubCode::GenerateOneArgOptimizedCheckInlineCacheWithExactnessCheckStub(
+    Assembler* assembler) {
+  __ Stop("Unimplemented");
+}
+
 void StubCode::GenerateTwoArgsOptimizedCheckInlineCacheStub(
     Assembler* assembler) {
   GenerateOptimizedUsageCounterIncrement(assembler);
diff --git a/runtime/vm/stub_code_x64.cc b/runtime/vm/stub_code_x64.cc
index 1158117..f6a2790 100644
--- a/runtime/vm/stub_code_x64.cc
+++ b/runtime/vm/stub_code_x64.cc
@@ -33,6 +33,7 @@
             false,
             "Set to true for debugging & verifying the slow paths.");
 DECLARE_FLAG(bool, trace_optimized_ic_calls);
+DECLARE_FLAG(bool, enable_interpreter);
 
 // Input parameters:
 //   RSP : points to return address.
@@ -975,7 +976,13 @@
 //   RDX : address of first argument.
 //   RCX : current thread.
 void StubCode::GenerateInvokeDartCodeFromBytecodeStub(Assembler* assembler) {
-#if defined(DART_USE_INTERPRETER)
+#if defined(DART_PRECOMPILED_RUNTIME)
+  __ Stop("Not using interpreter");
+#else
+  if (!FLAG_enable_interpreter) {
+    __ Stop("Not using interpreter");
+    return;
+  }
   // Save frame pointer coming in.
   __ EnterFrame(0);
 
@@ -1103,9 +1110,7 @@
   __ LeaveFrame();
 
   __ ret();
-#else
-  __ Stop("Not using interpreter");
-#endif  // defined(DART_USE_INTERPRETER)
+#endif  // defined(DART_PRECOMPILED_RUNTIME)
 }
 
 // Called for inline allocation of contexts.
@@ -1237,7 +1242,7 @@
   __ ret();
 }
 
-void StubCode::GenerateUpdateStoreBufferWrappersStub(Assembler* assembler) {
+void StubCode::GenerateWriteBarrierWrappersStub(Assembler* assembler) {
   for (intptr_t i = 0; i < kNumberOfCpuRegisters; ++i) {
     if ((kDartAvailableCpuRegs & (1 << i)) == 0) continue;
 
@@ -1245,7 +1250,7 @@
     intptr_t start = __ CodeSize();
     __ pushq(RDX);
     __ movq(RDX, reg);
-    __ call(Address(THR, Thread::update_store_buffer_entry_point_offset()));
+    __ call(Address(THR, Thread::write_barrier_entry_point_offset()));
     __ popq(RDX);
     __ ret();
     intptr_t end = __ CodeSize();
@@ -1256,8 +1261,16 @@
 
 // Helper stub to implement Assembler::StoreIntoObject.
 // Input parameters:
-//   RDX: Address being stored
-void StubCode::GenerateUpdateStoreBufferStub(Assembler* assembler) {
+//   RDX: Source object (old)
+//   TMP: Target object (old or new)
+// If TMP is new, add RDX to the store buffer. Otherwise TMP is old, mark TMP
+// and add it to the mark list.
+void StubCode::GenerateWriteBarrierStub(Assembler* assembler) {
+#if defined(CONCURRENT_MARKING)
+  Label add_to_mark_stack;
+  __ testq(TMP, Immediate(1 << kNewObjectBitPosition));
+  __ j(ZERO, &add_to_mark_stack);
+#else
   Label add_to_buffer;
   // Check whether this object has already been remembered. Skip adding to the
   // store buffer if the object is in the store buffer already.
@@ -1267,12 +1280,14 @@
   __ j(NOT_EQUAL, &add_to_buffer, Assembler::kNearJump);
   __ ret();
 
+  __ Bind(&add_to_buffer);
+#endif
+
   // Update the tags that this object has been remembered.
   // Note that we use 32 bit operations here to match the size of the
   // background sweeper which is also manipulating this 32 bit word.
   // RDX: Address being stored
   // RAX: Current tag value
-  __ Bind(&add_to_buffer);
   // lock+andl is an atomic read-modify-write.
   __ lock();
   __ andl(FieldAddress(RDX, Object::tags_offset()),
@@ -1306,13 +1321,18 @@
   __ Bind(&overflow);
   // Setup frame, push callee-saved registers.
   __ pushq(CODE_REG);
-  __ movq(CODE_REG, Address(THR, Thread::update_store_buffer_code_offset()));
+  __ movq(CODE_REG, Address(THR, Thread::write_barrier_code_offset()));
   __ EnterCallRuntimeFrame(0);
   __ movq(CallingConventions::kArg1Reg, THR);
   __ CallRuntime(kStoreBufferBlockProcessRuntimeEntry, 1);
   __ LeaveCallRuntimeFrame();
   __ popq(CODE_REG);
   __ ret();
+
+#if defined(CONCURRENT_MARKING)
+  __ Bind(&add_to_mark_stack);
+  __ Stop("Incremental barrier");
+#endif
 }
 
 // Called for inline allocation of objects.
@@ -1985,7 +2005,13 @@
 // R10: Arguments descriptor.
 // RAX: Function.
 void StubCode::GenerateInterpretCallStub(Assembler* assembler) {
-#if defined(DART_USE_INTERPRETER)
+#if defined(DART_PRECOMPILED_RUNTIME)
+  __ Stop("Not using interpreter");
+#else
+  if (!FLAG_enable_interpreter) {
+    __ Stop("Not using interpreter");
+    return;
+  }
   __ EnterStubFrame();
 
 #if defined(DEBUG)
@@ -2050,9 +2076,7 @@
 
   __ LeaveStubFrame();
   __ ret();
-#else
-  __ Stop("Not using interpreter");
-#endif  // defined(DART_USE_INTERPRETER)
+#endif  // defined(DART_PRECOMPILED_RUNTIME)
 }
 
 // RBX: Contains an ICData.
diff --git a/runtime/vm/symbols.h b/runtime/vm/symbols.h
index 28c6b68..bef0efa 100644
--- a/runtime/vm/symbols.h
+++ b/runtime/vm/symbols.h
@@ -183,7 +183,6 @@
   V(ClosureData, "ClosureData")                                                \
   V(SignatureData, "SignatureData")                                            \
   V(RedirectionData, "RedirectionData")                                        \
-  V(NativeEntryData, "NativeEntryData")                                        \
   V(Field, "Field")                                                            \
   V(LiteralToken, "LiteralToken")                                              \
   V(TokenStream, "TokenStream")                                                \
@@ -463,6 +462,7 @@
   V(DebugProcedureName, ":Eval")                                               \
   V(DebugClassName, "#DebugClass")                                             \
   V(vm_entry_point, "vm:entry-point")                                          \
+  V(vm_exact_result_type, "vm:exact-result-type")                              \
   V(Get, "get")                                                                \
   V(Set, "set")                                                                \
   V(vm_trace_entrypoints, "vm:testing.unsafe.trace-entrypoints-fn")            \
diff --git a/runtime/vm/thread.cc b/runtime/vm/thread.cc
index a188d2b1c..5bb99f2 100644
--- a/runtime/vm/thread.cc
+++ b/runtime/vm/thread.cc
@@ -60,6 +60,7 @@
     : BaseThread(false),
       stack_limit_(0),
       stack_overflow_flags_(0),
+      write_barrier_mask_(RawObject::kGenerationalBarrierMask),
       isolate_(NULL),
       heap_(NULL),
       top_(0),
@@ -119,7 +120,7 @@
 #if defined(TARGET_ARCH_ARM) || defined(TARGET_ARCH_ARM64) ||                  \
     defined(TARGET_ARCH_X64)
   for (intptr_t i = 0; i < kNumberOfDartAvailableCpuRegs; ++i) {
-    update_store_buffer_wrappers_entry_points_[i] = 0;
+    write_barrier_wrappers_entry_points_[i] = 0;
   }
 #endif
 
@@ -213,8 +214,8 @@
 #if defined(TARGET_ARCH_ARM) || defined(TARGET_ARCH_ARM64) ||                  \
     defined(TARGET_ARCH_X64)
   for (intptr_t i = 0; i < kNumberOfDartAvailableCpuRegs; ++i) {
-    update_store_buffer_wrappers_entry_points_[i] =
-        StubCode::UpdateStoreBufferWrappers_entry()->EntryPoint() +
+    write_barrier_wrappers_entry_points_[i] =
+        StubCode::WriteBarrierWrappers_entry()->EntryPoint() +
         i * kStoreBufferWrapperSize;
   }
 #endif
@@ -466,25 +467,6 @@
   return false;
 }
 
-void Thread::SetHighWatermark(intptr_t value) {
-  zone_high_watermark_ = value;
-
-#if !defined(PRODUCT)
-  if ((isolate()->name() != NULL)) {
-    TimelineEvent* event = Timeline::GetZoneStream()->StartEvent();
-    if (event != NULL) {
-      event->Counter(strdup(isolate()->name()));
-      event->set_owns_label(true);
-      // Prevent Catapult from showing "isolateId" as another series.
-      event->set_isolate_id(ILLEGAL_PORT);
-      event->SetNumArguments(1);
-      event->FormatArgument(0, "zoneHighWatermark", "%" Pd, value);
-      event->Complete();
-    }
-  }
-#endif
-}
-
 void Thread::DeferOOBMessageInterrupts() {
   MonitorLocker ml(thread_lock_);
   defer_oob_messages_count_++;
diff --git a/runtime/vm/thread.h b/runtime/vm/thread.h
index 65402de..d17fc3a 100644
--- a/runtime/vm/thread.h
+++ b/runtime/vm/thread.h
@@ -83,8 +83,8 @@
 #define CACHED_VM_STUBS_LIST(V)
 #else
 #define CACHED_VM_STUBS_LIST(V)                                                \
-  V(RawCode*, update_store_buffer_code_,                                       \
-    StubCode::UpdateStoreBuffer_entry()->code(), NULL)                         \
+  V(RawCode*, write_barrier_code_, StubCode::WriteBarrier_entry()->code(),     \
+    NULL)                                                                      \
   V(RawCode*, fix_callers_target_code_,                                        \
     StubCode::FixCallersTarget_entry()->code(), NULL)                          \
   V(RawCode*, fix_allocation_stub_code_,                                       \
@@ -139,8 +139,8 @@
 #define CACHED_VM_STUBS_ADDRESSES_LIST(V)
 #else
 #define CACHED_VM_STUBS_ADDRESSES_LIST(V)                                      \
-  V(uword, update_store_buffer_entry_point_,                                   \
-    StubCode::UpdateStoreBuffer_entry()->EntryPoint(), 0)                      \
+  V(uword, write_barrier_entry_point_,                                         \
+    StubCode::WriteBarrier_entry()->EntryPoint(), 0)                           \
   V(uword, call_to_runtime_entry_point_,                                       \
     StubCode::CallToRuntime_entry()->EntryPoint(), 0)                          \
   V(uword, null_error_shared_without_fpu_regs_entry_point_,                    \
@@ -274,8 +274,10 @@
     kOsrRequest = 0x1,  // Current stack overflow caused by OSR request.
   };
 
-  uword stack_overflow_flags_address() const {
-    return reinterpret_cast<uword>(&stack_overflow_flags_);
+  uword write_barrier_mask() const { return write_barrier_mask_; }
+
+  static intptr_t write_barrier_mask_offset() {
+    return OFFSET_OF(Thread, write_barrier_mask_);
   }
   static intptr_t stack_overflow_flags_offset() {
     return OFFSET_OF(Thread, stack_overflow_flags_);
@@ -323,7 +325,7 @@
   void IncrementMemoryCapacity(uintptr_t value) {
     current_zone_capacity_ += value;
     if (current_zone_capacity_ > zone_high_watermark_) {
-      SetHighWatermark(current_zone_capacity_);
+      zone_high_watermark_ = current_zone_capacity_;
     }
   }
 
@@ -336,9 +338,7 @@
 
   uintptr_t zone_high_watermark() const { return zone_high_watermark_; }
 
-  void ResetHighWatermark() { SetHighWatermark(current_zone_capacity_); }
-
-  void SetHighWatermark(intptr_t value);
+  void ResetHighWatermark() { zone_high_watermark_ = current_zone_capacity_; }
 
   // The reusable api local scope for this thread.
   ApiLocalScope* api_reusable_scope() const { return api_reusable_scope_; }
@@ -522,7 +522,7 @@
 
 #if defined(TARGET_ARCH_ARM) || defined(TARGET_ARCH_ARM64) ||                  \
     defined(TARGET_ARCH_X64)
-  static intptr_t update_store_buffer_wrappers_offset(Register reg) {
+  static intptr_t write_barrier_wrappers_offset(Register reg) {
     ASSERT((kDartAvailableCpuRegs & (1 << reg)) != 0);
     intptr_t index = 0;
     for (intptr_t i = 0; i < kNumberOfCpuRegisters; ++i) {
@@ -530,7 +530,7 @@
       if (i == reg) break;
       ++index;
     }
-    return OFFSET_OF(Thread, update_store_buffer_wrappers_entry_points_) +
+    return OFFSET_OF(Thread, write_barrier_wrappers_entry_points_) +
            index * sizeof(uword);
   }
 #endif
@@ -799,6 +799,7 @@
   // different architectures. See also CheckOffsets in dart.cc.
   uword stack_limit_;
   uword stack_overflow_flags_;
+  uword write_barrier_mask_;
   Isolate* isolate_;
   Heap* heap_;
   uword top_;
@@ -812,7 +813,7 @@
   // generated code to runtime.
   // TODO(dartbug.com/33549): Clean this up when unboxed values
   // could be passed as arguments.
-  int64_t unboxed_int64_runtime_arg_;
+  ALIGN8 int64_t unboxed_int64_runtime_arg_;
 
 // State that is cached in the TLS for fast access in generated code.
 #define DECLARE_MEMBERS(type_name, member_name, expr, default_init_value)      \
@@ -830,8 +831,7 @@
 
 #if defined(TARGET_ARCH_ARM) || defined(TARGET_ARCH_ARM64) ||                  \
     defined(TARGET_ARCH_X64)
-  uword
-      update_store_buffer_wrappers_entry_points_[kNumberOfDartAvailableCpuRegs];
+  uword write_barrier_wrappers_entry_points_[kNumberOfDartAvailableCpuRegs];
 #endif
 
   TimelineStream* dart_stream_;
diff --git a/runtime/vm/thread_test.cc b/runtime/vm/thread_test.cc
index 561db06..b0687de 100644
--- a/runtime/vm/thread_test.cc
+++ b/runtime/vm/thread_test.cc
@@ -13,6 +13,8 @@
 
 namespace dart {
 
+DECLARE_FLAG(bool, enable_interpreter);
+
 VM_UNIT_TEST_CASE(Mutex) {
   // This unit test case needs a running isolate.
   TestCase::CreateTestIsolate();
@@ -496,11 +498,11 @@
 // to get their verification done and exit. Use a specific UserTag
 // to enable the helpers to verify that the main thread is
 // successfully interrupted in the pure Dart loop.
-#if defined(USING_SIMULATOR) || defined(DART_USE_INTERPRETER)
+#if defined(USING_SIMULATOR)
   const intptr_t kLoopCount = 12345678;
 #else
-  const intptr_t kLoopCount = 1234567890;
-#endif  // defined(USING_SIMULATOR) || defined(DART_USE_INTERPRETER)
+  const intptr_t kLoopCount = FLAG_enable_interpreter ? 12345678 : 1234567890;
+#endif  // defined(USING_SIMULATOR)
   char buffer[1024];
   Utils::SNPrint(buffer, sizeof(buffer),
                  "import 'dart:developer';\n"
diff --git a/runtime/vm/timeline.h b/runtime/vm/timeline.h
index 98e00ce..94934e0 100644
--- a/runtime/vm/timeline.h
+++ b/runtime/vm/timeline.h
@@ -39,8 +39,7 @@
   V(Embedder, false)                                                           \
   V(GC, false)                                                                 \
   V(Isolate, false)                                                            \
-  V(VM, false)                                                                 \
-  V(Zone, false)
+  V(VM, false)
 
 // A stream of timeline events. A stream has a name and can be enabled or
 // disabled (globally and per isolate).
@@ -315,10 +314,10 @@
   void PrintJSON(JSONStream* stream) const;
 
   ThreadId thread() const { return thread_; }
+
   void set_thread(ThreadId tid) { thread_ = tid; }
 
   Dart_Port isolate_id() const { return isolate_id_; }
-  void set_isolate_id(Dart_Port id) { isolate_id_ = id; }
 
   const char* label() const { return label_; }
 
diff --git a/runtime/vm/vm_sources.gni b/runtime/vm/vm_sources.gni
index 93d8ac3..23f0402 100644
--- a/runtime/vm/vm_sources.gni
+++ b/runtime/vm/vm_sources.gni
@@ -41,6 +41,7 @@
   "code_patcher_arm64.cc",
   "code_patcher_dbc.cc",
   "code_patcher_ia32.cc",
+  "code_patcher_kbc.cc",
   "code_patcher_x64.cc",
   "compilation_trace.cc",
   "compilation_trace.h",
@@ -119,10 +120,13 @@
   "instructions_dbc.h",
   "instructions_ia32.cc",
   "instructions_ia32.h",
+  "instructions_kbc.cc",
+  "instructions_kbc.h",
   "instructions_x64.cc",
   "instructions_x64.h",
   "interpreter.cc",
   "interpreter.h",
+  "interpreter_unsupported.cc",
   "isolate.cc",
   "isolate.h",
   "isolate_reload.cc",
diff --git a/sdk/BUILD.gn b/sdk/BUILD.gn
index 857219e..5bd19c1 100644
--- a/sdk/BUILD.gn
+++ b/sdk/BUILD.gn
@@ -516,14 +516,10 @@
     ":copy_libraries",
     "../utils/compiler:compile_dart2js_platform",
     "../utils/compiler:compile_dart2js_server_platform",
-    "../utils/compiler:compile_dart2js_platform_strong",
-    "../utils/compiler:compile_dart2js_server_platform_strong",
   ]
   sources = [
     "$root_out_dir/dart2js_platform.dill",
     "$root_out_dir/dart2js_server_platform.dill",
-    "$root_out_dir/dart2js_platform_strong.dill",
-    "$root_out_dir/dart2js_server_platform_strong.dill",
   ]
   outputs = [
     "$root_out_dir/dart-sdk/lib/_internal/{{source_file_part}}",
diff --git a/sdk/lib/_internal/js_runtime/lib/interceptors.dart b/sdk/lib/_internal/js_runtime/lib/interceptors.dart
index 93b5751..a9fcb75 100644
--- a/sdk/lib/_internal/js_runtime/lib/interceptors.dart
+++ b/sdk/lib/_internal/js_runtime/lib/interceptors.dart
@@ -16,6 +16,7 @@
         JSSyntaxRegExp,
         Primitives,
         argumentErrorValue,
+        checkBool,
         checkInt,
         checkNull,
         checkNum,
@@ -364,6 +365,12 @@
   // Note: if you change this, also change the function [S].
   String toString() => JS('String', r'String(#)', this);
 
+  bool operator &(bool other) => JS('bool', "# && #", checkBool(other), this);
+
+  bool operator |(bool other) => JS('bool', "# || #", checkBool(other), this);
+
+  bool operator ^(bool other) => !identical(this, checkBool(other));
+
   // The values here are SMIs, co-prime and differ about half of the bit
   // positions, including the low bit, so they are different mod 2^k.
   int get hashCode => this ? (2 * 3 * 23 * 3761) : (269 * 811);
diff --git a/sdk/lib/_internal/js_runtime/lib/js_number.dart b/sdk/lib/_internal/js_runtime/lib/js_number.dart
index c0867be..58e5e55 100644
--- a/sdk/lib/_internal/js_runtime/lib/js_number.dart
+++ b/sdk/lib/_internal/js_runtime/lib/js_number.dart
@@ -217,7 +217,7 @@
   static String _handleIEtoString(String result) {
     // Result is probably IE's untraditional format for large numbers,
     // e.g., "8.0000000000008(e+15)" for 0x8000000000000800.toString(16).
-    var match = JS('List|Null',
+    var match = JS('JSArray|Null',
         r'/^([\da-z]+)(?:\.([\da-z]+))?\(e\+(\d+)\)$/.exec(#)', result);
     if (match == null) {
       // Then we don't know how to handle it at all.
diff --git a/sdk/lib/async/stream.dart b/sdk/lib/async/stream.dart
index a0efcb7..da9c337 100644
--- a/sdk/lib/async/stream.dart
+++ b/sdk/lib/async/stream.dart
@@ -2007,6 +2007,21 @@
       void handleDone(EventSink<T> sink)}) = _StreamHandlerTransformer<S, T>;
 
   /**
+   * Creates a [StreamTransformer] based on a [bind] callback.
+   *
+   * The returned stream transformer uses the [bind] argument to implement the
+   * [StreamTransformer.bind] API and can be used when the transformation is
+   * available as a stream-to-stream function.
+   *
+   * ```dart
+   * final splitDecoded = StreamTransformer<List<int>, String>.fromBind(
+   *     (stream) => stream.transform(utf8.decoder).transform(LineSplitter()));
+   * ```
+   */
+  factory StreamTransformer.fromBind(Stream<T> Function(Stream<S>) bind) =
+      _StreamBindTransformer<S, T>;
+
+  /**
    * Adapts [source] to be a `StreamTransfomer<TS, TT>`.
    *
    * This allows [source] to be used at the new type, but at run-time it
diff --git a/sdk/lib/async/stream_impl.dart b/sdk/lib/async/stream_impl.dart
index 9750478..6c2b8ba 100644
--- a/sdk/lib/async/stream_impl.dart
+++ b/sdk/lib/async/stream_impl.dart
@@ -766,7 +766,7 @@
   Future<E> asFuture<E>([E futureValue]) {
     _Future<E> result = new _Future<E>();
     _onDone = () {
-      result._completeWithValue(null);
+      result._completeWithValue(futureValue);
     };
     return result;
   }
diff --git a/sdk/lib/async/stream_transformers.dart b/sdk/lib/async/stream_transformers.dart
index 37bbc02..5488d55 100644
--- a/sdk/lib/async/stream_transformers.dart
+++ b/sdk/lib/async/stream_transformers.dart
@@ -282,6 +282,16 @@
   }
 }
 
+/**
+ * A StreamTransformer that overrides [StreamTransformer.bind] with a callback.
+ */
+class _StreamBindTransformer<S, T> extends StreamTransformerBase<S, T> {
+  final Stream<T> Function(Stream<S>) _bind;
+  _StreamBindTransformer(this._bind);
+
+  Stream<T> bind(Stream<S> stream) => _bind(stream);
+}
+
 /// A closure mapping a stream and cancelOnError to a StreamSubscription.
 typedef StreamSubscription<T> _SubscriptionTransformer<S, T>(
     Stream<S> stream, bool cancelOnError);
diff --git a/sdk/lib/core/bool.dart b/sdk/lib/core/bool.dart
index 2aeca44..980b1c5 100644
--- a/sdk/lib/core/bool.dart
+++ b/sdk/lib/core/bool.dart
@@ -5,7 +5,7 @@
 part of dart.core;
 
 /**
- * The reserved words [:true:] and [:false:] denote objects that are the only
+ * The reserved words `true` and `false` denote objects that are the only two
  * instances of this class.
  *
  * It is a compile-time error for a class to attempt to extend or implement
@@ -23,21 +23,22 @@
    * the result is the [defaultValue].
    *
    * The result is the same as would be returned by:
-   *
-   *     (const String.fromEnvironment(name) == "true")
-   *         ? true
-   *         : (const String.fromEnvironment(name) == "false")
-   *             ? false
-   *             : defaultValue
-   *
+   * ```dart
+   * (const String.fromEnvironment(name) == "true")
+   *     ? true
+   *     : (const String.fromEnvironment(name) == "false")
+   *         ? false
+   *         : defaultValue
+   * ```
    * Example:
-   *
-   *     const loggingFlag = const bool.fromEnvironment("logging");
-   *
+   * ```dart
+   * const loggingFlag = const bool.fromEnvironment("logging");
+   * ```
    * If you want to use a different truth-string than `"true"`, you can use the
    * [String.fromEnvironment] constructor directly:
-   *
-   *     const isLoggingOn = (const String.fromEnvironment("logging") == "on");
+   * ```dart
+   * const isLoggingOn = (const String.fromEnvironment("logging") == "on");
+   * ```
    */
   // The .fromEnvironment() constructors are special in that we do not want
   // users to call them using "new". We prohibit that by giving them bodies
@@ -50,9 +51,24 @@
 
   external int get hashCode;
 
+  /// The logical conjuncton ("and") of this and [other].
+  ///
+  /// Returns `true` if both this and [other] are `true`, and `false` otherwise.
+  //TODO(lrn): Remove "as bool" in Dart 2.
+  bool operator &(bool other) => (other as bool) && this;
+
+  /// The logical disjunction ("inclusive or") of this and [other].
+  ///
+  /// Returns `true` if either this or [other] is `true`, and `false` otherwise.
+  bool operator |(bool other) => (other as bool) || this;
+
+  /// The logical exclusive disjuction ("exclusive or") of this and [other].
+  ///
+  /// Returns whether this and [other] are neither both `true` nor both `false`.
+  bool operator ^(bool other) => !(other as bool) == this;
+
   /**
-   * Returns [:"true":] if the receiver is [:true:], or [:"false":] if the
-   * receiver is [:false:].
+   * Returns either `"true"` for `true` and `"false"` for `false`.
    */
   String toString() {
     return this ? "true" : "false";
diff --git a/sdk/lib/core/core.dart b/sdk/lib/core/core.dart
index 7b5c901..f58a6a3 100644
--- a/sdk/lib/core/core.dart
+++ b/sdk/lib/core/core.dart
@@ -169,6 +169,8 @@
 import "dart:math" show Random; // Used by List.shuffle.
 import "dart:typed_data" show Uint8List, Uint16List, Endian;
 
+export "dart:async" show Future, Stream;
+
 part "annotations.dart";
 part "bigint.dart";
 part "bool.dart";
diff --git a/sdk/lib/core/string.dart b/sdk/lib/core/string.dart
index ef5c3e6..0c81f28 100644
--- a/sdk/lib/core/string.dart
+++ b/sdk/lib/core/string.dart
@@ -223,6 +223,24 @@
   bool operator ==(Object other);
 
   /**
+   * Compares this string to [other].
+   *
+   * Returns a negative value if `this` is ordered before `other`,
+   * a positive value if `this` is ordered after `other`,
+   * or zero if `this` and `other` are equivalent.
+   *
+   * The ordering is the same as the ordering of the code points at the first
+   * position where the two strings differ.
+   * If one string is a prefix of the other,
+   * then the shorter string is ordered before the longer string.
+   * If the strings have exactly the same content, they are equivalent with
+   * regard to the ordering.
+   * Ordering does not check for Unicode equivalence.
+   * The comparison is case sensitive.
+   */
+  int compareTo(String other);
+
+  /**
    * Returns true if this string ends with [other]. For example:
    *
    *     'Dart'.endsWith('t'); // true
diff --git a/sdk/lib/html/html_common/conversions.dart b/sdk/lib/html/html_common/conversions.dart
index a8e3329..f2373b5 100644
--- a/sdk/lib/html/html_common/conversions.dart
+++ b/sdk/lib/html/html_common/conversions.dart
@@ -128,7 +128,7 @@
       // non-native properties or methods from interceptors and such, e.g.
       // an immutability marker. So we  had to stop doing that.
       var slot = findSlot(e);
-      var copy = JS('List|Null', '#', readSlot(slot));
+      var copy = JS('returns:List|Null;creates:;', '#', readSlot(slot));
       if (copy != null) return copy;
       copy = copyList(e, slot);
       return copy;
@@ -237,9 +237,9 @@
     }
 
     if (isJavaScriptArray(e)) {
-      var l = JS('List', '#', e);
+      var l = JS('returns:List;creates:;', '#', e);
       var slot = findSlot(l);
-      var copy = JS('List|Null', '#', readSlot(slot));
+      var copy = JS('returns:List|Null;creates:;', '#', readSlot(slot));
       if (copy != null) return copy;
 
       int length = l.length;
diff --git a/sdk/lib/io/platform_impl.dart b/sdk/lib/io/platform_impl.dart
index 5853d89..6b918b5 100644
--- a/sdk/lib/io/platform_impl.dart
+++ b/sdk/lib/io/platform_impl.dart
@@ -41,6 +41,7 @@
   static String packageRoot = null; // TODO(mfairhurst): remove this
   static String packageConfig = _packageConfig();
 
+  @pragma("vm:entry-point")
   static String Function() _localeClosure;
   static String localeName() {
     final result = (_localeClosure == null) ? _localeName() : _localeClosure();
diff --git a/sdk/lib/io/stdio.dart b/sdk/lib/io/stdio.dart
index bba0d70..e9d3862 100644
--- a/sdk/lib/io/stdio.dart
+++ b/sdk/lib/io/stdio.dart
@@ -34,18 +34,23 @@
   Stdin._(Stream<List<int>> stream, this._fd) : super(stream);
 
   /**
-   * Synchronously read a line from stdin. This call will block until a full
-   * line is available.
+   * Read a line from stdin.
    *
-   * The argument [encoding] can be used to changed how the input should be
-   * decoded. Default is [systemEncoding].
+   * Blocks until a full line is available.
    *
-   * If [retainNewlines] is `false`, the returned String will not contain the
-   * final newline. If `true`, the returned String will contain the line
+   * Lines my be terminated by either `<CR><LF>` or `<LF>`. On Windows in cases
+   * where the [stdioType] of stdin is [StdioType.termimal] the terminator may
+   * also be a single `<CR>`.
+   *
+   * Input bytes are converted to a string by [encoding].
+   * If [encoding] is omitted, it defaults to [systemEncoding].
+   *
+   * If [retainNewlines] is `false`, the returned String will not include the
+   * final line terminator. If `true`, the returned String will include the line
    * terminator. Default is `false`.
    *
    * If end-of-file is reached after any bytes have been read from stdin,
-   * that data is returned.
+   * that data is returned without a line terminator.
    * Returns `null` if no bytes preceded the end of input.
    */
   String readLineSync(
diff --git a/tests/co19/co19-co19.status b/tests/co19/co19-co19.status
index b3d404f..455498a 100644
--- a/tests/co19/co19-co19.status
+++ b/tests/co19/co19-co19.status
@@ -10,6 +10,7 @@
 
 # Tests that produce compile-time errors even in legacy mode.
 [ $runtime == none ]
+Language/Expressions/Bitwise_Expressions/syntax_t01/02: Skip
 Language/Variables/constant_initialization_t03: CompileTimeError # Uppercase constants removed
 Language/Variables/constant_variable_t09: CompileTimeError # Uppercase constants removed
 LibTest/core/double/operator_GE_A01_t03: CompileTimeError # Uppercase constants removed
@@ -42,6 +43,7 @@
 
 # Tests that fail either at compile-time or at runtime.
 [ $runtime != none ]
+Language/Expressions/Bitwise_Expressions/syntax_t01/02: Skip
 Language/Expressions/Numbers/static_type_of_double_t01: RuntimeError # Uppercase constants removed
 Language/Expressions/Object_Identity/constant_objects_t01: RuntimeError # Uppercase constants removed
 Language/Expressions/Object_Identity/double_t02: RuntimeError # Uppercase constants removed
diff --git a/tests/co19/co19-kernel.status b/tests/co19/co19-kernel.status
index 70c8436..456721c 100644
--- a/tests/co19/co19-kernel.status
+++ b/tests/co19/co19-kernel.status
@@ -14,7 +14,6 @@
 Language/Types/Parameterized_Types/arity_mismatch_t01: CompileTimeError
 Language/Types/Parameterized_Types/arity_mismatch_t05: CompileTimeError
 Language/Types/Parameterized_Types/arity_mismatch_t07: CompileTimeError
-Language/Types/Type_Void/syntax_t08: MissingCompileTimeError
 Language/Types/Type_Void/syntax_t09: MissingCompileTimeError
 LayoutTests/*: Skip # TODO(ahe): Make dart:html available.
 LibTest/collection/Maps/*: Skip # Maps class no longer exists.
@@ -227,6 +226,7 @@
 Language/Classes/method_definition_t03: CompileTimeError
 Language/Classes/method_definition_t04: CompileTimeError
 Language/Classes/method_definition_t05: CompileTimeError
+Language/Classes/mixins_t02: MissingCompileTimeError # co19 issue 163
 Language/Classes/same_name_instance_and_static_members_t02: Pass
 Language/Classes/same_name_instance_and_static_members_t04: Pass
 Language/Enums/declaration_equivalent_t03: CompileTimeError
@@ -1116,7 +1116,6 @@
 Language/Types/Type_Void/returning_t03: CompileTimeError
 Language/Types/Type_Void/returning_t04: CompileTimeError
 Language/Types/Type_Void/returning_t05: CompileTimeError
-Language/Types/Type_Void/syntax_t08: MissingCompileTimeError
 Language/Types/Type_Void/syntax_t09: MissingCompileTimeError
 Language/Types/Type_Void/syntax_t09: Pass
 Language/Types/Type_Void/using_t01: CompileTimeError
diff --git a/tests/co19_2/co19_2-analyzer.status b/tests/co19_2/co19_2-analyzer.status
index cbe12fd..8eaefac 100644
--- a/tests/co19_2/co19_2-analyzer.status
+++ b/tests/co19_2/co19_2-analyzer.status
@@ -1,4 +1,4 @@
-# Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+# !Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
 # for details. All rights reserved. Use of this source code is governed by a
 # BSD-style license that can be found in the LICENSE file.
 
@@ -14,6 +14,9 @@
 Language/Classes/Abstract_Instance_Members/same_name_static_method_in_superclass_t05: MissingCompileTimeError # Issue 33995
 Language/Classes/Abstract_Instance_Members/same_name_static_method_in_superclass_t06: MissingCompileTimeError # Issue 33995
 Language/Classes/Constructors/Generative_Constructors/final_variables_t01: CompileTimeError # co19 issue 155
+Language/Classes/Constructors/name_t01: MissingCompileTimeError # Legal, see #33235
+Language/Classes/Constructors/name_t02: MissingCompileTimeError # Legal, see #33235
+Language/Classes/Constructors/name_t03: MissingCompileTimeError # Legal, see #33235
 Language/Classes/Getters/instance_getter_t01: MissingCompileTimeError # Legal, see #33235
 Language/Classes/Getters/instance_getter_t02: MissingCompileTimeError # Legal, see #33235
 Language/Classes/Getters/instance_getter_t03: MissingCompileTimeError # Legal, see #33235
@@ -38,19 +41,20 @@
 Language/Classes/Setters/instance_setter_t04: MissingCompileTimeError # Legal, see #33235
 Language/Classes/Setters/instance_setter_t05: MissingCompileTimeError # Legal, see #33235
 Language/Classes/Setters/instance_setter_t06: MissingCompileTimeError # Legal, see #33235
+Language/Classes/Setters/name_t06: CompileTimeError
+Language/Classes/Setters/name_t07: CompileTimeError
 Language/Classes/Setters/return_type_not_void_t01: CompileTimeError # co19 issue 153
 Language/Classes/Setters/same_name_getter_different_type_t01: CompileTimeError # co19 issue 154
 Language/Classes/Setters/syntax_t04: CompileTimeError # co19 issue 153
 Language/Classes/Setters/type_object_t02: CompileTimeError # co19 issue 153
+Language/Classes/Static_Methods/same_name_method_and_setter_t01: CompileTimeError # Invalid test, see #33237
 Language/Classes/method_definition_t06: MissingCompileTimeError # Please triage this failure
+Language/Classes/mixins_t02: MissingCompileTimeError # This syntax is now allowed
 Language/Enums/syntax_t08: CompileTimeError # Issue 33995
 Language/Enums/syntax_t09: CompileTimeError # Issue 33995
 Language/Errors_and_Warnings/static_warning_t01: CompileTimeError # issue #34319
-Language/Expressions/Conditional/syntax_t03: MissingCompileTimeError # Issue 33995
-Language/Expressions/Conditional/syntax_t04: MissingCompileTimeError # Issue 33995
 Language/Expressions/Constants/constant_list_t02: MissingCompileTimeError # Please triage this failure
 Language/Expressions/Constants/constant_map_t02: MissingCompileTimeError # Please triage this failure
-Language/Expressions/Equality/syntax_t02: MissingCompileTimeError # Issue 33995
 Language/Expressions/Function_Invocation/Unqualified_Invocation/function_expr_invocation_t05: CompileTimeError # Please triage this failure
 Language/Expressions/Function_Invocation/async_cleanup_t01: CompileTimeError # Issue 33995
 Language/Expressions/Function_Invocation/async_cleanup_t02: CompileTimeError # Issue 33995
@@ -96,6 +100,7 @@
 Language/Mixins/Mixin_Application/warning_t03: CompileTimeError # Issue 23878
 Language/Mixins/declaring_constructor_t05: MissingCompileTimeError # Issue 24767
 Language/Mixins/declaring_constructor_t06: MissingCompileTimeError # Issue 24767
+Language/Overview/Privacy/private_and_public_t11: CompileTimeError
 Language/Statements/Continue/async_loops_t01: CompileTimeError # Issue 33995
 Language/Statements/Continue/async_loops_t02: CompileTimeError # Issue 33995
 Language/Statements/Continue/async_loops_t03: CompileTimeError # Issue 33995
@@ -123,7 +128,6 @@
 Language/Statements/Return/no_expression_function_t16: CompileTimeError # issue #34319
 Language/Statements/Return/no_expression_not_function_t01: CompileTimeError # issue #34319
 Language/Types/Interface_Types/subtype_t30: CompileTimeError # Please triage this failure
-Language/Types/Type_Void/syntax_t08: MissingCompileTimeError # Issue 33995
 Language/Types/Type_Void/syntax_t09: CompileTimeError # Please triage this failure
 Language/Types/Type_Void/using_t02: CompileTimeError # Please triage this failure
 LanguageFeatures/Instantiate-to-bound/Callable/Callable_named_extends_neg_assign_l1_t03: MissingCompileTimeError # Issue 34087
@@ -175,7 +179,6 @@
 LanguageFeatures/Instantiate-to-bound/class/custom_extends_neg_assign_l4_t05: Crash # Issue 33152, 33477
 LanguageFeatures/Instantiate-to-bound/class/custom_extends_neg_assign_l4_t06: Crash # Issue 33152, 33477
 LanguageFeatures/Instantiate-to-bound/class/custom_extends_neg_assign_l4_t07: Crash # Issue 33152, 33477
-LanguageFeatures/Instantiate-to-bound/class/custom_extends_neg_l1_t04: MissingCompileTimeError # Issue 33995--use-fasta-parser
 LanguageFeatures/Instantiate-to-bound/function/function_named_extends_neg_assign_l1_t10: CompileTimeError # Issue 33995
 LanguageFeatures/Instantiate-to-bound/function/function_named_extends_pos_l1_t04: CompileTimeError # Issue 33995
 LanguageFeatures/Instantiate-to-bound/function/function_named_extends_pos_l1_t05: CompileTimeError # Issue 33995
@@ -190,7 +193,6 @@
 LanguageFeatures/Instantiate-to-bound/function/function_pos_l1_t01: CompileTimeError # Issue 33995
 LanguageFeatures/Instantiate-to-bound/function/function_ret_extends_neg_assign_l1_t01: MissingCompileTimeError # Issue 33995
 LanguageFeatures/Instantiate-to-bound/function/function_ret_extends_neg_assign_l1_t19: CompileTimeError # Issue 33995
-LanguageFeatures/Instantiate-to-bound/function/function_ret_extends_neg_l1_t01: MissingCompileTimeError # Issue 33995
 LanguageFeatures/Instantiate-to-bound/interface/interface_neg_assign_l2_t01: MissingCompileTimeError # Issue 33995
 LanguageFeatures/Instantiate-to-bound/interface/interface_neg_assign_l2_t02: MissingCompileTimeError # Issue 33308
 LanguageFeatures/Instantiate-to-bound/mixin/mixin_neg_l1_t02: MissingCompileTimeError # Issue 33596
@@ -201,11 +203,9 @@
 LanguageFeatures/Instantiate-to-bound/typedef/typedef_optparam_extends_neg_l1_t03: MissingCompileTimeError # Issue 33597
 LanguageFeatures/Instantiate-to-bound/typedef/typedef_optparam_extends_neg_l2_t01: Crash # Issue 33599
 LanguageFeatures/Instantiate-to-bound/typedef/typedef_param_extends_neg_l1_t02: Crash # Issue 33599
-LanguageFeatures/Instantiate-to-bound/typedef/typedef_param_extends_neg_l1_t03: MissingCompileTimeError # Issue 33995--use-fasta-parser
 LanguageFeatures/Instantiate-to-bound/typedef/typedef_param_extends_neg_l1_t04: MissingCompileTimeError # Issue 33597
 LanguageFeatures/Instantiate-to-bound/typedef/typedef_param_extends_neg_l2_t01: Crash # Issue 33599
 LanguageFeatures/Instantiate-to-bound/typedef/typedef_ret_extends_neg_l1_t02: Crash # Issue 33599
-LanguageFeatures/Instantiate-to-bound/typedef/typedef_ret_extends_neg_l1_t03: MissingCompileTimeError # Issue 33995
 LanguageFeatures/Instantiate-to-bound/typedef/typedef_ret_extends_neg_l1_t04: MissingCompileTimeError # Issue 33597
 LanguageFeatures/Instantiate-to-bound/typedef/typedef_ret_extends_neg_l2_t01: Crash # Issue 33599
 LanguageFeatures/Super-bounded-types/motivation_example_A01_t01: CompileTimeError # Issue 32903
@@ -220,23 +220,5 @@
 LanguageFeatures/Super-bounded-types/static_analysis_A01_t07: CompileTimeError # Issue 32903
 LanguageFeatures/Super-bounded-types/static_analysis_A01_t08: CompileTimeError # Issue 32903
 LanguageFeatures/Super-bounded-types/static_analysis_A01_t09: CompileTimeError # Issue 32903
-LanguageFeatures/int-to-double/arguments_binding_t01: CompileTimeError # Please triage this failure
-LanguageFeatures/int-to-double/arguments_binding_t02: CompileTimeError # Please triage this failure
-LanguageFeatures/int-to-double/assignment_class_member_t01: CompileTimeError # Please triage this failure
-LanguageFeatures/int-to-double/assignment_class_member_t02: CompileTimeError # Please triage this failure
-LanguageFeatures/int-to-double/assignment_global_variable_t01: CompileTimeError # Please triage this failure
-LanguageFeatures/int-to-double/assignment_global_variable_t02: CompileTimeError # Please triage this failure
-LanguageFeatures/int-to-double/assignment_local_variable_t01: CompileTimeError # Please triage this failure
-LanguageFeatures/int-to-double/assignment_local_variable_t02: CompileTimeError # Please triage this failure
-LanguageFeatures/int-to-double/assignment_super_t01: CompileTimeError # Please triage this failure
-LanguageFeatures/int-to-double/assignment_super_t02: CompileTimeError # Please triage this failure
-LanguageFeatures/int-to-double/assignment_this_t01: CompileTimeError # Please triage this failure
-LanguageFeatures/int-to-double/assignment_this_t02: CompileTimeError # Please triage this failure
-LanguageFeatures/int-to-double/max_acceptable_value_t01: CompileTimeError # Please triage this failure
-LanguageFeatures/int-to-double/min_acceptable_values_t01: CompileTimeError # Please triage this failure
-LanguageFeatures/int-to-double/representation_t01: CompileTimeError # Please triage this failure
-LanguageFeatures/int-to-double/representation_t02: CompileTimeError # Please triage this failure
-LanguageFeatures/int-to-double/representation_t03: CompileTimeError # Please triage this failure
-LanguageFeatures/int-to-double/representation_t04: CompileTimeError # Please triage this failure
-LanguageFeatures/int-to-double/return_value_t01: CompileTimeError # Please triage this failure
-LanguageFeatures/int-to-double/return_value_t02: CompileTimeError # Please triage this failure
+LanguageFeatures/int-to-double/min_acceptable_values_t01: CompileTimeError # https://github.com/dart-lang/co19/issues/161
+LanguageFeatures/int-to-double/representation_t01: CompileTimeError # https://github.com/dart-lang/co19/issues/160
diff --git a/tests/co19_2/co19_2-dart2js.status b/tests/co19_2/co19_2-dart2js.status
index 6ba2d65..d45fa1d 100644
--- a/tests/co19_2/co19_2-dart2js.status
+++ b/tests/co19_2/co19_2-dart2js.status
@@ -4,6 +4,7 @@
 
 [ $compiler == dart2js ]
 Language/Classes/Constructors/Generative_Constructors/execution_of_a_superinitializer_t01: RuntimeError
+Language/Classes/mixins_t02: MissingCompileTimeError # co19 issue 163
 Language/Expressions/Assignment/null_aware_assignment_static_type_t01: RuntimeError
 Language/Expressions/Await_Expressions/evaluation_throws_t03: RuntimeError
 Language/Expressions/Booleans/Boolean_Conversion/definition_t01: RuntimeError
@@ -39,7 +40,6 @@
 Language/Metadata/before_type_param_t01: RuntimeError
 Language/Metadata/before_typedef_t01: RuntimeError
 Language/Metadata/before_variable_t01: RuntimeError
-Language/Mixins/Mixin_Application/syntax_t24: RuntimeError
 Language/Statements/Assert/execution_t03: RuntimeError
 Language/Statements/Assert/execution_t08: RuntimeError
 Language/Statements/Assert/execution_t11: RuntimeError
@@ -312,7 +312,7 @@
 LayoutTests/fast/lists/list-style-position-inside_t01: RuntimeError
 LayoutTests/fast/loader/scroll-position-restored-on-reload-at-load-event_t01: RuntimeError
 LayoutTests/fast/multicol/break-properties_t01: RuntimeError
-LayoutTests/fast/multicol/cssom-view_t01: Crash
+LayoutTests/fast/multicol/cssom-view_t01: RuntimeError
 LayoutTests/fast/multicol/fixed-column-percent-logical-height-orthogonal-writing-mode_t01: RuntimeError
 LayoutTests/fast/multicol/hit-test-above-or-below_t01: RuntimeError
 LayoutTests/fast/multicol/hit-test-end-of-column-with-line-height_t01: RuntimeError
@@ -339,10 +339,8 @@
 LayoutTests/fast/table/padding-height-and-override-height_t01: RuntimeError
 LayoutTests/fast/table/table-cell-offset-width_t01: RuntimeError
 LayoutTests/fast/text/international/thai-offsetForPosition-inside-character_t01: RuntimeError
-LayoutTests/fast/text/line-break-after-empty-inline-hebrew_t01: Crash
-LayoutTests/fast/text/line-break-after-inline-latin1_t01: Crash
+LayoutTests/fast/text/line-break-after-inline-latin1_t01: RuntimeError
 LayoutTests/fast/text/line-break-after-question-mark_t01: RuntimeError
-LayoutTests/fast/text/multiglyph-characters_t01: Crash
 LayoutTests/fast/text/remove-zero-length-run_t01: RuntimeError
 LayoutTests/fast/text/sub-pixel/text-scaling-pixel_t01: RuntimeError
 LayoutTests/fast/text/text-combine-shrink-to-fit_t01: RuntimeError
@@ -1272,8 +1270,6 @@
 Language/Metadata/before_param_t07: RuntimeError
 Language/Metadata/before_param_t09: RuntimeError
 Language/Metadata/before_variable_t02: RuntimeError
-Language/Mixins/Mixin_Application/syntax_t23: RuntimeError
-Language/Mixins/Mixin_Application/syntax_t25: RuntimeError
 Language/Overview/Privacy/private_and_public_t18: RuntimeError
 Language/Reference/Operator_Precedence/precedence_15_unary_prefix_t08: RuntimeError
 Language/Statements/Assert/execution_t09: RuntimeError
@@ -1441,7 +1437,6 @@
 LayoutTests/fast/css/content/content-quotes-01_t01: RuntimeError, Pass
 LayoutTests/fast/css/content/content-quotes-05_t01: RuntimeError, Pass
 LayoutTests/fast/css/counters/complex-before_t01: RuntimeError, Pass
-LayoutTests/fast/css/deprecated-flex-box-zero-width-intrinsic-max-width_t01: RuntimeError
 LayoutTests/fast/css/device-aspect-ratio_t01: RuntimeError
 LayoutTests/fast/css/fixed-width-intrinsic-width-excludes-scrollbars_t01: RuntimeError
 LayoutTests/fast/css/focus-display-block-inline_t01: RuntimeError, Pass
@@ -1481,7 +1476,6 @@
 LayoutTests/fast/dom/DOMImplementation/createDocument-namespace-err_t01: RuntimeError
 LayoutTests/fast/dom/Document/CaretRangeFromPoint/caretRangeFromPoint-in-zoom-and-scroll_t01: RuntimeError
 LayoutTests/fast/dom/Element/attribute-uppercase_t01: RuntimeError
-LayoutTests/fast/dom/Element/client-rect-list-argument_t01: RuntimeError
 LayoutTests/fast/dom/Element/getClientRects_t01: RuntimeError
 LayoutTests/fast/dom/HTMLAnchorElement/remove-href-from-focused-anchor_t01: Timeout, Pass
 LayoutTests/fast/dom/HTMLAnchorElement/set-href-attribute-host_t01: RuntimeError
@@ -1536,7 +1530,6 @@
 LayoutTests/fast/dom/MutationObserver/removed-out-of-order_t01: RuntimeError
 LayoutTests/fast/dom/MutationObserver/weak-callback-gc-crash_t01: RuntimeError
 LayoutTests/fast/dom/Range/bug-19527_t01: RuntimeError
-LayoutTests/fast/dom/Range/getClientRects-character_t01: RuntimeError
 LayoutTests/fast/dom/Range/range-created-during-remove-children_t01: RuntimeError, Pass
 LayoutTests/fast/dom/Range/range-detached-exceptions_t01: RuntimeError
 LayoutTests/fast/dom/Range/range-insertNode-splittext_t01: RuntimeError
@@ -1576,6 +1569,7 @@
 LayoutTests/fast/dom/shadow/shadow-disable_t01: RuntimeError
 LayoutTests/fast/dom/shadow/shadow-removechild-and-blur-event_t01: RuntimeError, Pass
 LayoutTests/fast/dom/shadow/shadowdom-for-input-type-change_t01: RuntimeError
+LayoutTests/fast/dom/shadow/shadowhost-keyframes_t01: RuntimeError, Pass
 LayoutTests/fast/dom/shadow/shadowroot-host_t01: RuntimeError
 LayoutTests/fast/dom/shadow/stale-distribution-after-shadow-removal_t01: RuntimeError
 LayoutTests/fast/dynamic/checkbox-selection-crash_t01: RuntimeError
@@ -1605,6 +1599,7 @@
 LayoutTests/fast/files/blob-close-read_t01: RuntimeError
 LayoutTests/fast/files/blob-constructor_t01: RuntimeError
 LayoutTests/fast/files/read-blob-as-array-buffer_t01: RuntimeError
+LayoutTests/fast/filesystem/async-operations_t01: RuntimeError, Pass
 LayoutTests/fast/filesystem/directory-entry-to-uri_t01: RuntimeError
 LayoutTests/fast/filesystem/file-entry-to-uri_t01: RuntimeError
 LayoutTests/fast/filesystem/file-writer-abort-continue_t01: RuntimeError
@@ -1669,7 +1664,6 @@
 LayoutTests/fast/multicol/float-truncation_t01: RuntimeError
 LayoutTests/fast/multicol/hit-test-end-of-column_t01: RuntimeError
 LayoutTests/fast/multicol/hit-test-float_t01: RuntimeError
-LayoutTests/fast/multicol/inline-getclientrects_t01: RuntimeError
 LayoutTests/fast/multicol/newmulticol/balance-images_t01: RuntimeError
 LayoutTests/fast/multicol/newmulticol/balance-maxheight_t01: RuntimeError
 LayoutTests/fast/multicol/vertical-lr/float-truncation_t01: RuntimeError
@@ -1693,6 +1687,7 @@
 LayoutTests/fast/speechsynthesis/speech-synthesis-speak_t01: Timeout, Pass
 LayoutTests/fast/storage/storage-disallowed-in-data-url_t01: RuntimeError
 LayoutTests/fast/sub-pixel/computedstylemargin_t01: RuntimeError, Pass
+LayoutTests/fast/table/col-width-span-expand_t01: RuntimeError, Pass
 LayoutTests/fast/table/fixed-table-layout-toggle-colwidth_t01: RuntimeError, Pass
 LayoutTests/fast/table/fixed-table-with-percent-width-inside-extra-large-div_t01: RuntimeError, Pass
 LayoutTests/fast/table/hittest-tablecell-bottom-edge_t01: RuntimeError
@@ -1713,9 +1708,7 @@
 LayoutTests/fast/text/font-ligatures-linebreak-word_t01: RuntimeError, Pass
 LayoutTests/fast/text/font-ligatures-linebreak_t01: RuntimeError, Pass
 LayoutTests/fast/text/international/iso-8859-8_t01: RuntimeError
-LayoutTests/fast/text/line-break-after-empty-inline-hebrew_t01: RuntimeError
 LayoutTests/fast/text/line-break-after-inline-latin1_t01: RuntimeError
-LayoutTests/fast/text/multiglyph-characters_t01: RuntimeError
 LayoutTests/fast/text/offsetForPosition-cluster-at-zero_t01: RuntimeError
 LayoutTests/fast/text/sub-pixel/text-scaling-ltr_t01: RuntimeError
 LayoutTests/fast/text/sub-pixel/text-scaling-vertical_t01: RuntimeError, Pass
@@ -1737,7 +1730,6 @@
 LayoutTests/fast/url/segments_t01: RuntimeError
 LayoutTests/fast/url/standard-url_t01: RuntimeError
 LayoutTests/fast/writing-mode/flipped-blocks-hit-test-overflow_t01: RuntimeError
-LayoutTests/fast/writing-mode/flipped-blocks-text-map-local-to-container_t01: RuntimeError
 LayoutTests/fast/writing-mode/percentage-margins-absolute-replaced_t01: RuntimeError, Pass
 LayoutTests/fast/writing-mode/percentage-margins-absolute_t01: RuntimeError, Pass
 LayoutTests/fast/writing-mode/table-hit-test_t01: RuntimeError
@@ -1962,6 +1954,7 @@
 WebPlatformTest/shadow-dom/events/retargeting-focus-events/test-001_t05: Timeout, Pass
 WebPlatformTest/shadow-dom/events/retargeting-focus-events/test-001_t06: Timeout, Pass
 WebPlatformTest/shadow-dom/events/retargeting-relatedtarget/test-001_t01: RuntimeError, Pass
+WebPlatformTest/shadow-dom/events/retargeting-relatedtarget/test-002_t01: RuntimeError, Pass
 WebPlatformTest/shadow-dom/html-elements-and-their-shadow-trees/test-001_t01: RuntimeError
 WebPlatformTest/shadow-dom/html-elements-and-their-shadow-trees/test-003_t01: RuntimeError
 WebPlatformTest/shadow-dom/html-elements-and-their-shadow-trees/test-004_t01: RuntimeError
@@ -1988,7 +1981,6 @@
 LayoutTests/fast/canvas/webgl/read-pixels-test_t01: RuntimeError, Pass
 LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image-data_t01: RuntimeError, Pass
 LayoutTests/fast/dom/HTMLDialogElement/submit-dialog-close-event_t01: Timeout, Pass
-LayoutTests/fast/table/col-width-span-expand_t01: RuntimeError, Pass
 LayoutTests/fast/text/international/combining-marks-position_t01: RuntimeError
 
 [ $compiler == dart2js && $runtime == chrome && $system == macos ]
@@ -2032,7 +2024,6 @@
 LayoutTests/fast/css/cssText-shorthand_t01: RuntimeError
 LayoutTests/fast/css/font-face-cache-bug_t01: RuntimeError, Pass
 LayoutTests/fast/dom/DOMException/XPathException_t01: RuntimeError
-LayoutTests/fast/dom/shadow/shadowhost-keyframes_t01: RuntimeError, Pass
 LayoutTests/fast/dom/vertical-scrollbar-in-rtl-doesnt-fire-onscroll_t01: RuntimeError, Pass
 LayoutTests/fast/filesystem/async-operations_t01: RuntimeError, Pass
 LayoutTests/fast/replaced/iframe-with-percentage-height-within-table-with-anonymous-table-cell_t01: RuntimeError
@@ -2054,7 +2045,6 @@
 LibTest/math/cos_A01_t01: RuntimeError
 WebPlatformTest/html/semantics/scripting-1/the-script-element/async_t11: RuntimeError
 WebPlatformTest/html/syntax/parsing/Document.getElementsByTagName-foreign_t01: RuntimeError
-WebPlatformTest/shadow-dom/events/retargeting-relatedtarget/test-002_t01: RuntimeError, Pass
 
 [ $compiler == dart2js && $runtime == chrome && !$fast_startup ]
 WebPlatformTest/html/syntax/parsing/Document.getElementsByTagName-foreign_t01: RuntimeError
@@ -2219,10 +2209,6 @@
 WebPlatformTest/webstorage/storage_session_setitem_quotaexceedederr_t01: RuntimeError
 
 [ $compiler == dart2js && $runtime != chrome && $runtime != ff && $runtime != safari && !$fast_startup ]
-Language/Functions/setter_modifier_t02: Crash
-Language/Functions/setter_modifier_t03: Crash
-Language/Functions/setter_modifier_t05: Crash
-Language/Functions/setter_modifier_t06: Crash
 LayoutTests/fast/animation/request-animation-frame-callback-id_t01: RuntimeError
 LayoutTests/fast/animation/request-animation-frame-cancel_t01: RuntimeError
 LayoutTests/fast/animation/request-animation-frame-timestamps-advance_t01: RuntimeError
@@ -2910,7 +2896,7 @@
 LibTest/html/Element/getAttribute_A01_t01: RuntimeError
 LibTest/html/Element/getBoundingClientRect_A01_t01: RuntimeError
 LibTest/html/Element/getBoundingClientRect_A01_t02: RuntimeError
-LibTest/html/Element/getClientRects_A01_t01: Crash
+LibTest/html/Element/getClientRects_A01_t01: RuntimeError
 LibTest/html/Element/getElementsByClassName_A01_t01: RuntimeError
 LibTest/html/Element/getElementsByClassName_A02_t01: RuntimeError
 LibTest/html/Element/hasChildNodes_A01_t01: RuntimeError
@@ -3086,7 +3072,7 @@
 LibTest/html/IFrameElement/getAttributeNS_A01_t01: RuntimeError
 LibTest/html/IFrameElement/getAttribute_A01_t01: RuntimeError
 LibTest/html/IFrameElement/getBoundingClientRect_A01_t01: RuntimeError
-LibTest/html/IFrameElement/getClientRects_A01_t01: Crash
+LibTest/html/IFrameElement/getClientRects_A01_t01: RuntimeError
 LibTest/html/IFrameElement/getClientRects_A01_t02: RuntimeError
 LibTest/html/IFrameElement/getElementsByClassName_A01_t01: RuntimeError
 LibTest/html/IFrameElement/getElementsByClassName_A02_t01: RuntimeError
@@ -3500,8 +3486,6 @@
 Language/Expressions/Shift/integer_t02: CompileTimeError
 Language/Expressions/Type_Cast/syntax_t01: RuntimeError
 Language/Expressions/Unary_Expressions/variable_negative_t03: RuntimeError
-Language/Functions/setter_modifier_t01: Crash
-Language/Functions/setter_modifier_t04: Crash
 Language/Libraries_and_Scripts/Scripts/top_level_main_t01: CompileTimeError
 Language/Libraries_and_Scripts/top_level_syntax_t01: CompileTimeError
 Language/Metadata/before_ctor_t02: RuntimeError
@@ -3516,8 +3500,6 @@
 Language/Metadata/before_param_t07: RuntimeError
 Language/Metadata/before_param_t09: RuntimeError
 Language/Metadata/before_variable_t02: RuntimeError
-Language/Mixins/Mixin_Application/syntax_t23: RuntimeError
-Language/Mixins/Mixin_Application/syntax_t25: RuntimeError
 Language/Overview/Privacy/private_and_public_t18: RuntimeError
 Language/Reference/Operator_Precedence/precedence_15_unary_prefix_t08: RuntimeError
 Language/Statements/Assert/execution_t09: RuntimeError
@@ -3820,7 +3802,7 @@
 LayoutTests/fast/css/dashboard-regions-attr-crash_t01: RuntimeError
 LayoutTests/fast/css/dashboard-regions-undefined-length-assertion_t01: RuntimeError
 LayoutTests/fast/css/delete-rule-crash_t01: RuntimeError
-LayoutTests/fast/css/deprecated-flex-box-zero-width-intrinsic-max-width_t01: Crash
+LayoutTests/fast/css/deprecated-flex-box-zero-width-intrinsic-max-width_t01: RuntimeError
 LayoutTests/fast/css/device-aspect-ratio_t01: RuntimeError
 LayoutTests/fast/css/div_plus_nav_bug47971_t01: RuntimeError
 LayoutTests/fast/css/draggable-region-parser_t01: RuntimeError
@@ -3989,7 +3971,7 @@
 LayoutTests/fast/dom/DOMImplementation/createHTMLDocument-title_t01: RuntimeError
 LayoutTests/fast/dom/Document/CaretRangeFromPoint/caretRangeFromPoint-in-strict-mode-wtih-checkbox_t01: RuntimeError
 LayoutTests/fast/dom/Document/CaretRangeFromPoint/caretRangeFromPoint-in-user-select-none_t01: RuntimeError
-LayoutTests/fast/dom/Document/CaretRangeFromPoint/caretRangeFromPoint-in-zoom-and-scroll_t01: Crash
+LayoutTests/fast/dom/Document/CaretRangeFromPoint/caretRangeFromPoint-in-zoom-and-scroll_t01: RuntimeError
 LayoutTests/fast/dom/Document/CaretRangeFromPoint/caretRangeFromPoint-with-first-letter-style_t01: RuntimeError
 LayoutTests/fast/dom/Document/clone-node_t01: RuntimeError
 LayoutTests/fast/dom/Document/createElement-invalid-names_t01: RuntimeError
@@ -3997,10 +3979,10 @@
 LayoutTests/fast/dom/Document/title-with-multiple-children_t01: RuntimeError
 LayoutTests/fast/dom/DocumentFragment/document-fragment-constructor_t01: RuntimeError
 LayoutTests/fast/dom/Element/attribute-uppercase_t01: RuntimeError
-LayoutTests/fast/dom/Element/client-rect-list-argument_t01: Crash
+LayoutTests/fast/dom/Element/client-rect-list-argument_t01: RuntimeError
 LayoutTests/fast/dom/Element/dimension-properties-unrendered_t01: RuntimeError
 LayoutTests/fast/dom/Element/getBoundingClientRect-getClientRects-relative-to-viewport_t01: RuntimeError
-LayoutTests/fast/dom/Element/getClientRects_t01: Crash
+LayoutTests/fast/dom/Element/getClientRects_t01: RuntimeError
 LayoutTests/fast/dom/Element/id-in-frame_t01: RuntimeError
 LayoutTests/fast/dom/Element/id-in-getelement01_t01: RuntimeError
 LayoutTests/fast/dom/Element/id-in-insert-hr_t01: RuntimeError
@@ -4155,7 +4137,7 @@
 LayoutTests/fast/dom/Range/bug-19527_t01: RuntimeError
 LayoutTests/fast/dom/Range/create-contextual-fragment-script-unmark-already-started_t01: RuntimeError
 LayoutTests/fast/dom/Range/deleted-range-endpoints_t01: RuntimeError
-LayoutTests/fast/dom/Range/getClientRects-character_t01: Crash
+LayoutTests/fast/dom/Range/getClientRects-character_t01: RuntimeError
 LayoutTests/fast/dom/Range/missing-arguments_t01: RuntimeError
 LayoutTests/fast/dom/Range/range-clone-contents_t01: RuntimeError
 LayoutTests/fast/dom/Range/range-comparePoint_t01: RuntimeError
@@ -4615,7 +4597,7 @@
 LayoutTests/fast/multicol/hit-test-float_t01: RuntimeError
 LayoutTests/fast/multicol/hit-test-gap-between-pages-flipped_t01: RuntimeError
 LayoutTests/fast/multicol/image-inside-nested-blocks-with-border_t01: RuntimeError
-LayoutTests/fast/multicol/inline-getclientrects_t01: Crash
+LayoutTests/fast/multicol/inline-getclientrects_t01: RuntimeError
 LayoutTests/fast/multicol/newmulticol/balance-images_t01: RuntimeError
 LayoutTests/fast/multicol/newmulticol/balance-maxheight_t01: RuntimeError
 LayoutTests/fast/multicol/newmulticol/balance_t01: RuntimeError
@@ -4729,8 +4711,10 @@
 LayoutTests/fast/text/font-ligature-letter-spacing_t01: RuntimeError
 LayoutTests/fast/text/font-size-zero_t01: RuntimeError
 LayoutTests/fast/text/glyph-reordering_t01: RuntimeError
-LayoutTests/fast/text/international/iso-8859-8_t01: Crash
+LayoutTests/fast/text/international/iso-8859-8_t01: RuntimeError
+LayoutTests/fast/text/line-break-after-empty-inline-hebrew_t01: RuntimeError
 LayoutTests/fast/text/line-breaks-after-closing-punctuations_t01: RuntimeError
+LayoutTests/fast/text/multiglyph-characters_t01: RuntimeError
 LayoutTests/fast/text/offsetForPosition-cluster-at-zero_t01: RuntimeError
 LayoutTests/fast/text/soft-hyphen-5_t01: RuntimeError
 LayoutTests/fast/text/sub-pixel/text-scaling-ltr_t01: RuntimeError
@@ -4766,7 +4750,7 @@
 LayoutTests/fast/url/standard-url_t01: RuntimeError
 LayoutTests/fast/writing-mode/auto-margins-across-boundaries_t01: RuntimeError
 LayoutTests/fast/writing-mode/flipped-blocks-hit-test-overflow_t01: RuntimeError
-LayoutTests/fast/writing-mode/flipped-blocks-text-map-local-to-container_t01: Crash
+LayoutTests/fast/writing-mode/flipped-blocks-text-map-local-to-container_t01: RuntimeError
 LayoutTests/fast/writing-mode/overhanging-float-legend-crash_t01: RuntimeError
 LayoutTests/fast/writing-mode/positionForPoint_t01: RuntimeError
 LayoutTests/fast/writing-mode/table-hit-test_t01: RuntimeError
@@ -5177,8 +5161,6 @@
 Language/Metadata/before_param_t07: RuntimeError
 Language/Metadata/before_param_t09: RuntimeError
 Language/Metadata/before_variable_t02: RuntimeError
-Language/Mixins/Mixin_Application/syntax_t23: RuntimeError
-Language/Mixins/Mixin_Application/syntax_t25: RuntimeError
 Language/Overview/Privacy/private_and_public_t18: RuntimeError
 Language/Reference/Operator_Precedence/precedence_15_unary_prefix_t08: RuntimeError
 Language/Statements/Assert/execution_t09: RuntimeError
@@ -5343,7 +5325,6 @@
 LayoutTests/fast/css/counters/complex-before_t01: RuntimeError
 LayoutTests/fast/css/cursor-parsing-image-set_t01: RuntimeError
 LayoutTests/fast/css/cursor-parsing_t01: RuntimeError
-LayoutTests/fast/css/deprecated-flex-box-zero-width-intrinsic-max-width_t01: RuntimeError
 LayoutTests/fast/css/device-aspect-ratio_t01: RuntimeError
 LayoutTests/fast/css/draggable-region-parser_t01: RuntimeError
 LayoutTests/fast/css/fixed-width-intrinsic-width-excludes-scrollbars_t01: RuntimeError
@@ -5413,7 +5394,6 @@
 LayoutTests/fast/dom/Document/CaretRangeFromPoint/caretRangeFromPoint-with-first-letter-style_t01: RuntimeError
 LayoutTests/fast/dom/Document/createElement-valid-names_t01: RuntimeError
 LayoutTests/fast/dom/Element/attribute-uppercase_t01: RuntimeError
-LayoutTests/fast/dom/Element/client-rect-list-argument_t01: RuntimeError
 LayoutTests/fast/dom/Element/getClientRects_t01: RuntimeError
 LayoutTests/fast/dom/Element/id-in-insert-hr_t01: RuntimeError
 LayoutTests/fast/dom/Element/offsetTop-table-cell_t01: RuntimeError
@@ -5756,9 +5736,7 @@
 LayoutTests/fast/text/find-russian_t01: RuntimeError
 LayoutTests/fast/text/find-soft-hyphen_t01: RuntimeError
 LayoutTests/fast/text/international/iso-8859-8_t01: RuntimeError
-LayoutTests/fast/text/line-break-after-empty-inline-hebrew_t01: RuntimeError
 LayoutTests/fast/text/line-break-after-inline-latin1_t01: RuntimeError
-LayoutTests/fast/text/multiglyph-characters_t01: RuntimeError
 LayoutTests/fast/text/offsetForPosition-cluster-at-zero_t01: RuntimeError
 LayoutTests/fast/text/sub-pixel/text-scaling-ltr_t01: RuntimeError
 LayoutTests/fast/text/sub-pixel/text-scaling-vertical_t01: RuntimeError
@@ -5782,7 +5760,6 @@
 LayoutTests/fast/url/segments_t01: RuntimeError
 LayoutTests/fast/url/standard-url_t01: RuntimeError
 LayoutTests/fast/writing-mode/flipped-blocks-hit-test-overflow_t01: RuntimeError
-LayoutTests/fast/writing-mode/flipped-blocks-text-map-local-to-container_t01: RuntimeError
 LayoutTests/fast/writing-mode/positionForPoint_t01: RuntimeError
 LayoutTests/fast/writing-mode/table-hit-test_t01: RuntimeError
 LayoutTests/fast/writing-mode/vertical-inline-block-hittest_t01: RuntimeError
@@ -6108,8 +6085,6 @@
 Language/Metadata/before_param_t07: RuntimeError
 Language/Metadata/before_param_t09: RuntimeError
 Language/Metadata/before_variable_t02: RuntimeError
-Language/Mixins/Mixin_Application/syntax_t23: RuntimeError
-Language/Mixins/Mixin_Application/syntax_t25: RuntimeError
 Language/Overview/Privacy/private_and_public_t18: RuntimeError
 Language/Reference/Operator_Precedence/precedence_15_unary_prefix_t08: RuntimeError
 Language/Statements/Assert/execution_t09: RuntimeError
@@ -6271,7 +6246,6 @@
 LayoutTests/fast/css/counters/complex-before_t01: RuntimeError
 LayoutTests/fast/css/cursor-parsing-image-set_t01: RuntimeError
 LayoutTests/fast/css/cursor-parsing_t01: RuntimeError
-LayoutTests/fast/css/deprecated-flex-box-zero-width-intrinsic-max-width_t01: RuntimeError
 LayoutTests/fast/css/device-aspect-ratio_t01: RuntimeError
 LayoutTests/fast/css/draggable-region-parser_t01: RuntimeError
 LayoutTests/fast/css/fixed-width-intrinsic-width-excludes-scrollbars_t01: RuntimeError
@@ -6340,7 +6314,6 @@
 LayoutTests/fast/dom/Document/CaretRangeFromPoint/caretRangeFromPoint-with-first-letter-style_t01: RuntimeError
 LayoutTests/fast/dom/Document/createElement-valid-names_t01: RuntimeError
 LayoutTests/fast/dom/Element/attribute-uppercase_t01: RuntimeError
-LayoutTests/fast/dom/Element/client-rect-list-argument_t01: RuntimeError
 LayoutTests/fast/dom/Element/getClientRects_t01: RuntimeError
 LayoutTests/fast/dom/Element/id-in-insert-hr_t01: RuntimeError
 LayoutTests/fast/dom/Element/offsetTop-table-cell_t01: RuntimeError
@@ -6423,7 +6396,6 @@
 LayoutTests/fast/dom/MutationObserver/removed-out-of-order_t01: RuntimeError
 LayoutTests/fast/dom/MutationObserver/weak-callback-gc-crash_t01: RuntimeError
 LayoutTests/fast/dom/Range/bug-19527_t01: RuntimeError
-LayoutTests/fast/dom/Range/getClientRects-character_t01: RuntimeError
 LayoutTests/fast/dom/Range/range-created-during-remove-children_t01: RuntimeError
 LayoutTests/fast/dom/Range/range-detached-exceptions_t01: RuntimeError
 LayoutTests/fast/dom/Range/range-insertNode-assertion_t01: RuntimeError
@@ -6642,7 +6614,6 @@
 LayoutTests/fast/multicol/hit-test-float_t01: RuntimeError
 LayoutTests/fast/multicol/hit-test-gap-between-pages-flipped_t01: RuntimeError
 LayoutTests/fast/multicol/image-inside-nested-blocks-with-border_t01: RuntimeError
-LayoutTests/fast/multicol/inline-getclientrects_t01: RuntimeError
 LayoutTests/fast/multicol/vertical-lr/float-truncation_t01: RuntimeError
 LayoutTests/fast/multicol/vertical-rl/float-truncation_t01: RuntimeError
 LayoutTests/fast/multicol/widows_t01: RuntimeError
@@ -6678,9 +6649,7 @@
 LayoutTests/fast/text/find-russian_t01: RuntimeError
 LayoutTests/fast/text/find-soft-hyphen_t01: RuntimeError
 LayoutTests/fast/text/international/iso-8859-8_t01: RuntimeError
-LayoutTests/fast/text/line-break-after-empty-inline-hebrew_t01: RuntimeError
 LayoutTests/fast/text/line-break-after-inline-latin1_t01: RuntimeError
-LayoutTests/fast/text/multiglyph-characters_t01: RuntimeError
 LayoutTests/fast/text/offsetForPosition-cluster-at-zero_t01: RuntimeError
 LayoutTests/fast/text/sub-pixel/text-scaling-ltr_t01: RuntimeError
 LayoutTests/fast/text/sub-pixel/text-scaling-vertical_t01: RuntimeError
@@ -6704,7 +6673,6 @@
 LayoutTests/fast/url/segments_t01: RuntimeError
 LayoutTests/fast/url/standard-url_t01: RuntimeError
 LayoutTests/fast/writing-mode/flipped-blocks-hit-test-overflow_t01: RuntimeError
-LayoutTests/fast/writing-mode/flipped-blocks-text-map-local-to-container_t01: RuntimeError
 LayoutTests/fast/writing-mode/positionForPoint_t01: RuntimeError
 LayoutTests/fast/writing-mode/table-hit-test_t01: RuntimeError
 LayoutTests/fast/writing-mode/vertical-inline-block-hittest_t01: RuntimeError
@@ -7046,8 +7014,6 @@
 Language/Metadata/before_param_t07: RuntimeError
 Language/Metadata/before_param_t09: RuntimeError
 Language/Metadata/before_variable_t02: RuntimeError
-Language/Mixins/Mixin_Application/syntax_t23: RuntimeError
-Language/Mixins/Mixin_Application/syntax_t25: RuntimeError
 Language/Overview/Privacy/private_and_public_t18: RuntimeError
 Language/Reference/Operator_Precedence/precedence_15_unary_prefix_t08: RuntimeError
 Language/Statements/Assert/execution_t09: RuntimeError
@@ -7207,7 +7173,6 @@
 LayoutTests/fast/css/content/content-none_t01: RuntimeError
 LayoutTests/fast/css/content/content-quotes-05_t01: RuntimeError
 LayoutTests/fast/css/cursor-parsing-image-set_t01: RuntimeError
-LayoutTests/fast/css/deprecated-flex-box-zero-width-intrinsic-max-width_t01: RuntimeError
 LayoutTests/fast/css/device-aspect-ratio_t01: RuntimeError
 LayoutTests/fast/css/draggable-region-parser_t01: RuntimeError
 LayoutTests/fast/css/dynamic-class-pseudo-elements_t01: RuntimeError
@@ -7261,7 +7226,6 @@
 LayoutTests/fast/dom/Document/CaretRangeFromPoint/caretRangeFromPoint-in-zoom-and-scroll_t01: RuntimeError
 LayoutTests/fast/dom/Document/CaretRangeFromPoint/caretRangeFromPoint-with-first-letter-style_t01: RuntimeError
 LayoutTests/fast/dom/Element/attribute-uppercase_t01: RuntimeError
-LayoutTests/fast/dom/Element/client-rect-list-argument_t01: RuntimeError
 LayoutTests/fast/dom/Element/getClientRects_t01: RuntimeError
 LayoutTests/fast/dom/Element/offsetTop-table-cell_t01: RuntimeError
 LayoutTests/fast/dom/HTMLAnchorElement/remove-href-from-focused-anchor_t01: Timeout
@@ -7316,7 +7280,6 @@
 LayoutTests/fast/dom/MutationObserver/observe-options-character-data_t01: RuntimeError
 LayoutTests/fast/dom/MutationObserver/weak-callback-gc-crash_t01: RuntimeError
 LayoutTests/fast/dom/Range/bug-19527_t01: RuntimeError
-LayoutTests/fast/dom/Range/getClientRects-character_t01: RuntimeError
 LayoutTests/fast/dom/Range/range-created-during-remove-children_t01: RuntimeError
 LayoutTests/fast/dom/Range/range-detached-exceptions_t01: RuntimeError
 LayoutTests/fast/dom/Range/range-insertNode-splittext_t01: RuntimeError
@@ -7479,7 +7442,6 @@
 LayoutTests/fast/multicol/float-truncation_t01: RuntimeError
 LayoutTests/fast/multicol/hit-test-end-of-column_t01: RuntimeError
 LayoutTests/fast/multicol/hit-test-float_t01: RuntimeError
-LayoutTests/fast/multicol/inline-getclientrects_t01: RuntimeError
 LayoutTests/fast/multicol/newmulticol/balance-images_t01: RuntimeError
 LayoutTests/fast/multicol/newmulticol/balance-maxheight_t01: RuntimeError
 LayoutTests/fast/multicol/vertical-lr/float-truncation_t01: RuntimeError
@@ -7503,7 +7465,7 @@
 LayoutTests/fast/speechsynthesis/speech-synthesis-cancel_t01: RuntimeError
 LayoutTests/fast/speechsynthesis/speech-synthesis-pause-resume_t01: Timeout, Pass
 LayoutTests/fast/speechsynthesis/speech-synthesis-speak_t01: Timeout, Pass
-LayoutTests/fast/speechsynthesis/speech-synthesis-utterance-uses-voice_t01: Timeout
+LayoutTests/fast/speechsynthesis/speech-synthesis-utterance-uses-voice_t01: Timeout, Pass
 LayoutTests/fast/storage/storage-disallowed-in-data-url_t01: RuntimeError
 LayoutTests/fast/sub-pixel/shadows-computed-style_t01: RuntimeError
 LayoutTests/fast/svg/whitespace-angle_t01: RuntimeError
@@ -7530,9 +7492,7 @@
 LayoutTests/fast/text/find-soft-hyphen_t01: RuntimeError
 LayoutTests/fast/text/glyph-reordering_t01: RuntimeError
 LayoutTests/fast/text/international/iso-8859-8_t01: RuntimeError
-LayoutTests/fast/text/line-break-after-empty-inline-hebrew_t01: RuntimeError
 LayoutTests/fast/text/line-break-after-inline-latin1_t01: RuntimeError
-LayoutTests/fast/text/multiglyph-characters_t01: RuntimeError
 LayoutTests/fast/text/offsetForPosition-cluster-at-zero_t01: RuntimeError
 LayoutTests/fast/text/sub-pixel/text-scaling-ltr_t01: RuntimeError
 LayoutTests/fast/text/sub-pixel/text-scaling-vertical_t01: RuntimeError
@@ -7551,7 +7511,6 @@
 LayoutTests/fast/url/relative_t01: RuntimeError
 LayoutTests/fast/url/segments_t01: RuntimeError
 LayoutTests/fast/url/standard-url_t01: RuntimeError
-LayoutTests/fast/writing-mode/flipped-blocks-text-map-local-to-container_t01: RuntimeError
 LayoutTests/fast/xmlhttprequest/xmlhttprequest-responseXML-html-document-responsetype-quirks_t01: RuntimeError
 LayoutTests/fast/xmlhttprequest/xmlhttprequest-responseXML-xml-text-responsetype_t01: RuntimeError
 LayoutTests/fast/xmlhttprequest/xmlhttprequest-responsetype-before-open-sync-request_t01: RuntimeError
diff --git a/tests/co19_2/co19_2-kernel.status b/tests/co19_2/co19_2-kernel.status
index a1c4e33..fdd22f1 100644
--- a/tests/co19_2/co19_2-kernel.status
+++ b/tests/co19_2/co19_2-kernel.status
@@ -51,6 +51,7 @@
 Language/Classes/Superclasses/wrong_superclass_t08: MissingCompileTimeError # Issue 30273
 Language/Classes/Superinterfaces/wrong_type_t05: MissingCompileTimeError # Issue 30273
 Language/Classes/method_definition_t06: MissingCompileTimeError # Legal
+Language/Classes/mixins_t02: MissingCompileTimeError # co19 issue 163
 Language/Enums/syntax_t08: CompileTimeError
 Language/Enums/syntax_t09: CompileTimeError
 Language/Expressions/Assignable_Expressions/syntax_t01: CompileTimeError
@@ -150,7 +151,6 @@
 Language/Types/Static_Types/malformed_type_t01/04: MissingCompileTimeError # Issue 33308
 Language/Types/Static_Types/malformed_type_t01/05: MissingCompileTimeError # Issue 33308
 Language/Types/Static_Types/malformed_type_t01/06: MissingCompileTimeError # Issue 33308
-Language/Types/Type_Void/syntax_t08: MissingCompileTimeError # Issue 33308
 Language/Types/Type_Void/syntax_t09: CompileTimeError # Test contains a compile-time error
 Language/Types/Type_Void/using_t02: CompileTimeError # Test contains a compile-time error
 LanguageFeatures/Instantiate-to-bound/Callable/Callable_named_extends_neg_assign_l1_t01: MissingCompileTimeError # Please triage this failure
@@ -205,7 +205,6 @@
 LanguageFeatures/Instantiate-to-bound/Callable/Callable_ret_extends_neg_assign_l1_t19: MissingCompileTimeError # Issue 34087
 LanguageFeatures/Instantiate-to-bound/Callable/Callable_ret_extends_neg_assign_l1_t20: MissingCompileTimeError # Issue 34087
 LanguageFeatures/Instantiate-to-bound/Callable/Callable_ret_extends_neg_assign_l1_t21: MissingCompileTimeError # Issue 34087
-LanguageFeatures/Instantiate-to-bound/class/custom_extends_neg_l1_t04: MissingCompileTimeError
 LanguageFeatures/Instantiate-to-bound/class/custom_extends_neg_l1_t05: MissingCompileTimeError
 LanguageFeatures/Instantiate-to-bound/function/function_named_extends_neg_assign_l1_t01: MissingCompileTimeError
 LanguageFeatures/Instantiate-to-bound/function/function_named_extends_neg_assign_l1_t03: MissingCompileTimeError
@@ -250,7 +249,6 @@
 LanguageFeatures/Instantiate-to-bound/function/function_ret_extends_neg_assign_l1_t18: MissingCompileTimeError
 LanguageFeatures/Instantiate-to-bound/function/function_ret_extends_neg_assign_l1_t20: MissingCompileTimeError
 LanguageFeatures/Instantiate-to-bound/function/function_ret_extends_neg_assign_l1_t21: MissingCompileTimeError
-LanguageFeatures/Instantiate-to-bound/function/function_ret_extends_neg_l1_t01: MissingCompileTimeError
 LanguageFeatures/Instantiate-to-bound/function/function_ret_extends_neg_l1_t02: MissingCompileTimeError
 LanguageFeatures/Instantiate-to-bound/interface/interface_neg_assign_l2_t01: MissingCompileTimeError
 LanguageFeatures/Instantiate-to-bound/interface/interface_neg_assign_l2_t02: MissingCompileTimeError
@@ -263,10 +261,8 @@
 LanguageFeatures/Instantiate-to-bound/typedef/typedef_named_extends_neg_l2_t02: MissingCompileTimeError
 LanguageFeatures/Instantiate-to-bound/typedef/typedef_optparam_extends_neg_l1_t03: MissingCompileTimeError
 LanguageFeatures/Instantiate-to-bound/typedef/typedef_optparam_extends_neg_l2_t02: MissingCompileTimeError
-LanguageFeatures/Instantiate-to-bound/typedef/typedef_param_extends_neg_l1_t03: MissingCompileTimeError
 LanguageFeatures/Instantiate-to-bound/typedef/typedef_param_extends_neg_l1_t04: MissingCompileTimeError
 LanguageFeatures/Instantiate-to-bound/typedef/typedef_param_extends_neg_l2_t02: MissingCompileTimeError
-LanguageFeatures/Instantiate-to-bound/typedef/typedef_ret_extends_neg_l1_t03: MissingCompileTimeError
 LanguageFeatures/Instantiate-to-bound/typedef/typedef_ret_extends_neg_l1_t04: MissingCompileTimeError
 LanguageFeatures/Instantiate-to-bound/typedef/typedef_ret_extends_neg_l1_t05: MissingCompileTimeError
 LanguageFeatures/Instantiate-to-bound/typedef/typedef_ret_extends_neg_l2_t02: MissingCompileTimeError
diff --git a/tests/compiler/dart2js/analyses/analysis_helper.dart b/tests/compiler/dart2js/analyses/analysis_helper.dart
new file mode 100644
index 0000000..9c6a5d9
--- /dev/null
+++ b/tests/compiler/dart2js/analyses/analysis_helper.dart
@@ -0,0 +1,214 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:async_helper/async_helper.dart';
+import 'package:compiler/src/compiler.dart';
+import 'package:compiler/src/diagnostics/diagnostic_listener.dart';
+import 'package:compiler/src/diagnostics/messages.dart';
+import 'package:compiler/src/diagnostics/source_span.dart';
+import 'package:compiler/src/library_loader.dart';
+import 'package:compiler/src/ir/util.dart';
+import 'package:expect/expect.dart';
+import 'package:kernel/ast.dart' as ir;
+import 'package:kernel/class_hierarchy.dart' as ir;
+import 'package:kernel/core_types.dart' as ir;
+import 'package:kernel/type_environment.dart' as ir;
+
+import '../helpers/memory_compiler.dart';
+
+// TODO(johnniwinther): Update allowed-listing to mention specific properties.
+run(Uri entryPoint,
+    {Map<String, String> memorySourceFiles = const {},
+    Map<String, List<String>> allowedList,
+    bool verbose = false}) {
+  asyncTest(() async {
+    Compiler compiler = await compilerFor(memorySourceFiles: memorySourceFiles);
+    LoadedLibraries loadedLibraries =
+        await compiler.libraryLoader.loadLibraries(entryPoint);
+    new DynamicVisitor(
+            compiler.reporter, loadedLibraries.component, allowedList)
+        .run(verbose: verbose);
+  });
+}
+
+// TODO(johnniwinther): Add improved type promotion to handle negative
+// reasoning.
+// TODO(johnniwinther): Use this visitor in kernel impact computation.
+abstract class StaticTypeVisitor extends ir.Visitor<ir.DartType> {
+  ir.Component get component;
+  ir.TypeEnvironment _typeEnvironment;
+  bool _isStaticTypePrepared = false;
+
+  @override
+  ir.DartType defaultNode(ir.Node node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
+  ir.DartType defaultExpression(ir.Expression node) {
+    defaultNode(node);
+    return getStaticType(node);
+  }
+
+  ir.DartType getStaticType(ir.Expression node) {
+    if (!_isStaticTypePrepared) {
+      _isStaticTypePrepared = true;
+      try {
+        _typeEnvironment ??= new ir.TypeEnvironment(
+            new ir.CoreTypes(component), new ir.ClassHierarchy(component));
+      } catch (e) {}
+    }
+    if (_typeEnvironment == null) {
+      // The class hierarchy crashes on multiple inheritance. Use `dynamic`
+      // as static type.
+      return const ir.DynamicType();
+    }
+    ir.TreeNode enclosingClass = node;
+    while (enclosingClass != null && enclosingClass is! ir.Class) {
+      enclosingClass = enclosingClass.parent;
+    }
+    try {
+      _typeEnvironment.thisType =
+          enclosingClass is ir.Class ? enclosingClass.thisType : null;
+      return node.getStaticType(_typeEnvironment);
+    } catch (e) {
+      // The static type computation crashes on type errors. Use `dynamic`
+      // as static type.
+      return const ir.DynamicType();
+    }
+  }
+}
+
+// TODO(johnniwinther): Handle dynamic access of Object properties/methods
+// separately.
+class DynamicVisitor extends StaticTypeVisitor {
+  final DiagnosticReporter reporter;
+  final ir.Component component;
+  final Map<String, List<String>> allowedList;
+  int _errorCount = 0;
+  Map<String, Set<String>> _encounteredAllowedListedErrors =
+      <String, Set<String>>{};
+  Map<Uri, List<DiagnosticMessage>> _allowedListedErrors =
+      <Uri, List<DiagnosticMessage>>{};
+
+  DynamicVisitor(this.reporter, this.component, this.allowedList);
+
+  void run({bool verbose = false}) {
+    component.accept(this);
+    bool failed = false;
+    if (_errorCount != 0) {
+      print('$_errorCount error(s) found.');
+      failed = true;
+    }
+    allowedList.forEach((String file, List<String> messageParts) {
+      Set<String> encounteredParts = _encounteredAllowedListedErrors[file];
+      if (encounteredParts == null) {
+        print("Allowed-listing of path '$file' isn't used. "
+            "Remove it from the allowed-list.");
+        failed = true;
+      } else if (messageParts != null) {
+        for (String messagePart in messageParts) {
+          if (!encounteredParts.contains(messagePart)) {
+            print("Allowed-listing of message '$messagePart' in path '$file' "
+                "isn't used. Remove it from the allowed-list.");
+          }
+          failed = true;
+        }
+      }
+    });
+    Expect.isFalse(failed, "Errors occurred.");
+    if (verbose) {
+      _allowedListedErrors.forEach((Uri uri, List<DiagnosticMessage> messages) {
+        for (DiagnosticMessage message in messages) {
+          reporter.reportError(message);
+        }
+      });
+    } else {
+      int total = 0;
+      _allowedListedErrors.forEach((Uri uri, List<DiagnosticMessage> messages) {
+        print('${messages.length} error(s) allowed in $uri');
+        total += messages.length;
+      });
+      if (total > 0) {
+        print('${total} error(s) allowed in total.');
+      }
+    }
+  }
+
+  @override
+  ir.DartType visitPropertyGet(ir.PropertyGet node) {
+    ir.DartType result = super.visitPropertyGet(node);
+    ir.DartType type = node.receiver.accept(this);
+    if (type is ir.DynamicType) {
+      reportError(node, "Dynamic access of '${node.name}'.");
+    }
+    return result;
+  }
+
+  @override
+  ir.DartType visitPropertySet(ir.PropertySet node) {
+    ir.DartType result = super.visitPropertySet(node);
+    ir.DartType type = node.receiver.accept(this);
+    if (type is ir.DynamicType) {
+      reportError(node, "Dynamic update to '${node.name}'.");
+    }
+    return result;
+  }
+
+  @override
+  ir.DartType visitMethodInvocation(ir.MethodInvocation node) {
+    ir.DartType result = super.visitMethodInvocation(node);
+    if (node.name.name == '==' &&
+        node.arguments.positional.single is ir.NullLiteral) {
+      return result;
+    }
+    ir.DartType type = node.receiver.accept(this);
+    if (type is ir.DynamicType) {
+      reportError(node, "Dynamic invocation of '${node.name}'.");
+    }
+    return result;
+  }
+
+  void reportError(ir.Node node, String message) {
+    SourceSpan span = computeSourceSpanFromTreeNode(node);
+    Uri uri = span.uri;
+    if (uri.scheme == 'org-dartlang-sdk') {
+      uri = Uri.base.resolve(uri.path.substring(1));
+      span = new SourceSpan(uri, span.begin, span.end);
+    }
+    bool whiteListed = false;
+    allowedList.forEach((String file, List<String> messageParts) {
+      if (uri.path.endsWith(file)) {
+        if (messageParts == null) {
+          // All errors are whitelisted.
+          whiteListed = true;
+          message += ' (white-listed)';
+          _encounteredAllowedListedErrors.putIfAbsent(
+              file, () => new Set<String>());
+        } else {
+          for (String messagePart in messageParts) {
+            if (message.contains(messagePart)) {
+              _encounteredAllowedListedErrors
+                  .putIfAbsent(file, () => new Set<String>())
+                  .add(messagePart);
+              message += ' (allowed)';
+              whiteListed = true;
+            }
+          }
+        }
+      }
+    });
+    DiagnosticMessage diagnosticMessage =
+        reporter.createMessage(span, MessageKind.GENERIC, {'text': message});
+    if (whiteListed) {
+      _allowedListedErrors
+          .putIfAbsent(uri, () => <DiagnosticMessage>[])
+          .add(diagnosticMessage);
+    } else {
+      reporter.reportError(diagnosticMessage);
+      _errorCount++;
+    }
+  }
+}
diff --git a/tests/compiler/dart2js/analyze_test.dart b/tests/compiler/dart2js/analyses/analyze_test.dart
similarity index 100%
rename from tests/compiler/dart2js/analyze_test.dart
rename to tests/compiler/dart2js/analyses/analyze_test.dart
diff --git a/tests/compiler/dart2js/analyses/api_dynamic_test.dart b/tests/compiler/dart2js/analyses/api_dynamic_test.dart
new file mode 100644
index 0000000..0737162
--- /dev/null
+++ b/tests/compiler/dart2js/analyses/api_dynamic_test.dart
@@ -0,0 +1,73 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:async_helper/async_helper.dart';
+import 'analysis_helper.dart';
+
+// TODO(johnniwinther): Remove unneeded dynamic accesses.
+const Map<String, List<String>> allowedList = {
+  'sdk/lib/_http/crypto.dart': null,
+  'sdk/lib/_http/http_date.dart': null,
+  'sdk/lib/_http/http_headers.dart': null,
+  'sdk/lib/_http/http_impl.dart': null,
+  'sdk/lib/_http/http_parser.dart': null,
+  'sdk/lib/_http/websocket_impl.dart': null,
+  'sdk/lib/_internal/js_runtime/lib/async_patch.dart': null,
+  'sdk/lib/_internal/js_runtime/lib/collection_patch.dart': null,
+  'sdk/lib/_internal/js_runtime/lib/constant_map.dart': null,
+  'sdk/lib/_internal/js_runtime/lib/convert_patch.dart': null,
+  'sdk/lib/_internal/js_runtime/lib/core_patch.dart': null,
+  'sdk/lib/_internal/js_runtime/lib/interceptors.dart': null,
+  'sdk/lib/_internal/js_runtime/lib/js_helper.dart': null,
+  'sdk/lib/_internal/js_runtime/lib/js_number.dart': null,
+  'sdk/lib/_internal/js_runtime/lib/js_rti.dart': null,
+  'sdk/lib/_internal/js_runtime/lib/linked_hash_map.dart': null,
+  'sdk/lib/_internal/js_runtime/lib/native_helper.dart': null,
+  'sdk/lib/_internal/js_runtime/lib/native_typed_data.dart': null,
+  'sdk/lib/_internal/js_runtime/lib/regexp_helper.dart': null,
+  'sdk/lib/_internal/js_runtime/lib/string_helper.dart': null,
+  'sdk/lib/async/async_error.dart': null,
+  'sdk/lib/async/future.dart': null,
+  'sdk/lib/async/stream.dart': null,
+  'sdk/lib/collection/hash_map.dart': null,
+  'sdk/lib/collection/iterable.dart': null,
+  'sdk/lib/collection/splay_tree.dart': null,
+  'sdk/lib/convert/encoding.dart': null,
+  'sdk/lib/convert/json.dart': null,
+  'sdk/lib/convert/string_conversion.dart': null,
+  'sdk/lib/core/date_time.dart': null,
+  'sdk/lib/core/duration.dart': null,
+  'sdk/lib/core/errors.dart': null,
+  'sdk/lib/core/exceptions.dart': null,
+  'sdk/lib/core/uri.dart': null,
+  'sdk/lib/html/dart2js/html_dart2js.dart': null,
+  'sdk/lib/html/html_common/conversions.dart': null,
+  'sdk/lib/html/html_common/filtered_element_list.dart': null,
+  'sdk/lib/html/html_common/lists.dart': null,
+  'sdk/lib/indexed_db/dart2js/indexed_db_dart2js.dart': null,
+  'sdk/lib/io/common.dart': null,
+  'sdk/lib/io/directory_impl.dart': null,
+  'sdk/lib/io/file_impl.dart': null,
+  'sdk/lib/io/file_system_entity.dart': null,
+  'sdk/lib/io/io_resource_info.dart': null,
+  'sdk/lib/io/link.dart': null,
+  'sdk/lib/io/platform_impl.dart': null,
+  'sdk/lib/io/secure_server_socket.dart': null,
+  'sdk/lib/io/secure_socket.dart': null,
+  'sdk/lib/io/stdio.dart': null,
+  'sdk/lib/isolate/isolate.dart': null,
+  'sdk/lib/js/dart2js/js_dart2js.dart': null,
+  'sdk/lib/math/point.dart': null,
+  'sdk/lib/math/rectangle.dart': null,
+  'sdk/lib/svg/dart2js/svg_dart2js.dart': null,
+};
+
+main(List<String> args) {
+  asyncTest(() async {
+    await run(Uri.parse('memory:main.dart'),
+        memorySourceFiles: {'main.dart': 'main() {}'},
+        allowedList: allowedList,
+        verbose: args.contains('-v'));
+  });
+}
diff --git a/tests/compiler/dart2js/analyses/dart2js_dynamic_test.dart b/tests/compiler/dart2js/analyses/dart2js_dynamic_test.dart
new file mode 100644
index 0000000..82964d8
--- /dev/null
+++ b/tests/compiler/dart2js/analyses/dart2js_dynamic_test.dart
@@ -0,0 +1,121 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:async_helper/async_helper.dart';
+import 'analysis_helper.dart';
+import 'api_dynamic_test.dart' as api;
+
+// TODO(johnniwinther): Remove unneeded dynamic accesses.
+const Map<String, List<String>> allowedList = {
+  'pkg/compiler/lib/src/closure.dart': null,
+  'pkg/compiler/lib/src/common/tasks.dart': null,
+  'pkg/compiler/lib/src/compiler.dart': null,
+  'pkg/compiler/lib/src/constant_system_dart.dart': null,
+  'pkg/compiler/lib/src/constants/constructors.dart': null,
+  'pkg/compiler/lib/src/constants/expressions.dart': null,
+  'pkg/compiler/lib/src/constants/values.dart': null,
+  'pkg/compiler/lib/src/dart2js.dart': null,
+  'pkg/compiler/lib/src/deferred_load.dart': null,
+  'pkg/compiler/lib/src/diagnostics/messages.dart': null,
+  'pkg/compiler/lib/src/diagnostics/source_span.dart': null,
+  'pkg/compiler/lib/src/elements/entities.dart': null,
+  'pkg/compiler/lib/src/elements/names.dart': null,
+  'pkg/compiler/lib/src/elements/types.dart': null,
+  'pkg/compiler/lib/src/hash/sha1.dart': null,
+  'pkg/compiler/lib/src/helpers/debug_collection.dart': null,
+  'pkg/compiler/lib/src/helpers/expensive_map.dart': null,
+  'pkg/compiler/lib/src/helpers/expensive_set.dart': null,
+  'pkg/compiler/lib/src/helpers/trace.dart': null,
+  'pkg/compiler/lib/src/helpers/track_map.dart': null,
+  'pkg/compiler/lib/src/inferrer/inferrer_engine.dart': null,
+  'pkg/compiler/lib/src/inferrer/locals_handler.dart': null,
+  'pkg/compiler/lib/src/inferrer/node_tracer.dart': null,
+  'pkg/compiler/lib/src/inferrer/type_graph_dump.dart': null,
+  'pkg/compiler/lib/src/inferrer/type_graph_nodes.dart': null,
+  'pkg/compiler/lib/src/inferrer/typemasks/container_type_mask.dart': null,
+  'pkg/compiler/lib/src/inferrer/typemasks/dictionary_type_mask.dart': null,
+  'pkg/compiler/lib/src/inferrer/typemasks/forwarding_type_mask.dart': null,
+  'pkg/compiler/lib/src/inferrer/typemasks/map_type_mask.dart': null,
+  'pkg/compiler/lib/src/inferrer/typemasks/type_mask.dart': null,
+  'pkg/compiler/lib/src/inferrer/typemasks/union_type_mask.dart': null,
+  'pkg/compiler/lib/src/inferrer/typemasks/value_type_mask.dart': null,
+  'pkg/compiler/lib/src/io/position_information.dart': null,
+  'pkg/compiler/lib/src/io/source_information.dart': null,
+  'pkg/compiler/lib/src/js/js.dart': null,
+  'pkg/compiler/lib/src/js/rewrite_async.dart': null,
+  'pkg/compiler/lib/src/js_backend/checked_mode_helpers.dart': null,
+  'pkg/compiler/lib/src/js_backend/constant_system_javascript.dart': null,
+  'pkg/compiler/lib/src/js_backend/namer_names.dart': null,
+  'pkg/compiler/lib/src/js_backend/native_data.dart': null,
+  'pkg/compiler/lib/src/js_emitter/full_emitter/emitter.dart': null,
+  'pkg/compiler/lib/src/js_emitter/program_builder/program_builder.dart': null,
+  'pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_emitter.dart': null,
+  'pkg/compiler/lib/src/js_model/closure.dart': null,
+  'pkg/compiler/lib/src/js_model/js_strategy.dart': null,
+  'pkg/compiler/lib/src/native/behavior.dart': null,
+  'pkg/compiler/lib/src/native/enqueue.dart': null,
+  'pkg/compiler/lib/src/native/js.dart': null,
+  'pkg/compiler/lib/src/source_file_provider.dart': null,
+  'pkg/compiler/lib/src/ssa/builder_kernel.dart': null,
+  'pkg/compiler/lib/src/ssa/interceptor_simplifier.dart': null,
+  'pkg/compiler/lib/src/ssa/nodes.dart': null,
+  'pkg/compiler/lib/src/ssa/optimize.dart': null,
+  'pkg/compiler/lib/src/ssa/types.dart': null,
+  'pkg/compiler/lib/src/ssa/validate.dart': null,
+  'pkg/compiler/lib/src/ssa/value_range_analyzer.dart': null,
+  'pkg/compiler/lib/src/ssa/value_set.dart': null,
+  'pkg/compiler/lib/src/ssa/variable_allocator.dart': null,
+  'pkg/compiler/lib/src/universe/feature.dart': null,
+  'pkg/compiler/lib/src/universe/function_set.dart': null,
+  'pkg/compiler/lib/src/universe/member_usage.dart': null,
+  'pkg/compiler/lib/src/universe/resolution_world_builder.dart': null,
+  'pkg/compiler/lib/src/universe/side_effects.dart': null,
+  'pkg/compiler/lib/src/universe/use.dart': null,
+  'pkg/compiler/lib/src/universe/world_builder.dart': null,
+  'pkg/compiler/lib/src/util/enumset.dart': null,
+  'pkg/compiler/lib/src/util/maplet.dart': null,
+  'pkg/compiler/lib/src/util/setlet.dart': null,
+  'pkg/compiler/lib/src/util/util.dart': null,
+  'pkg/front_end/lib/src/base/libraries_specification.dart': null,
+  'pkg/front_end/lib/src/fasta/builder/function_type_builder.dart': null,
+  'pkg/front_end/lib/src/fasta/colors.dart': null,
+  'pkg/front_end/lib/src/fasta/crash.dart': null,
+  'pkg/front_end/lib/src/fasta/dill/dill_member_builder.dart': null,
+  'pkg/front_end/lib/src/fasta/kernel/body_builder.dart': null,
+  'pkg/front_end/lib/src/fasta/kernel/expression_generator.dart': null,
+  'pkg/front_end/lib/src/fasta/kernel/kernel_class_builder.dart': null,
+  'pkg/front_end/lib/src/fasta/kernel/kernel_function_type_alias_builder.dart':
+      null,
+  'pkg/front_end/lib/src/fasta/kernel/kernel_function_type_builder.dart': null,
+  'pkg/front_end/lib/src/fasta/kernel/kernel_library_builder.dart': null,
+  'pkg/front_end/lib/src/fasta/kernel/kernel_procedure_builder.dart': null,
+  'pkg/front_end/lib/src/fasta/scanner/string_canonicalizer.dart': null,
+  'pkg/front_end/lib/src/fasta/scanner/token.dart': null,
+  'pkg/front_end/lib/src/fasta/source/diet_listener.dart': null,
+  'pkg/front_end/lib/src/fasta/source/outline_builder.dart': null,
+  'pkg/front_end/lib/src/fasta/util/link.dart': null,
+  'pkg/front_end/lib/src/fasta/util/link_implementation.dart': null,
+  'pkg/js_ast/lib/src/builder.dart': null,
+  'pkg/js_ast/lib/src/template.dart': null,
+  'pkg/kernel/lib/ast.dart': null,
+  'pkg/kernel/lib/clone.dart': null,
+  'pkg/kernel/lib/import_table.dart': null,
+  'pkg/kernel/lib/kernel.dart': null,
+  'pkg/kernel/lib/text/ast_to_text.dart': null,
+  'third_party/pkg/dart2js_info/lib/json_info_codec.dart': null,
+  'third_party/pkg/dart2js_info/lib/src/measurements.dart': null,
+  'third_party/pkg/dart2js_info/lib/src/util.dart': null,
+  'third_party/pkg/source_span/lib/src/file.dart': null,
+  'third_party/pkg/source_span/lib/src/span_mixin.dart': null,
+};
+
+main(List<String> args) {
+  asyncTest(() async {
+    Map<String, List<String>> allowed = {};
+    allowed.addAll(api.allowedList);
+    allowed.addAll(allowedList);
+    await run(Uri.parse('package:compiler/src/dart2js.dart'),
+        allowedList: allowed, verbose: args.contains('-v'));
+  });
+}
diff --git a/tests/compiler/dart2js/closure/closure_test.dart b/tests/compiler/dart2js/closure/closure_test.dart
index 89eedbe..a74d20e 100644
--- a/tests/compiler/dart2js/closure/closure_test.dart
+++ b/tests/compiler/dart2js/closure/closure_test.dart
@@ -9,8 +9,9 @@
 import 'package:compiler/src/compiler.dart';
 import 'package:compiler/src/diagnostics/diagnostic_listener.dart';
 import 'package:compiler/src/elements/entities.dart';
+import 'package:compiler/src/js_model/element_map.dart';
 import 'package:compiler/src/kernel/element_map.dart';
-import 'package:compiler/src/kernel/kernel_backend_strategy.dart';
+import 'package:compiler/src/js_model/js_strategy.dart';
 import 'package:compiler/src/js_model/locals.dart';
 import 'package:compiler/src/universe/world_builder.dart';
 import 'package:expect/expect.dart';
@@ -34,8 +35,8 @@
   void computeMemberData(
       Compiler compiler, MemberEntity member, Map<Id, ActualData> actualMap,
       {bool verbose: false}) {
-    KernelBackendStrategy backendStrategy = compiler.backendStrategy;
-    KernelToElementMapForBuilding elementMap = backendStrategy.elementMap;
+    JsBackendStrategy backendStrategy = compiler.backendStrategy;
+    JsToElementMap elementMap = backendStrategy.elementMap;
     GlobalLocalsMap localsMap = backendStrategy.globalLocalsMapForTesting;
     ClosureDataLookup closureDataLookup = backendStrategy.closureDataLookup;
     MemberDefinition definition = elementMap.getMemberDefinition(member);
@@ -74,7 +75,7 @@
   ClosureIrChecker(
       DiagnosticReporter reporter,
       Map<Id, ActualData> actualMap,
-      KernelToElementMapForBuilding elementMap,
+      JsToElementMap elementMap,
       this.member,
       this._localsMap,
       this.closureDataLookup,
diff --git a/tests/compiler/dart2js/codegen/arithmetic_simplification_test.dart b/tests/compiler/dart2js/codegen/arithmetic_simplification_test.dart
index 835facd..35f344f 100644
--- a/tests/compiler/dart2js/codegen/arithmetic_simplification_test.dart
+++ b/tests/compiler/dart2js/codegen/arithmetic_simplification_test.dart
@@ -4,7 +4,7 @@
 // Test constant folding on numbers.
 
 import 'package:async_helper/async_helper.dart';
-import '../compiler_helper.dart';
+import '../helpers/compiler_helper.dart';
 
 const String INT_PLUS_ZERO = """
 int foo(int x) => x;
diff --git a/tests/compiler/dart2js/codegen/array_static_intercept_test.dart b/tests/compiler/dart2js/codegen/array_static_intercept_test.dart
index f7cb5e3..3dc7b76 100644
--- a/tests/compiler/dart2js/codegen/array_static_intercept_test.dart
+++ b/tests/compiler/dart2js/codegen/array_static_intercept_test.dart
@@ -4,7 +4,7 @@
 
 import 'package:expect/expect.dart';
 import 'package:async_helper/async_helper.dart';
-import '../compiler_helper.dart';
+import '../helpers/compiler_helper.dart';
 
 const String TEST_ONE = r"""
 foo(a) {
diff --git a/tests/compiler/dart2js/codegen/builtin_equals_test.dart b/tests/compiler/dart2js/codegen/builtin_equals_test.dart
index f60d067..29d1577 100644
--- a/tests/compiler/dart2js/codegen/builtin_equals_test.dart
+++ b/tests/compiler/dart2js/codegen/builtin_equals_test.dart
@@ -4,7 +4,7 @@
 
 import 'package:expect/expect.dart';
 import 'package:async_helper/async_helper.dart';
-import '../compiler_helper.dart';
+import '../helpers/compiler_helper.dart';
 
 const String TEST = r"""
 foo() {
diff --git a/tests/compiler/dart2js/codegen/builtin_interceptor_test.dart b/tests/compiler/dart2js/codegen/builtin_interceptor_test.dart
index b8e7201..36e15f7 100644
--- a/tests/compiler/dart2js/codegen/builtin_interceptor_test.dart
+++ b/tests/compiler/dart2js/codegen/builtin_interceptor_test.dart
@@ -4,7 +4,7 @@
 
 import 'package:expect/expect.dart';
 import 'package:async_helper/async_helper.dart';
-import '../compiler_helper.dart';
+import '../helpers/compiler_helper.dart';
 
 const String TEST_ONE = r"""
 foo() {
diff --git a/tests/compiler/dart2js/codegen/class_codegen2_test.dart b/tests/compiler/dart2js/codegen/class_codegen2_test.dart
index 2fb2595..213c5f3 100644
--- a/tests/compiler/dart2js/codegen/class_codegen2_test.dart
+++ b/tests/compiler/dart2js/codegen/class_codegen2_test.dart
@@ -6,7 +6,7 @@
 import 'dart:async';
 import "package:expect/expect.dart";
 import "package:async_helper/async_helper.dart";
-import '../compiler_helper.dart';
+import '../helpers/compiler_helper.dart';
 
 const String TEST_ONE = r"""
 class A { foo() => 499; }
diff --git a/tests/compiler/dart2js/codegen/class_codegen_test.dart b/tests/compiler/dart2js/codegen/class_codegen_test.dart
index 63f28ba..a9439f9 100644
--- a/tests/compiler/dart2js/codegen/class_codegen_test.dart
+++ b/tests/compiler/dart2js/codegen/class_codegen_test.dart
@@ -5,7 +5,7 @@
 
 import "package:expect/expect.dart";
 import "package:async_helper/async_helper.dart";
-import '../compiler_helper.dart';
+import '../helpers/compiler_helper.dart';
 
 const String TEST_ONE = r"""
 class A { }
diff --git a/tests/compiler/dart2js/codegen/class_order_test.dart b/tests/compiler/dart2js/codegen/class_order_test.dart
index 14d79a7..28fc7f2 100644
--- a/tests/compiler/dart2js/codegen/class_order_test.dart
+++ b/tests/compiler/dart2js/codegen/class_order_test.dart
@@ -5,7 +5,7 @@
 
 import "package:expect/expect.dart";
 import "package:async_helper/async_helper.dart";
-import '../compiler_helper.dart';
+import '../helpers/compiler_helper.dart';
 
 const String TEST_ONE = r"""
 class A { foo() => 499; }
diff --git a/tests/compiler/dart2js/codegen/closure_codegen_test.dart b/tests/compiler/dart2js/codegen/closure_codegen_test.dart
index 927d023..83119ac 100644
--- a/tests/compiler/dart2js/codegen/closure_codegen_test.dart
+++ b/tests/compiler/dart2js/codegen/closure_codegen_test.dart
@@ -6,7 +6,7 @@
 import 'dart:async';
 import 'package:expect/expect.dart';
 import 'package:async_helper/async_helper.dart';
-import '../compiler_helper.dart';
+import '../helpers/compiler_helper.dart';
 
 const String TEST_INVOCATION0 = r"""
 main() {
diff --git a/tests/compiler/dart2js/codegen/code_motion_test.dart b/tests/compiler/dart2js/codegen/code_motion_test.dart
index b727164..d0f1e59 100644
--- a/tests/compiler/dart2js/codegen/code_motion_test.dart
+++ b/tests/compiler/dart2js/codegen/code_motion_test.dart
@@ -4,7 +4,7 @@
 
 import 'package:expect/expect.dart';
 import 'package:async_helper/async_helper.dart';
-import '../compiler_helper.dart';
+import '../helpers/compiler_helper.dart';
 
 const String TEST_ONE = r"""
 foo(int a, int b, bool param2) {
diff --git a/tests/compiler/dart2js/codegen/constant_folding_codeUnitAt_test.dart b/tests/compiler/dart2js/codegen/constant_folding_codeUnitAt_test.dart
index 9bb13e8..465bc32 100644
--- a/tests/compiler/dart2js/codegen/constant_folding_codeUnitAt_test.dart
+++ b/tests/compiler/dart2js/codegen/constant_folding_codeUnitAt_test.dart
@@ -4,7 +4,7 @@
 // Test constant folding on numbers.
 
 import 'package:async_helper/async_helper.dart';
-import '../compiler_helper.dart';
+import '../helpers/compiler_helper.dart';
 
 const String TEST_1 = """
 foo() {
diff --git a/tests/compiler/dart2js/codegen/constant_folding_test.dart b/tests/compiler/dart2js/codegen/constant_folding_test.dart
index c6d0a58..227d97b 100644
--- a/tests/compiler/dart2js/codegen/constant_folding_test.dart
+++ b/tests/compiler/dart2js/codegen/constant_folding_test.dart
@@ -5,7 +5,7 @@
 
 import 'package:expect/expect.dart';
 import 'package:async_helper/async_helper.dart';
-import '../compiler_helper.dart';
+import '../helpers/compiler_helper.dart';
 
 const String NUMBER_FOLDING = """
 void main() {
diff --git a/tests/compiler/dart2js/codegen/constant_namer_test.dart b/tests/compiler/dart2js/codegen/constant_namer_test.dart
index eca5838..076f377 100644
--- a/tests/compiler/dart2js/codegen/constant_namer_test.dart
+++ b/tests/compiler/dart2js/codegen/constant_namer_test.dart
@@ -4,7 +4,7 @@
 
 import 'package:async_helper/async_helper.dart';
 import 'package:expect/expect.dart';
-import '../compiler_helper.dart';
+import '../helpers/compiler_helper.dart';
 
 const String TEST_ONE = r"""
   class Token {
diff --git a/tests/compiler/dart2js/codegen/dead_code_test.dart b/tests/compiler/dart2js/codegen/dead_code_test.dart
index d62af18..c7ffd88 100644
--- a/tests/compiler/dart2js/codegen/dead_code_test.dart
+++ b/tests/compiler/dart2js/codegen/dead_code_test.dart
@@ -4,7 +4,7 @@
 
 import "package:expect/expect.dart";
 import "package:async_helper/async_helper.dart";
-import '../compiler_helper.dart';
+import '../helpers/compiler_helper.dart';
 
 String TEST = r'''
 main() {
diff --git a/tests/compiler/dart2js/codegen/dead_phi_eliminator_test.dart b/tests/compiler/dart2js/codegen/dead_phi_eliminator_test.dart
index d6627b3..49de078 100644
--- a/tests/compiler/dart2js/codegen/dead_phi_eliminator_test.dart
+++ b/tests/compiler/dart2js/codegen/dead_phi_eliminator_test.dart
@@ -4,7 +4,7 @@
 
 import 'package:expect/expect.dart';
 import 'package:async_helper/async_helper.dart';
-import '../compiler_helper.dart';
+import '../helpers/compiler_helper.dart';
 
 const String TEST_ONE = r"""
 void foo(bar) {
diff --git a/tests/compiler/dart2js/codegen/declare_once_test.dart b/tests/compiler/dart2js/codegen/declare_once_test.dart
index b1d9cbb..849b1bf 100644
--- a/tests/compiler/dart2js/codegen/declare_once_test.dart
+++ b/tests/compiler/dart2js/codegen/declare_once_test.dart
@@ -5,7 +5,7 @@
 
 import 'package:async_helper/async_helper.dart';
 import 'package:expect/expect.dart';
-import '../compiler_helper.dart';
+import '../helpers/compiler_helper.dart';
 
 main() {
   // For a function with only one variable we declare it inline for more
diff --git a/tests/compiler/dart2js/codegen/elide_callthrough_stub_test.dart b/tests/compiler/dart2js/codegen/elide_callthrough_stub_test.dart
index c315c66..67102fe 100644
--- a/tests/compiler/dart2js/codegen/elide_callthrough_stub_test.dart
+++ b/tests/compiler/dart2js/codegen/elide_callthrough_stub_test.dart
@@ -8,7 +8,7 @@
 
 import 'package:async_helper/async_helper.dart';
 import 'package:expect/expect.dart';
-import '../compiler_helper.dart';
+import '../helpers/compiler_helper.dart';
 
 const String TEST1 = r'''
 class W {
diff --git a/tests/compiler/dart2js/codegen/emit_const_fields_test.dart b/tests/compiler/dart2js/codegen/emit_const_fields_test.dart
index abc960f..fbfa9f4 100644
--- a/tests/compiler/dart2js/codegen/emit_const_fields_test.dart
+++ b/tests/compiler/dart2js/codegen/emit_const_fields_test.dart
@@ -5,7 +5,7 @@
 
 import "package:expect/expect.dart";
 import "package:async_helper/async_helper.dart";
-import '../compiler_helper.dart';
+import '../helpers/compiler_helper.dart';
 
 const String TEST_GUIDE = r"""
 class Guide {
diff --git a/tests/compiler/dart2js/codegen/equals_test.dart b/tests/compiler/dart2js/codegen/equals_test.dart
new file mode 100644
index 0000000..9395108
--- /dev/null
+++ b/tests/compiler/dart2js/codegen/equals_test.dart
@@ -0,0 +1,84 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for 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 equals_test;
+
+import 'dart:async';
+import 'package:async_helper/async_helper.dart';
+import '../helpers/compiler_helper.dart';
+
+const String TEST1 = r"""
+foo(int a) {
+  return a == null;
+  // present: 'a == null'
+  // absent: 'eq'
+}
+""";
+
+const String TEST2 = r"""
+foo(int a) {
+  return a == 123;
+  // present: 'a === 123'
+  // absent: 'eq'
+}
+""";
+
+const String TEST3 = r"""
+foo(int a, int b) {
+  return a == b;
+  // present: 'a == b'
+  // absent: 'eq'
+  // absent: '==='
+}
+""";
+
+const String TEST4 = r"""
+foo(String a, String b) {
+  return a == b;
+  // present: 'a == b'
+  // absent: 'eq'
+  // absent: '==='
+}
+""";
+
+// Comparable includes String and int, so can't be compared with `a == b` since
+// that will convert an operand to make `2 =="2"` true.
+const String TEST5 = r"""
+foo(Comparable a, Comparable b) {
+  return a == b;
+  // present: 'a === b'
+  // present: 'a == null'
+  // present: 'b == null'
+  // absent: 'eq'
+  // absent: 'a == b'
+}
+""";
+
+const String TEST6 = r"""
+foo(dynamic a, dynamic b) {
+  return a == b;
+  // present: 'eq'
+  // absent: '=='
+}
+""";
+
+main() {
+  runTests() async {
+    Future check(String test) {
+      return compile(test, entry: 'foo', check: checkerForAbsentPresent(test));
+    }
+
+    await check(TEST1);
+    await check(TEST2);
+    await check(TEST3);
+    await check(TEST4);
+    await check(TEST5);
+    await check(TEST6);
+  }
+
+  asyncTest(() async {
+    print('--test from kernel------------------------------------------------');
+    await runTests();
+  });
+}
diff --git a/tests/compiler/dart2js/codegen/expect_annotations2_test.dart b/tests/compiler/dart2js/codegen/expect_annotations2_test.dart
index 3ceca1c..5b0ba5c 100644
--- a/tests/compiler/dart2js/codegen/expect_annotations2_test.dart
+++ b/tests/compiler/dart2js/codegen/expect_annotations2_test.dart
@@ -5,7 +5,7 @@
 import "package:expect/expect.dart";
 import "package:async_helper/async_helper.dart";
 import 'package:compiler/compiler_new.dart';
-import '../memory_compiler.dart';
+import '../helpers/memory_compiler.dart';
 
 const MEMORY_SOURCE_FILES = const {
   'main.dart': '''
diff --git a/tests/compiler/dart2js/codegen/expect_annotations_test.dart b/tests/compiler/dart2js/codegen/expect_annotations_test.dart
index 93f0714..f317c5b 100644
--- a/tests/compiler/dart2js/codegen/expect_annotations_test.dart
+++ b/tests/compiler/dart2js/codegen/expect_annotations_test.dart
@@ -7,11 +7,10 @@
 import 'package:compiler/src/compiler.dart';
 import 'package:compiler/src/elements/entities.dart';
 import 'package:compiler/src/inferrer/typemasks/masks.dart';
-import 'package:compiler/src/js_backend/annotations.dart' as optimizerHints;
 import 'package:compiler/src/types/types.dart';
 import 'package:compiler/src/world.dart' show JClosedWorld;
 import '../inference/type_mask_test_helper.dart';
-import '../memory_compiler.dart';
+import '../helpers/memory_compiler.dart';
 
 const Map<String, String> MEMORY_SOURCE_FILES = const {
   'main.dart': r"""
@@ -94,19 +93,17 @@
     Expect.isNotNull(method);
     Expect.equals(
         expectNoInline,
-        optimizerHints.noInline(
-            closedWorld.elementEnvironment, closedWorld.commonElements, method),
-        "Unexpected annotation of @NoInline on '$method'.");
+        closedWorld.annotationsData.nonInlinableFunctions.contains(method),
+        "Unexpected annotation of @NoInline() on '$method'.");
     Expect.equals(
         expectTrustTypeAnnotations,
-        optimizerHints.trustTypeAnnotations(
-            closedWorld.elementEnvironment, closedWorld.commonElements, method),
-        "Unexpected annotation of @TrustTypeAnnotations on '$method'.");
+        closedWorld.annotationsData.trustTypeAnnotationsMembers
+            .contains(method),
+        "Unexpected annotation of @TrustTypeAnnotations() on '$method'.");
     Expect.equals(
         expectAssumeDynamic,
-        optimizerHints.assumeDynamic(
-            closedWorld.elementEnvironment, closedWorld.commonElements, method),
-        "Unexpected annotation of @AssumeDynamic on '$method'.");
+        closedWorld.annotationsData.assumeDynamicMembers.contains(method),
+        "Unexpected annotation of @AssumeDynamic() on '$method'.");
     GlobalTypeInferenceResults results =
         compiler.globalInference.resultsForTesting;
     if (expectTrustTypeAnnotations && expectedParameterType != null) {
diff --git a/tests/compiler/dart2js/codegen/field_codegen_test.dart b/tests/compiler/dart2js/codegen/field_codegen_test.dart
index 46229f7..76eea98 100644
--- a/tests/compiler/dart2js/codegen/field_codegen_test.dart
+++ b/tests/compiler/dart2js/codegen/field_codegen_test.dart
@@ -5,7 +5,7 @@
 
 import "package:expect/expect.dart";
 import "package:async_helper/async_helper.dart";
-import '../compiler_helper.dart';
+import '../helpers/compiler_helper.dart';
 
 const String TEST_NULL0 = r"""
 class A { static var x; }
diff --git a/tests/compiler/dart2js/codegen/field_update_test.dart b/tests/compiler/dart2js/codegen/field_update_test.dart
index 6e24a0b..995ce95 100644
--- a/tests/compiler/dart2js/codegen/field_update_test.dart
+++ b/tests/compiler/dart2js/codegen/field_update_test.dart
@@ -4,7 +4,7 @@
 
 import "package:expect/expect.dart";
 import "package:async_helper/async_helper.dart";
-import '../compiler_helper.dart';
+import '../helpers/compiler_helper.dart';
 
 // Test for emitting JavaScript pre- and post-increment and assignment ops.
 
diff --git a/tests/compiler/dart2js/codegen/for_in_test.dart b/tests/compiler/dart2js/codegen/for_in_test.dart
index 0bf5b31..6c5cb0e 100644
--- a/tests/compiler/dart2js/codegen/for_in_test.dart
+++ b/tests/compiler/dart2js/codegen/for_in_test.dart
@@ -4,7 +4,7 @@
 
 import 'package:expect/expect.dart';
 import 'package:async_helper/async_helper.dart';
-import '../compiler_helper.dart';
+import '../helpers/compiler_helper.dart';
 
 const String TEST_ONE = r"""
 foo(a) {
diff --git a/tests/compiler/dart2js/codegen/forloop_box_test.dart b/tests/compiler/dart2js/codegen/forloop_box_test.dart
index 3651aae..aa90153 100644
--- a/tests/compiler/dart2js/codegen/forloop_box_test.dart
+++ b/tests/compiler/dart2js/codegen/forloop_box_test.dart
@@ -4,7 +4,7 @@
 
 import "package:expect/expect.dart";
 import "package:async_helper/async_helper.dart";
-import '../compiler_helper.dart';
+import '../helpers/compiler_helper.dart';
 
 String SHOULD_NOT_BE_BOXED_TEST = r'''
 main() {
diff --git a/tests/compiler/dart2js/codegen/generate_at_use_site_test.dart b/tests/compiler/dart2js/codegen/generate_at_use_site_test.dart
index afb890f..334ecc4 100644
--- a/tests/compiler/dart2js/codegen/generate_at_use_site_test.dart
+++ b/tests/compiler/dart2js/codegen/generate_at_use_site_test.dart
@@ -4,7 +4,7 @@
 
 import 'package:expect/expect.dart';
 import 'package:async_helper/async_helper.dart';
-import '../compiler_helper.dart';
+import '../helpers/compiler_helper.dart';
 
 const String FIB = r"""
 fib(n) {
diff --git a/tests/compiler/dart2js/codegen/gvn_dynamic_field_get_test.dart b/tests/compiler/dart2js/codegen/gvn_dynamic_field_get_test.dart
index 98f7718..d908ebd 100644
--- a/tests/compiler/dart2js/codegen/gvn_dynamic_field_get_test.dart
+++ b/tests/compiler/dart2js/codegen/gvn_dynamic_field_get_test.dart
@@ -4,15 +4,15 @@
 // Test that dart2js gvns dynamic getters that don't have side
 // effects.
 
-import 'package:expect/expect.dart';
 import 'package:async_helper/async_helper.dart';
-import '../compiler_helper.dart';
 import 'package:compiler/compiler_new.dart';
 import 'package:compiler/src/compiler.dart';
 import 'package:compiler/src/elements/names.dart';
 import 'package:compiler/src/universe/selector.dart' show Selector;
 import 'package:compiler/src/world.dart';
-import '../memory_compiler.dart';
+import 'package:expect/expect.dart';
+import '../helpers/compiler_helper.dart';
+import '../helpers/memory_compiler.dart';
 
 const String TEST = r"""
 class A {
diff --git a/tests/compiler/dart2js/codegen/gvn_test.dart b/tests/compiler/dart2js/codegen/gvn_test.dart
index ab196ad..54f4d30 100644
--- a/tests/compiler/dart2js/codegen/gvn_test.dart
+++ b/tests/compiler/dart2js/codegen/gvn_test.dart
@@ -4,7 +4,7 @@
 
 import 'package:expect/expect.dart';
 import 'package:async_helper/async_helper.dart';
-import '../compiler_helper.dart';
+import '../helpers/compiler_helper.dart';
 
 const String TEST_ONE = r"""
 void foo(bar) {
diff --git a/tests/compiler/dart2js/codegen/identity_test.dart b/tests/compiler/dart2js/codegen/identity_test.dart
index 1f400f1..03ef1ba 100644
--- a/tests/compiler/dart2js/codegen/identity_test.dart
+++ b/tests/compiler/dart2js/codegen/identity_test.dart
@@ -4,7 +4,7 @@
 
 import 'package:expect/expect.dart';
 import 'package:async_helper/async_helper.dart';
-import '../compiler_helper.dart';
+import '../helpers/compiler_helper.dart';
 
 const String TEST_ONE = r"""
 class A {}
diff --git a/tests/compiler/dart2js/codegen/if_do_while_test.dart b/tests/compiler/dart2js/codegen/if_do_while_test.dart
index 63d5b1e..06c963c 100644
--- a/tests/compiler/dart2js/codegen/if_do_while_test.dart
+++ b/tests/compiler/dart2js/codegen/if_do_while_test.dart
@@ -4,7 +4,7 @@
 
 import 'package:expect/expect.dart';
 import 'package:async_helper/async_helper.dart';
-import '../compiler_helper.dart';
+import '../helpers/compiler_helper.dart';
 
 const String TEST = r"""
 foo(param0, param1, param2) {
diff --git a/tests/compiler/dart2js/codegen/interceptor_almost_constant_test.dart b/tests/compiler/dart2js/codegen/interceptor_almost_constant_test.dart
index acc5fff..ee6c404 100644
--- a/tests/compiler/dart2js/codegen/interceptor_almost_constant_test.dart
+++ b/tests/compiler/dart2js/codegen/interceptor_almost_constant_test.dart
@@ -4,7 +4,7 @@
 
 import 'package:expect/expect.dart';
 import 'package:async_helper/async_helper.dart';
-import '../compiler_helper.dart';
+import '../helpers/compiler_helper.dart';
 
 const String TEST_ONE = r"""
   foo(b) {
diff --git a/tests/compiler/dart2js/codegen/interceptor_test.dart b/tests/compiler/dart2js/codegen/interceptor_test.dart
index 5b3be69..e77058e 100644
--- a/tests/compiler/dart2js/codegen/interceptor_test.dart
+++ b/tests/compiler/dart2js/codegen/interceptor_test.dart
@@ -4,7 +4,7 @@
 
 import 'package:expect/expect.dart';
 import 'package:async_helper/async_helper.dart';
-import '../compiler_helper.dart';
+import '../helpers/compiler_helper.dart';
 
 const String TEST_ONE = r"""
   foo(a) {
diff --git a/tests/compiler/dart2js/codegen/interpolation_folding_test.dart b/tests/compiler/dart2js/codegen/interpolation_folding_test.dart
index ef88234..4b88d9d 100644
--- a/tests/compiler/dart2js/codegen/interpolation_folding_test.dart
+++ b/tests/compiler/dart2js/codegen/interpolation_folding_test.dart
@@ -4,7 +4,7 @@
 
 import 'package:async_helper/async_helper.dart';
 import 'package:expect/expect.dart';
-import '../compiler_helper.dart';
+import '../helpers/compiler_helper.dart';
 
 // Tests for
 const String TEST_1 = r"""
diff --git a/tests/compiler/dart2js/codegen/inverse_operator_test.dart b/tests/compiler/dart2js/codegen/inverse_operator_test.dart
index 5881a49..5d5e1d2 100644
--- a/tests/compiler/dart2js/codegen/inverse_operator_test.dart
+++ b/tests/compiler/dart2js/codegen/inverse_operator_test.dart
@@ -3,7 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:async_helper/async_helper.dart';
-import '../compiler_helper.dart';
+import '../helpers/compiler_helper.dart';
 
 const String MAIN = r"""
 int inscrutable(int x) => x == 0 ? 0 : x | inscrutable(x & (x - 1));
diff --git a/tests/compiler/dart2js/codegen/is_function_test.dart b/tests/compiler/dart2js/codegen/is_function_test.dart
index e535c69..53cbaf3 100644
--- a/tests/compiler/dart2js/codegen/is_function_test.dart
+++ b/tests/compiler/dart2js/codegen/is_function_test.dart
@@ -10,7 +10,7 @@
 import 'package:compiler/src/compiler.dart';
 import 'package:compiler/src/js_emitter/model.dart';
 import 'package:expect/expect.dart';
-import '../memory_compiler.dart';
+import '../helpers/memory_compiler.dart';
 
 const String SOURCE = '''
 import 'dart:isolate';
diff --git a/tests/compiler/dart2js/codegen/is_inference2_test.dart b/tests/compiler/dart2js/codegen/is_inference2_test.dart
index cfd6ba9..4117a99 100644
--- a/tests/compiler/dart2js/codegen/is_inference2_test.dart
+++ b/tests/compiler/dart2js/codegen/is_inference2_test.dart
@@ -4,7 +4,7 @@
 
 import 'package:expect/expect.dart';
 import 'package:async_helper/async_helper.dart';
-import '../compiler_helper.dart';
+import '../helpers/compiler_helper.dart';
 
 const String TEST_IF_BOOL_FIRST_INSTRUCTION = r"""
 negate(x) {
diff --git a/tests/compiler/dart2js/codegen/is_inference_test.dart b/tests/compiler/dart2js/codegen/is_inference_test.dart
index 8758dd8..195e02c 100644
--- a/tests/compiler/dart2js/codegen/is_inference_test.dart
+++ b/tests/compiler/dart2js/codegen/is_inference_test.dart
@@ -5,7 +5,7 @@
 import 'dart:async';
 import 'package:expect/expect.dart';
 import 'package:async_helper/async_helper.dart';
-import '../compiler_helper.dart';
+import '../helpers/compiler_helper.dart';
 
 const String TEST_IF = r"""
 test(param) {
diff --git a/tests/compiler/dart2js/codegen/jsarray_indexof_test.dart b/tests/compiler/dart2js/codegen/jsarray_indexof_test.dart
index c915f48..e105f5f 100644
--- a/tests/compiler/dart2js/codegen/jsarray_indexof_test.dart
+++ b/tests/compiler/dart2js/codegen/jsarray_indexof_test.dart
@@ -15,7 +15,7 @@
 import 'package:compiler/src/js/js.dart' as js;
 import 'package:compiler/src/universe/selector.dart';
 import 'package:expect/expect.dart';
-import '../memory_compiler.dart';
+import '../helpers/memory_compiler.dart';
 import '../helpers/element_lookup.dart';
 import '../helpers/program_lookup.dart';
 
diff --git a/tests/compiler/dart2js/codegen/licm_test.dart b/tests/compiler/dart2js/codegen/licm_test.dart
index 731da5c..32f889c 100644
--- a/tests/compiler/dart2js/codegen/licm_test.dart
+++ b/tests/compiler/dart2js/codegen/licm_test.dart
@@ -6,7 +6,7 @@
 // condition involves control flow.
 
 import 'package:async_helper/async_helper.dart';
-import '../compiler_helper.dart';
+import '../helpers/compiler_helper.dart';
 
 const String TEST = '''
 var a = [1];
diff --git a/tests/compiler/dart2js/codegen/list_tracer_length_test.dart b/tests/compiler/dart2js/codegen/list_tracer_length_test.dart
index ac42284..7f97bb9 100644
--- a/tests/compiler/dart2js/codegen/list_tracer_length_test.dart
+++ b/tests/compiler/dart2js/codegen/list_tracer_length_test.dart
@@ -6,7 +6,7 @@
 
 import "package:expect/expect.dart";
 import "package:async_helper/async_helper.dart";
-import '../compiler_helper.dart';
+import '../helpers/compiler_helper.dart';
 
 const String TEST1 = r"""
 var a = [42];
diff --git a/tests/compiler/dart2js/codegen/list_tracer_node_type_test.dart b/tests/compiler/dart2js/codegen/list_tracer_node_type_test.dart
index 5ce5970..1aa5c2a 100644
--- a/tests/compiler/dart2js/codegen/list_tracer_node_type_test.dart
+++ b/tests/compiler/dart2js/codegen/list_tracer_node_type_test.dart
@@ -4,7 +4,7 @@
 
 import "package:expect/expect.dart";
 import "package:async_helper/async_helper.dart";
-import '../compiler_helper.dart';
+import '../helpers/compiler_helper.dart';
 
 const String TEST1 = r"""
 main() {
diff --git a/tests/compiler/dart2js/codegen/literal_list_test.dart b/tests/compiler/dart2js/codegen/literal_list_test.dart
index bae6dea..ae346c3 100644
--- a/tests/compiler/dart2js/codegen/literal_list_test.dart
+++ b/tests/compiler/dart2js/codegen/literal_list_test.dart
@@ -4,7 +4,7 @@
 
 import 'package:expect/expect.dart';
 import 'package:async_helper/async_helper.dart';
-import '../compiler_helper.dart';
+import '../helpers/compiler_helper.dart';
 
 const String TEST_ONE = r"""
 foo() {
diff --git a/tests/compiler/dart2js/codegen/literal_map_test.dart b/tests/compiler/dart2js/codegen/literal_map_test.dart
index c1bfcf3..b5db2aa 100644
--- a/tests/compiler/dart2js/codegen/literal_map_test.dart
+++ b/tests/compiler/dart2js/codegen/literal_map_test.dart
@@ -4,7 +4,7 @@
 
 import 'package:expect/expect.dart';
 import 'package:async_helper/async_helper.dart';
-import '../compiler_helper.dart';
+import '../helpers/compiler_helper.dart';
 
 const String TEST = """
 foo() {
diff --git a/tests/compiler/dart2js/codegen/load_elimination_test.dart b/tests/compiler/dart2js/codegen/load_elimination_test.dart
index be948ce..fa16f0f 100644
--- a/tests/compiler/dart2js/codegen/load_elimination_test.dart
+++ b/tests/compiler/dart2js/codegen/load_elimination_test.dart
@@ -4,7 +4,7 @@
 
 import "package:expect/expect.dart";
 import "package:async_helper/async_helper.dart";
-import '../compiler_helper.dart';
+import '../helpers/compiler_helper.dart';
 
 const String TEST_1 = """
 class A {
diff --git a/tests/compiler/dart2js/codegen/logical_expression_test.dart b/tests/compiler/dart2js/codegen/logical_expression_test.dart
index 2efbaca..2108602 100644
--- a/tests/compiler/dart2js/codegen/logical_expression_test.dart
+++ b/tests/compiler/dart2js/codegen/logical_expression_test.dart
@@ -5,7 +5,7 @@
 // Test that logical or-expressions don't introduce unnecessary nots.
 
 import 'package:async_helper/async_helper.dart';
-import '../compiler_helper.dart';
+import '../helpers/compiler_helper.dart';
 
 const String TEST_ONE = r"""
 foo(bar, gee) {
diff --git a/tests/compiler/dart2js/codegen/loop_test.dart b/tests/compiler/dart2js/codegen/loop_test.dart
index 2615469..acd1d88 100644
--- a/tests/compiler/dart2js/codegen/loop_test.dart
+++ b/tests/compiler/dart2js/codegen/loop_test.dart
@@ -4,7 +4,7 @@
 
 import 'package:expect/expect.dart';
 import 'package:async_helper/async_helper.dart';
-import '../compiler_helper.dart';
+import '../helpers/compiler_helper.dart';
 
 const String TEST_ONE = r"""
 foo(a) {
diff --git a/tests/compiler/dart2js/codegen/minify_many_locals_test.dart b/tests/compiler/dart2js/codegen/minify_many_locals_test.dart
index 598996d..197f77c 100644
--- a/tests/compiler/dart2js/codegen/minify_many_locals_test.dart
+++ b/tests/compiler/dart2js/codegen/minify_many_locals_test.dart
@@ -5,7 +5,7 @@
 
 import 'package:async_helper/async_helper.dart';
 import 'package:expect/expect.dart';
-import '../compiler_helper.dart';
+import '../helpers/compiler_helper.dart';
 
 main() {
   runTests({int numberOfParameters}) async {
diff --git a/tests/compiler/dart2js/codegen/modulo_remainder_test.dart b/tests/compiler/dart2js/codegen/modulo_remainder_test.dart
index 7997dbf..7faffa0 100644
--- a/tests/compiler/dart2js/codegen/modulo_remainder_test.dart
+++ b/tests/compiler/dart2js/codegen/modulo_remainder_test.dart
@@ -3,7 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:async_helper/async_helper.dart';
-import '../compiler_helper.dart';
+import '../helpers/compiler_helper.dart';
 
 const String MOD1 = r"""
 foo(param) {
diff --git a/tests/compiler/dart2js/codegen/negation_shift_regression_test.dart b/tests/compiler/dart2js/codegen/negation_shift_regression_test.dart
index aeb6731..f3ac6fd 100644
--- a/tests/compiler/dart2js/codegen/negation_shift_regression_test.dart
+++ b/tests/compiler/dart2js/codegen/negation_shift_regression_test.dart
@@ -3,7 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:async_helper/async_helper.dart';
-import '../compiler_helper.dart';
+import '../helpers/compiler_helper.dart';
 
 // A bug in UnaryNegateSpecializer left '-a' labelled as 'positive', allowing
 // misoptimization of '<<'.
diff --git a/tests/compiler/dart2js/codegen/no_constructor_body_test.dart b/tests/compiler/dart2js/codegen/no_constructor_body_test.dart
index 2279739..e34f13c 100644
--- a/tests/compiler/dart2js/codegen/no_constructor_body_test.dart
+++ b/tests/compiler/dart2js/codegen/no_constructor_body_test.dart
@@ -4,7 +4,7 @@
 
 import "package:expect/expect.dart";
 import "package:async_helper/async_helper.dart";
-import '../compiler_helper.dart';
+import '../helpers/compiler_helper.dart';
 
 const String TEST = r"""
 class A {
diff --git a/tests/compiler/dart2js/codegen/no_duplicate_constructor_body2_test.dart b/tests/compiler/dart2js/codegen/no_duplicate_constructor_body2_test.dart
index e7cd4cd..cd9f5a7 100644
--- a/tests/compiler/dart2js/codegen/no_duplicate_constructor_body2_test.dart
+++ b/tests/compiler/dart2js/codegen/no_duplicate_constructor_body2_test.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-import '../compiler_helper.dart';
+import '../helpers/compiler_helper.dart';
 import "package:async_helper/async_helper.dart";
 
 const String CODE = """
diff --git a/tests/compiler/dart2js/codegen/no_duplicate_constructor_body_test.dart b/tests/compiler/dart2js/codegen/no_duplicate_constructor_body_test.dart
index f5625d5..194fce2 100644
--- a/tests/compiler/dart2js/codegen/no_duplicate_constructor_body_test.dart
+++ b/tests/compiler/dart2js/codegen/no_duplicate_constructor_body_test.dart
@@ -3,7 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import "package:async_helper/async_helper.dart";
-import '../compiler_helper.dart';
+import '../helpers/compiler_helper.dart';
 
 const String CODE = """
 class A {
diff --git a/tests/compiler/dart2js/codegen/no_duplicate_stub_test.dart b/tests/compiler/dart2js/codegen/no_duplicate_stub_test.dart
index cd7a05a..98db5e4 100644
--- a/tests/compiler/dart2js/codegen/no_duplicate_stub_test.dart
+++ b/tests/compiler/dart2js/codegen/no_duplicate_stub_test.dart
@@ -3,7 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import "package:async_helper/async_helper.dart";
-import '../compiler_helper.dart';
+import '../helpers/compiler_helper.dart';
 
 const String TEST = r"""
 class A {
diff --git a/tests/compiler/dart2js/codegen/null_check_test.dart b/tests/compiler/dart2js/codegen/null_check_test.dart
index 90b7847..63d226e 100644
--- a/tests/compiler/dart2js/codegen/null_check_test.dart
+++ b/tests/compiler/dart2js/codegen/null_check_test.dart
@@ -3,7 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import "package:expect/expect.dart";
-import '../compiler_helper.dart';
+import '../helpers/compiler_helper.dart';
 import "package:async_helper/async_helper.dart";
 
 const String TEST1 = r"""
diff --git a/tests/compiler/dart2js/codegen/null_type_test.dart b/tests/compiler/dart2js/codegen/null_type_test.dart
index ecbf6df..0a23eaf 100644
--- a/tests/compiler/dart2js/codegen/null_type_test.dart
+++ b/tests/compiler/dart2js/codegen/null_type_test.dart
@@ -4,7 +4,7 @@
 
 import 'package:expect/expect.dart';
 import 'package:async_helper/async_helper.dart';
-import '../compiler_helper.dart';
+import '../helpers/compiler_helper.dart';
 
 const String TEST_ONE = r"""
 foo() {
diff --git a/tests/compiler/dart2js/codegen/number_output_test.dart b/tests/compiler/dart2js/codegen/number_output_test.dart
index 8bfe28e..317b5ad 100644
--- a/tests/compiler/dart2js/codegen/number_output_test.dart
+++ b/tests/compiler/dart2js/codegen/number_output_test.dart
@@ -7,7 +7,7 @@
 import 'package:compiler/compiler_new.dart';
 import 'package:compiler/src/commandline_options.dart';
 import 'package:async_helper/async_helper.dart';
-import '../memory_compiler.dart';
+import '../helpers/memory_compiler.dart';
 
 const MEMORY_SOURCE_FILES = const {
   'main.dart': '''
diff --git a/tests/compiler/dart2js/codegen/parameter_phi_elimination_test.dart b/tests/compiler/dart2js/codegen/parameter_phi_elimination_test.dart
index 2b843d6..5c9aa95 100644
--- a/tests/compiler/dart2js/codegen/parameter_phi_elimination_test.dart
+++ b/tests/compiler/dart2js/codegen/parameter_phi_elimination_test.dart
@@ -7,7 +7,7 @@
 // VMOptions=--enable_asserts
 
 import 'package:async_helper/async_helper.dart';
-import '../compiler_helper.dart';
+import '../helpers/compiler_helper.dart';
 
 const String SOURCE = r"""
 bool baz(int a, int b) {
diff --git a/tests/compiler/dart2js/codegen/pretty_parameter_test.dart b/tests/compiler/dart2js/codegen/pretty_parameter_test.dart
index f23704d..882be84 100644
--- a/tests/compiler/dart2js/codegen/pretty_parameter_test.dart
+++ b/tests/compiler/dart2js/codegen/pretty_parameter_test.dart
@@ -5,7 +5,7 @@
 
 import 'package:expect/expect.dart';
 import 'package:async_helper/async_helper.dart';
-import '../compiler_helper.dart';
+import '../helpers/compiler_helper.dart';
 
 const String FOO = r"""
 void foo(var a, var b) {
diff --git a/tests/compiler/dart2js/codegen/redundant_phi_eliminator_test.dart b/tests/compiler/dart2js/codegen/redundant_phi_eliminator_test.dart
index a6f6c37..210c142 100644
--- a/tests/compiler/dart2js/codegen/redundant_phi_eliminator_test.dart
+++ b/tests/compiler/dart2js/codegen/redundant_phi_eliminator_test.dart
@@ -4,7 +4,7 @@
 
 import 'package:expect/expect.dart';
 import 'package:async_helper/async_helper.dart';
-import '../compiler_helper.dart';
+import '../helpers/compiler_helper.dart';
 
 const String TEST_ONE = r"""
 void foo(bar) {
diff --git a/tests/compiler/dart2js/codegen/regress_10231_test.dart b/tests/compiler/dart2js/codegen/regress_10231_test.dart
index bc97ecb..9133791 100644
--- a/tests/compiler/dart2js/codegen/regress_10231_test.dart
+++ b/tests/compiler/dart2js/codegen/regress_10231_test.dart
@@ -6,7 +6,7 @@
 
 import 'package:expect/expect.dart';
 import "package:async_helper/async_helper.dart";
-import '../compiler_helper.dart';
+import '../helpers/compiler_helper.dart';
 
 const String SOURCE = """
 test(a, b, c, d) {
diff --git a/tests/compiler/dart2js/codegen/side_effect_tdiv_regression_test.dart b/tests/compiler/dart2js/codegen/side_effect_tdiv_regression_test.dart
index 670316a..2648985 100644
--- a/tests/compiler/dart2js/codegen/side_effect_tdiv_regression_test.dart
+++ b/tests/compiler/dart2js/codegen/side_effect_tdiv_regression_test.dart
@@ -5,7 +5,7 @@
 import 'package:expect/expect.dart';
 import "package:async_helper/async_helper.dart";
 
-import '../compiler_helper.dart';
+import '../helpers/compiler_helper.dart';
 
 const String TEST = r'''
 class A {
diff --git a/tests/compiler/dart2js/codegen/simple_function_subtype_test.dart b/tests/compiler/dart2js/codegen/simple_function_subtype_test.dart
index 6f64cdf..eece082 100644
--- a/tests/compiler/dart2js/codegen/simple_function_subtype_test.dart
+++ b/tests/compiler/dart2js/codegen/simple_function_subtype_test.dart
@@ -8,7 +8,7 @@
 
 import 'package:expect/expect.dart';
 import 'package:async_helper/async_helper.dart';
-import '../compiler_helper.dart';
+import '../helpers/compiler_helper.dart';
 
 const String TEST = r"""
 typedef Args0();
diff --git a/tests/compiler/dart2js/codegen/simple_inferrer_relations_test.dart b/tests/compiler/dart2js/codegen/simple_inferrer_relations_test.dart
index 6eef9bb..21bb5d0 100644
--- a/tests/compiler/dart2js/codegen/simple_inferrer_relations_test.dart
+++ b/tests/compiler/dart2js/codegen/simple_inferrer_relations_test.dart
@@ -7,7 +7,7 @@
 import 'package:async_helper/async_helper.dart';
 import 'package:expect/expect.dart';
 
-import '../compiler_helper.dart';
+import '../helpers/compiler_helper.dart';
 
 // Test that if (x == y) where we know nothing about x and y will get optimized
 // to if ($.$eq(x, y)) and not
diff --git a/tests/compiler/dart2js/codegen/ssa_phi_codegen_test.dart b/tests/compiler/dart2js/codegen/ssa_phi_codegen_test.dart
index d06e5ba..7799586 100644
--- a/tests/compiler/dart2js/codegen/ssa_phi_codegen_test.dart
+++ b/tests/compiler/dart2js/codegen/ssa_phi_codegen_test.dart
@@ -4,7 +4,7 @@
 // Test that parameters keep their names in the output.
 
 import 'package:async_helper/async_helper.dart';
-import '../compiler_helper.dart';
+import '../helpers/compiler_helper.dart';
 
 const String TEST_ONE = r"""
 void foo(bar) {
diff --git a/tests/compiler/dart2js/codegen/static_closure_test.dart b/tests/compiler/dart2js/codegen/static_closure_test.dart
index 7865768..7b3947d 100644
--- a/tests/compiler/dart2js/codegen/static_closure_test.dart
+++ b/tests/compiler/dart2js/codegen/static_closure_test.dart
@@ -6,7 +6,7 @@
 
 import "package:expect/expect.dart";
 import "package:async_helper/async_helper.dart";
-import '../compiler_helper.dart';
+import '../helpers/compiler_helper.dart';
 
 main() {
   runTest() async {
diff --git a/tests/compiler/dart2js/codegen/strength_eq_test.dart b/tests/compiler/dart2js/codegen/strength_eq_test.dart
index c2f063a..e0c1090d 100644
--- a/tests/compiler/dart2js/codegen/strength_eq_test.dart
+++ b/tests/compiler/dart2js/codegen/strength_eq_test.dart
@@ -4,7 +4,7 @@
 // Test constant folding on numbers.
 
 import 'package:async_helper/async_helper.dart';
-import '../compiler_helper.dart';
+import '../helpers/compiler_helper.dart';
 
 const String CODE = """
 class A {
diff --git a/tests/compiler/dart2js/codegen/string_add_test.dart b/tests/compiler/dart2js/codegen/string_add_test.dart
index da069f1..2b64f35 100644
--- a/tests/compiler/dart2js/codegen/string_add_test.dart
+++ b/tests/compiler/dart2js/codegen/string_add_test.dart
@@ -4,7 +4,7 @@
 
 import "package:expect/expect.dart";
 import "package:async_helper/async_helper.dart";
-import '../compiler_helper.dart';
+import '../helpers/compiler_helper.dart';
 
 main() {
   runTest() async {
diff --git a/tests/compiler/dart2js/codegen/string_escapes_test.dart b/tests/compiler/dart2js/codegen/string_escapes_test.dart
index c765230..16d469d 100644
--- a/tests/compiler/dart2js/codegen/string_escapes_test.dart
+++ b/tests/compiler/dart2js/codegen/string_escapes_test.dart
@@ -5,7 +5,7 @@
 import 'dart:async';
 import 'package:async_helper/async_helper.dart';
 import 'package:expect/expect.dart';
-import '../compiler_helper.dart';
+import '../helpers/compiler_helper.dart';
 
 // Test that the compiler handles string literals containing line terminators.
 
diff --git a/tests/compiler/dart2js/codegen/string_interpolation_test.dart b/tests/compiler/dart2js/codegen/string_interpolation_test.dart
index 720f498..c36f45e 100644
--- a/tests/compiler/dart2js/codegen/string_interpolation_test.dart
+++ b/tests/compiler/dart2js/codegen/string_interpolation_test.dart
@@ -4,7 +4,7 @@
 
 import "package:expect/expect.dart";
 import "package:async_helper/async_helper.dart";
-import '../compiler_helper.dart';
+import '../helpers/compiler_helper.dart';
 
 main() {
   runTests() async {
diff --git a/tests/compiler/dart2js/codegen/switch_empty_default_test.dart b/tests/compiler/dart2js/codegen/switch_empty_default_test.dart
index 19121e1..0ba4272 100644
--- a/tests/compiler/dart2js/codegen/switch_empty_default_test.dart
+++ b/tests/compiler/dart2js/codegen/switch_empty_default_test.dart
@@ -4,7 +4,7 @@
 // Test constant folding on numbers.
 
 import 'package:async_helper/async_helper.dart';
-import '../compiler_helper.dart';
+import '../helpers/compiler_helper.dart';
 
 const String SIMPLY_EMPTY = """
 int foo(x) => x;
diff --git a/tests/compiler/dart2js/codegen/tdiv_test.dart b/tests/compiler/dart2js/codegen/tdiv_test.dart
index 0101c71..86e6f08 100644
--- a/tests/compiler/dart2js/codegen/tdiv_test.dart
+++ b/tests/compiler/dart2js/codegen/tdiv_test.dart
@@ -6,7 +6,7 @@
 
 import 'dart:async';
 import 'package:async_helper/async_helper.dart';
-import '../compiler_helper.dart';
+import '../helpers/compiler_helper.dart';
 
 const String TEST1 = r"""
 foo(param) {
diff --git a/tests/compiler/dart2js/codegen/top_level_closure_tree_shake_test.dart b/tests/compiler/dart2js/codegen/top_level_closure_tree_shake_test.dart
index 5f21bfe..5868d23 100644
--- a/tests/compiler/dart2js/codegen/top_level_closure_tree_shake_test.dart
+++ b/tests/compiler/dart2js/codegen/top_level_closure_tree_shake_test.dart
@@ -4,7 +4,7 @@
 
 import 'package:expect/expect.dart';
 import 'package:async_helper/async_helper.dart';
-import '../compiler_helper.dart';
+import '../helpers/compiler_helper.dart';
 
 const String TEST_ONE = r"""
 main() {
diff --git a/tests/compiler/dart2js/codegen/tree_shaking_test.dart b/tests/compiler/dart2js/codegen/tree_shaking_test.dart
index 8fa1ee9..518851d 100644
--- a/tests/compiler/dart2js/codegen/tree_shaking_test.dart
+++ b/tests/compiler/dart2js/codegen/tree_shaking_test.dart
@@ -4,7 +4,7 @@
 
 import "package:expect/expect.dart";
 import "package:async_helper/async_helper.dart";
-import '../compiler_helper.dart';
+import '../helpers/compiler_helper.dart';
 
 const String TEST = r"""
 class A {
diff --git a/tests/compiler/dart2js/codegen/trust_type_annotations2_test.dart b/tests/compiler/dart2js/codegen/trust_type_annotations2_test.dart
index b5b8bdd..9f2eed7 100644
--- a/tests/compiler/dart2js/codegen/trust_type_annotations2_test.dart
+++ b/tests/compiler/dart2js/codegen/trust_type_annotations2_test.dart
@@ -5,7 +5,7 @@
 import 'package:expect/expect.dart';
 import "package:async_helper/async_helper.dart";
 import 'package:compiler/src/commandline_options.dart';
-import '../memory_compiler.dart';
+import '../helpers/memory_compiler.dart';
 
 const MEMORY_SOURCE_FILES = const {
   'main.dart': '''
diff --git a/tests/compiler/dart2js/codegen/trust_type_annotations_test.dart b/tests/compiler/dart2js/codegen/trust_type_annotations_test.dart
index f7feed2..5937b0d 100644
--- a/tests/compiler/dart2js/codegen/trust_type_annotations_test.dart
+++ b/tests/compiler/dart2js/codegen/trust_type_annotations_test.dart
@@ -7,7 +7,7 @@
 import 'package:compiler/src/commandline_options.dart';
 import 'package:compiler/src/elements/entities.dart';
 import 'package:compiler/src/inferrer/typemasks/masks.dart';
-import '../memory_compiler.dart';
+import '../helpers/memory_compiler.dart';
 
 const String TEST = """
 class A {
diff --git a/tests/compiler/dart2js/codegen/type_guard_unuser_test.dart b/tests/compiler/dart2js/codegen/type_guard_unuser_test.dart
index 0b3e412..35f1617 100644
--- a/tests/compiler/dart2js/codegen/type_guard_unuser_test.dart
+++ b/tests/compiler/dart2js/codegen/type_guard_unuser_test.dart
@@ -4,7 +4,7 @@
 
 import 'package:expect/expect.dart';
 import 'package:async_helper/async_helper.dart';
-import '../compiler_helper.dart';
+import '../helpers/compiler_helper.dart';
 
 const String TEST_ONE = r"""
 foo(a) {
diff --git a/tests/compiler/dart2js/codegen/type_inference2_test.dart b/tests/compiler/dart2js/codegen/type_inference2_test.dart
index 415f8fc..77366de 100644
--- a/tests/compiler/dart2js/codegen/type_inference2_test.dart
+++ b/tests/compiler/dart2js/codegen/type_inference2_test.dart
@@ -3,7 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:async_helper/async_helper.dart';
-import '../compiler_helper.dart';
+import '../helpers/compiler_helper.dart';
 
 const String TEST_ONE = r"""
 sum(param0, param1) {
diff --git a/tests/compiler/dart2js/codegen/type_inference3_test.dart b/tests/compiler/dart2js/codegen/type_inference3_test.dart
index 8574b25..0580e9e 100644
--- a/tests/compiler/dart2js/codegen/type_inference3_test.dart
+++ b/tests/compiler/dart2js/codegen/type_inference3_test.dart
@@ -4,7 +4,7 @@
 
 import 'package:expect/expect.dart';
 import 'package:async_helper/async_helper.dart';
-import '../compiler_helper.dart';
+import '../helpers/compiler_helper.dart';
 
 const String TEST_ONE = r"""
 sum(param0, param1) {
diff --git a/tests/compiler/dart2js/codegen/type_inference4_test.dart b/tests/compiler/dart2js/codegen/type_inference4_test.dart
index 6dc393f..754f094 100644
--- a/tests/compiler/dart2js/codegen/type_inference4_test.dart
+++ b/tests/compiler/dart2js/codegen/type_inference4_test.dart
@@ -4,7 +4,7 @@
 
 import 'package:expect/expect.dart';
 import 'package:async_helper/async_helper.dart';
-import '../compiler_helper.dart';
+import '../helpers/compiler_helper.dart';
 
 const String TEST_ONE = r"""
 foo(j) {
diff --git a/tests/compiler/dart2js/codegen/type_inference5_test.dart b/tests/compiler/dart2js/codegen/type_inference5_test.dart
index 75799aa..e478856 100644
--- a/tests/compiler/dart2js/codegen/type_inference5_test.dart
+++ b/tests/compiler/dart2js/codegen/type_inference5_test.dart
@@ -4,7 +4,7 @@
 
 import 'package:expect/expect.dart';
 import 'package:async_helper/async_helper.dart';
-import '../compiler_helper.dart';
+import '../helpers/compiler_helper.dart';
 
 const String TEST_ONE = r"""
 foo(j) {
diff --git a/tests/compiler/dart2js/codegen/type_inference8_test.dart b/tests/compiler/dart2js/codegen/type_inference8_test.dart
index b3d232e..865f73e 100644
--- a/tests/compiler/dart2js/codegen/type_inference8_test.dart
+++ b/tests/compiler/dart2js/codegen/type_inference8_test.dart
@@ -9,7 +9,7 @@
 import "package:compiler/src/constants/values.dart";
 import 'package:compiler/src/inferrer/typemasks/masks.dart';
 import "package:expect/expect.dart";
-import '../memory_compiler.dart';
+import '../helpers/memory_compiler.dart';
 
 import 'dart:async';
 
diff --git a/tests/compiler/dart2js/codegen/types_of_captured_variables_test.dart b/tests/compiler/dart2js/codegen/types_of_captured_variables_test.dart
index aa6a3b7..d327223 100644
--- a/tests/compiler/dart2js/codegen/types_of_captured_variables_test.dart
+++ b/tests/compiler/dart2js/codegen/types_of_captured_variables_test.dart
@@ -4,7 +4,7 @@
 
 import 'package:expect/expect.dart';
 import "package:async_helper/async_helper.dart";
-import '../compiler_helper.dart';
+import '../helpers/compiler_helper.dart';
 
 const String TEST1 = r"""
 main() {
diff --git a/tests/compiler/dart2js/codegen/unused_empty_map_test.dart b/tests/compiler/dart2js/codegen/unused_empty_map_test.dart
index dd7d6fb..cf3fa88 100644
--- a/tests/compiler/dart2js/codegen/unused_empty_map_test.dart
+++ b/tests/compiler/dart2js/codegen/unused_empty_map_test.dart
@@ -7,7 +7,7 @@
 import 'package:async_helper/async_helper.dart';
 import 'package:compiler/compiler_new.dart';
 import 'package:expect/expect.dart';
-import '../memory_compiler.dart';
+import '../helpers/memory_compiler.dart';
 
 const TEST_SOURCE = const {
   "main.dart": r"""
diff --git a/tests/compiler/dart2js/codegen/use_checks_test.dart b/tests/compiler/dart2js/codegen/use_checks_test.dart
index 0d50d070..d22e26d 100644
--- a/tests/compiler/dart2js/codegen/use_checks_test.dart
+++ b/tests/compiler/dart2js/codegen/use_checks_test.dart
@@ -5,7 +5,7 @@
 import 'package:async_helper/async_helper.dart';
 import 'package:compiler/src/commandline_options.dart';
 import 'package:expect/expect.dart';
-import '../memory_compiler.dart';
+import '../helpers/memory_compiler.dart';
 
 const MEMORY_SOURCE_FILES = const {
   'main.dart': '''
diff --git a/tests/compiler/dart2js/codegen/use_strict_test.dart b/tests/compiler/dart2js/codegen/use_strict_test.dart
index 6c65a7f..896cbd4 100644
--- a/tests/compiler/dart2js/codegen/use_strict_test.dart
+++ b/tests/compiler/dart2js/codegen/use_strict_test.dart
@@ -5,7 +5,7 @@
 import 'package:async_helper/async_helper.dart';
 import 'package:compiler/compiler_new.dart';
 import 'package:expect/expect.dart';
-import '../memory_compiler.dart';
+import '../helpers/memory_compiler.dart';
 
 // Use strict does not allow parameters or locals named "arguments" or "eval".
 
diff --git a/tests/compiler/dart2js/codegen/value_range3_test.dart b/tests/compiler/dart2js/codegen/value_range3_test.dart
index bc973e5..62286e7 100644
--- a/tests/compiler/dart2js/codegen/value_range3_test.dart
+++ b/tests/compiler/dart2js/codegen/value_range3_test.dart
@@ -6,7 +6,7 @@
 
 import 'package:async_helper/async_helper.dart';
 import 'package:expect/expect.dart';
-import '../memory_compiler.dart';
+import '../helpers/memory_compiler.dart';
 
 const MEMORY_SOURCE_FILES = const {
   'main.dart': '''
diff --git a/tests/compiler/dart2js/codegen/value_range_test.dart b/tests/compiler/dart2js/codegen/value_range_test.dart
index 10e3f32..a50b20e 100644
--- a/tests/compiler/dart2js/codegen/value_range_test.dart
+++ b/tests/compiler/dart2js/codegen/value_range_test.dart
@@ -5,7 +5,7 @@
 import 'dart:async';
 import 'package:async_helper/async_helper.dart';
 import 'package:expect/expect.dart';
-import '../compiler_helper.dart';
+import '../helpers/compiler_helper.dart';
 
 const int REMOVED = 0;
 const int ABOVE_ZERO = 1;
diff --git a/tests/compiler/dart2js/dart2js.status b/tests/compiler/dart2js/dart2js.status
index f6d4117..b39dc5f4f 100644
--- a/tests/compiler/dart2js/dart2js.status
+++ b/tests/compiler/dart2js/dart2js.status
@@ -2,9 +2,7 @@
 # for details. All rights reserved. Use of this source code is governed by a
 # BSD-style license that can be found in the LICENSE file.
 
-analyze_test: Slow, Pass
-async_await_syntax_test: Pass # DON'T CHANGE THIS LINE -- Don't mark these tests as failing. Instead, fix the errors/warnings that they report or update the whitelist in the test-files to temporarily allow digression.
-boolified_operator_test: Fail # Issue 8001
+analyses/analyze_test: Slow, Pass
 closure/closure_test: Pass, Slow
 codegen/gvn_dynamic_field_get_test: Fail # Issue 18519
 codegen/list_tracer_length_test: Fail # Issue 33051
@@ -15,9 +13,10 @@
 codegen/string_escapes_test: Fail # Issue 33060
 deferred_loading/deferred_loading_test: Slow, Pass
 end_to_end/dump_info_test: Slow, Pass
+end_to_end/generate_code_with_compile_time_errors_test: RuntimeError # not supported yet with the new FE.
+end_to_end/show_package_warnings_test: RuntimeError # missing errors from the FE
 equivalence/id_equivalence1_test: Pass, Slow
 equivalence/id_equivalence2_test: Pass, Slow
-generate_code_with_compile_time_errors_test: RuntimeError # not supported yet with the new FE.
 inference/inference0_test: Slow, Pass
 inference/inference1_test: Slow, Pass
 inference/simple_inferrer_const_closure2_test: Fail # Issue 16507
@@ -26,46 +25,37 @@
 inference/swarm_test: Slow, Pass, Fail #
 inference/type_mask2_test: RuntimeError # Issue 34095
 inlining/inlining_test: Slow, Pass
-kernel/*: Slow, Pass
-kernel/compile_from_dill_fast_startup_test: RuntimeError # Test must be updated to support FE with patching.
-kernel/compile_from_dill_test: RuntimeError # Test must be updated to support FE with patching.
 model/native_test: Pass, Slow
+model/no_such_method_enabled_test: Pass, Slow
 model/subtype_test: Pass, Slow
-no_such_method_enabled_test: Pass, Slow
 packages/*: Skip # Skip packages folder
 rti/rti_emission_test: Pass, Slow
 rti/rti_need0_test: Pass, Slow
 rti/rti_need1_test: Pass, Slow
-show_package_warnings_test: RuntimeError # missing errors from the FE
 sourcemaps/d2js_validity_test: RuntimeError # Issue 33072
 sourcemaps/deferred_d2js_validity_test: RuntimeError # Issue 33072
 sourcemaps/source_mapping_invokes_test: Pass, Slow
 sourcemaps/source_mapping_operators_test: Pass, Slow
 sourcemaps/source_mapping_test: Pass, Slow
-subtype_test: Slow, Pass
 
 [ $mode == debug ]
 deferred/load_graph_segmentation_test: Pass, Slow
 deferred/load_mapping_test: Pass, Slow
 end_to_end/dart2js_batch_test: Pass, Slow
 end_to_end/exit_code_test: Pass, Slow
-in_user_code_test: Pass, Slow
-show_package_warnings_test: Pass, Slow
-
-[ $system == linux ]
-dart2js_batch2_test: Pass, RuntimeError # Issue 29021
+end_to_end/in_user_code_test: Pass, Slow
+end_to_end/show_package_warnings_test: Pass, Slow
 
 [ $checked ]
 codegen/value_range_kernel_test: Pass, Slow
 codegen/value_range_test: Pass, Slow
 end_to_end/exit_code_test: Pass, Slow
+end_to_end/output_type_test: Pass, Slow
+end_to_end/uri_retention_test: Pass, Slow
 jsinterop/declaration_test: Slow, Pass
 jsinterop/interop_anonymous_unreachable_test: Pass, Slow
 jsinterop/world_test: Pass, Slow
-kernel/visitor_test: Pass, Slow
-output_type_test: Pass, Slow
 sourcemaps/stacktrace_test: Pass, Slow
-uri_retention_test: Pass, Slow
 
 [ !$checked ]
 end_to_end/exit_code_test: Skip # This tests requires checked mode.
diff --git a/tests/compiler/dart2js/deferred/closures_test.dart b/tests/compiler/dart2js/deferred/closures_test.dart
index ea6148b..3f6d36d 100644
--- a/tests/compiler/dart2js/deferred/closures_test.dart
+++ b/tests/compiler/dart2js/deferred/closures_test.dart
@@ -8,8 +8,8 @@
 import 'package:compiler/compiler_new.dart';
 import 'package:expect/expect.dart';
 
-import '../memory_compiler.dart';
-import '../output_collector.dart';
+import '../helpers/memory_compiler.dart';
+import '../helpers/output_collector.dart';
 
 void main() {
   asyncTest(() async {
diff --git a/tests/compiler/dart2js/deferred/custom_element_test.dart b/tests/compiler/dart2js/deferred/custom_element_test.dart
index 3b39cfd..5618ff6 100644
--- a/tests/compiler/dart2js/deferred/custom_element_test.dart
+++ b/tests/compiler/dart2js/deferred/custom_element_test.dart
@@ -9,7 +9,7 @@
 import 'package:async_helper/async_helper.dart';
 import 'package:compiler/src/compiler.dart';
 import 'package:expect/expect.dart';
-import '../memory_compiler.dart';
+import '../helpers/memory_compiler.dart';
 
 void main() {
   asyncTest(() async {
diff --git a/tests/compiler/dart2js/deferred/dont_inline_deferred_constants_test.dart b/tests/compiler/dart2js/deferred/dont_inline_deferred_constants_test.dart
index e4d9e05..388e4fd 100644
--- a/tests/compiler/dart2js/deferred/dont_inline_deferred_constants_test.dart
+++ b/tests/compiler/dart2js/deferred/dont_inline_deferred_constants_test.dart
@@ -9,8 +9,8 @@
 import 'package:compiler/compiler_new.dart';
 import 'package:compiler/src/compiler.dart';
 import 'package:expect/expect.dart';
-import '../memory_compiler.dart';
-import '../output_collector.dart';
+import '../helpers/memory_compiler.dart';
+import '../helpers/output_collector.dart';
 
 void main() {
   runTest() async {
diff --git a/tests/compiler/dart2js/deferred/dont_inline_deferred_globals_test.dart b/tests/compiler/dart2js/deferred/dont_inline_deferred_globals_test.dart
index 4c3db2a..f9f973c 100644
--- a/tests/compiler/dart2js/deferred/dont_inline_deferred_globals_test.dart
+++ b/tests/compiler/dart2js/deferred/dont_inline_deferred_globals_test.dart
@@ -9,8 +9,8 @@
 import 'package:compiler/compiler_new.dart';
 import 'package:compiler/src/compiler.dart';
 import 'package:expect/expect.dart';
-import '../memory_compiler.dart';
-import '../output_collector.dart';
+import '../helpers/memory_compiler.dart';
+import '../helpers/output_collector.dart';
 
 void main() {
   runTest() async {
diff --git a/tests/compiler/dart2js/deferred/emit_type_checks_test.dart b/tests/compiler/dart2js/deferred/emit_type_checks_test.dart
index f016ac2..a6cf80c 100644
--- a/tests/compiler/dart2js/deferred/emit_type_checks_test.dart
+++ b/tests/compiler/dart2js/deferred/emit_type_checks_test.dart
@@ -10,8 +10,8 @@
 import 'package:compiler/src/compiler.dart';
 import 'package:compiler/src/js_backend/js_backend.dart' show JavaScriptBackend;
 import 'package:expect/expect.dart';
-import '../memory_compiler.dart';
-import '../output_collector.dart';
+import '../helpers/memory_compiler.dart';
+import '../helpers/output_collector.dart';
 
 void main() {
   runTest() async {
diff --git a/tests/compiler/dart2js/deferred/follow_constant_dependencies_test.dart b/tests/compiler/dart2js/deferred/follow_constant_dependencies_test.dart
index 4e72c4c..d192a4d 100644
--- a/tests/compiler/dart2js/deferred/follow_constant_dependencies_test.dart
+++ b/tests/compiler/dart2js/deferred/follow_constant_dependencies_test.dart
@@ -8,7 +8,7 @@
 import 'package:compiler/src/compiler.dart';
 import 'package:compiler/src/constants/values.dart';
 import 'package:expect/expect.dart';
-import '../memory_compiler.dart';
+import '../helpers/memory_compiler.dart';
 
 void main() {
   runTest() async {
diff --git a/tests/compiler/dart2js/deferred/follow_implicit_super_regression_test.dart b/tests/compiler/dart2js/deferred/follow_implicit_super_regression_test.dart
index 1a67951..26ab5044 100644
--- a/tests/compiler/dart2js/deferred/follow_implicit_super_regression_test.dart
+++ b/tests/compiler/dart2js/deferred/follow_implicit_super_regression_test.dart
@@ -6,7 +6,7 @@
 import 'package:compiler/src/compiler.dart' as dart2js;
 import 'package:expect/expect.dart';
 
-import '../memory_compiler.dart';
+import '../helpers/memory_compiler.dart';
 
 void main() {
   runTest() async {
diff --git a/tests/compiler/dart2js/deferred/inline_restrictions_test.dart b/tests/compiler/dart2js/deferred/inline_restrictions_test.dart
index 789baf0..c5c5b53 100644
--- a/tests/compiler/dart2js/deferred/inline_restrictions_test.dart
+++ b/tests/compiler/dart2js/deferred/inline_restrictions_test.dart
@@ -9,7 +9,7 @@
 import 'package:compiler/compiler_new.dart';
 import 'package:compiler/src/compiler.dart';
 import 'package:expect/expect.dart';
-import '../memory_compiler.dart';
+import '../helpers/memory_compiler.dart';
 
 void main() {
   asyncTest(() async {
diff --git a/tests/compiler/dart2js/deferred/load_graph_segmentation2_test.dart b/tests/compiler/dart2js/deferred/load_graph_segmentation2_test.dart
index e953c59..4c3c5ad 100644
--- a/tests/compiler/dart2js/deferred/load_graph_segmentation2_test.dart
+++ b/tests/compiler/dart2js/deferred/load_graph_segmentation2_test.dart
@@ -9,7 +9,7 @@
 import 'package:async_helper/async_helper.dart';
 import 'package:compiler/src/compiler.dart';
 import 'package:expect/expect.dart';
-import '../memory_compiler.dart';
+import '../helpers/memory_compiler.dart';
 
 void main() {
   asyncTest(() async {
diff --git a/tests/compiler/dart2js/deferred/load_graph_segmentation_test.dart b/tests/compiler/dart2js/deferred/load_graph_segmentation_test.dart
index 8c34df7..d46b928 100644
--- a/tests/compiler/dart2js/deferred/load_graph_segmentation_test.dart
+++ b/tests/compiler/dart2js/deferred/load_graph_segmentation_test.dart
@@ -10,7 +10,7 @@
 import 'package:compiler/src/compiler.dart';
 import 'package:compiler/src/deferred_load.dart';
 import 'package:expect/expect.dart';
-import '../memory_compiler.dart';
+import '../helpers/memory_compiler.dart';
 
 void main() {
   asyncTest(() async {
diff --git a/tests/compiler/dart2js/deferred/load_mapping_test.dart b/tests/compiler/dart2js/deferred/load_mapping_test.dart
index 6efef69..51ae1a8 100644
--- a/tests/compiler/dart2js/deferred/load_mapping_test.dart
+++ b/tests/compiler/dart2js/deferred/load_mapping_test.dart
@@ -5,8 +5,8 @@
 import 'package:expect/expect.dart';
 import 'package:async_helper/async_helper.dart';
 import 'package:compiler/compiler_new.dart';
-import '../memory_source_file_helper.dart';
-import '../memory_compiler.dart';
+import '../helpers/memory_source_file_helper.dart';
+import '../helpers/memory_compiler.dart';
 
 void main() {
   asyncTest(() async {
diff --git a/tests/compiler/dart2js/deferred/not_in_main_test.dart b/tests/compiler/dart2js/deferred/not_in_main_test.dart
index 93c9c27..d701a11 100644
--- a/tests/compiler/dart2js/deferred/not_in_main_test.dart
+++ b/tests/compiler/dart2js/deferred/not_in_main_test.dart
@@ -9,45 +9,42 @@
 import 'package:async_helper/async_helper.dart';
 import 'package:compiler/src/compiler.dart';
 import 'package:expect/expect.dart';
-import '../memory_compiler.dart';
+import '../helpers/memory_compiler.dart';
 
 void main() {
-  deferredTest1();
-  deferredTest2();
-}
-
-void deferredTest1() {
   asyncTest(() async {
-    CompilationResult result = await runCompiler(memorySourceFiles: TEST1);
-    Compiler compiler = result.compiler;
-    var outputUnitForMember =
-        compiler.backend.outputUnitData.outputUnitForMember;
-    var mainOutputUnit = compiler.backend.outputUnitData.mainOutputUnit;
-    var env = compiler.backendClosedWorldForTesting.elementEnvironment;
-    lookupLibrary(name) => env.lookupLibrary(Uri.parse(name));
-    dynamic lib1 = lookupLibrary("memory:lib1.dart");
-    dynamic lib2 = lookupLibrary("memory:lib2.dart");
-    env.lookupLibraryMember(lib1, "foo1");
-    var foo2 = env.lookupLibraryMember(lib2, "foo2");
-
-    Expect.notEquals(mainOutputUnit, outputUnitForMember(foo2));
+    await deferredTest1();
+    await deferredTest2();
   });
 }
 
-void deferredTest2() {
-  asyncTest(() async {
-    CompilationResult result = await runCompiler(memorySourceFiles: TEST2);
-    Compiler compiler = result.compiler;
-    var outputUnitForClass = compiler.backend.outputUnitData.outputUnitForClass;
+deferredTest1() async {
+  CompilationResult result = await runCompiler(memorySourceFiles: TEST1);
+  Compiler compiler = result.compiler;
+  var outputUnitForMember = compiler.backend.outputUnitData.outputUnitForMember;
+  var mainOutputUnit = compiler.backend.outputUnitData.mainOutputUnit;
+  var env = compiler.backendClosedWorldForTesting.elementEnvironment;
+  lookupLibrary(name) => env.lookupLibrary(Uri.parse(name));
+  dynamic lib1 = lookupLibrary("memory:lib1.dart");
+  dynamic lib2 = lookupLibrary("memory:lib2.dart");
+  env.lookupLibraryMember(lib1, "foo1");
+  var foo2 = env.lookupLibraryMember(lib2, "foo2");
 
-    var mainOutputUnit = compiler.backend.outputUnitData.mainOutputUnit;
-    var env = compiler.backendClosedWorldForTesting.elementEnvironment;
-    lookupLibrary(name) => env.lookupLibrary(Uri.parse(name));
-    dynamic shared = lookupLibrary("memory:shared.dart");
-    var a = env.lookupClass(shared, "A");
+  Expect.notEquals(mainOutputUnit, outputUnitForMember(foo2));
+}
 
-    Expect.equals(mainOutputUnit, outputUnitForClass(a));
-  });
+deferredTest2() async {
+  CompilationResult result = await runCompiler(memorySourceFiles: TEST2);
+  Compiler compiler = result.compiler;
+  var outputUnitForClass = compiler.backend.outputUnitData.outputUnitForClass;
+
+  var mainOutputUnit = compiler.backend.outputUnitData.mainOutputUnit;
+  var env = compiler.backendClosedWorldForTesting.elementEnvironment;
+  lookupLibrary(name) => env.lookupLibrary(Uri.parse(name));
+  dynamic shared = lookupLibrary("memory:shared.dart");
+  var a = env.lookupClass(shared, "A");
+
+  Expect.equals(mainOutputUnit, outputUnitForClass(a));
 }
 
 // lib1 imports lib2 deferred. But mainlib never uses DeferredLibrary.
diff --git a/tests/compiler/dart2js/deferred/unneeded_part_js_test.dart b/tests/compiler/dart2js/deferred/unneeded_part_js_test.dart
index 6741047..7f5ccaa 100644
--- a/tests/compiler/dart2js/deferred/unneeded_part_js_test.dart
+++ b/tests/compiler/dart2js/deferred/unneeded_part_js_test.dart
@@ -6,7 +6,7 @@
 
 import 'package:async_helper/async_helper.dart';
 import 'package:expect/expect.dart';
-import '../memory_compiler.dart';
+import '../helpers/memory_compiler.dart';
 
 main() {
   runTest() async {
diff --git a/tests/compiler/dart2js/deferred_loading/deferred_loading_test.dart b/tests/compiler/dart2js/deferred_loading/deferred_loading_test.dart
index 5fee0a1..a47110f 100644
--- a/tests/compiler/dart2js/deferred_loading/deferred_loading_test.dart
+++ b/tests/compiler/dart2js/deferred_loading/deferred_loading_test.dart
@@ -9,8 +9,10 @@
 import 'package:compiler/src/compiler.dart';
 import 'package:compiler/src/deferred_load.dart';
 import 'package:compiler/src/elements/entities.dart';
+import 'package:compiler/src/ir/util.dart';
+import 'package:compiler/src/js_model/element_map.dart';
+import 'package:compiler/src/js_model/js_strategy.dart';
 import 'package:compiler/src/kernel/element_map.dart';
-import 'package:compiler/src/kernel/kernel_backend_strategy.dart';
 import 'package:expect/expect.dart';
 import '../equivalence/id_equivalence.dart';
 import '../equivalence/id_equivalence_helper.dart';
@@ -88,8 +90,8 @@
   void computeMemberData(
       Compiler compiler, MemberEntity member, Map<Id, ActualData> actualMap,
       {bool verbose: false}) {
-    KernelBackendStrategy backendStrategy = compiler.backendStrategy;
-    KernelToElementMapForBuilding elementMap = backendStrategy.elementMap;
+    JsBackendStrategy backendStrategy = compiler.backendStrategy;
+    JsToElementMap elementMap = backendStrategy.elementMap;
     MemberDefinition definition = elementMap.getMemberDefinition(member);
     new OutputUnitIrComputer(compiler.reporter, actualMap, elementMap, member,
             compiler.backend.outputUnitData, backendStrategy.closureDataLookup)
@@ -106,8 +108,8 @@
     OutputUnitData data = compiler.backend.outputUnitData;
     String value = outputUnitString(data.outputUnitForClass(cls));
 
-    KernelBackendStrategy backendStrategy = compiler.backendStrategy;
-    KernelToElementMapForBuilding elementMap = backendStrategy.elementMap;
+    JsBackendStrategy backendStrategy = compiler.backendStrategy;
+    JsToElementMap elementMap = backendStrategy.elementMap;
     ClassDefinition definition = elementMap.getClassDefinition(cls);
 
     _registerValue(
@@ -121,7 +123,7 @@
 }
 
 class OutputUnitIrComputer extends IrDataExtractor {
-  final KernelToElementMapForBuilding _elementMap;
+  final JsToElementMap _elementMap;
   final OutputUnitData _data;
   final ClosureDataLookup _closureDataLookup;
 
diff --git a/tests/compiler/dart2js/all_native_test.dart b/tests/compiler/dart2js/end_to_end/all_native_test.dart
similarity index 96%
rename from tests/compiler/dart2js/all_native_test.dart
rename to tests/compiler/dart2js/end_to_end/all_native_test.dart
index ae40236..f85b144 100644
--- a/tests/compiler/dart2js/all_native_test.dart
+++ b/tests/compiler/dart2js/end_to_end/all_native_test.dart
@@ -5,7 +5,7 @@
 import 'package:async_helper/async_helper.dart';
 import 'package:compiler/src/commandline_options.dart';
 import 'package:expect/expect.dart';
-import 'memory_compiler.dart';
+import '../helpers/memory_compiler.dart';
 
 main() {
   asyncTest(() async {
diff --git a/tests/compiler/dart2js/dill_loader_test.dart b/tests/compiler/dart2js/end_to_end/dill_loader_test.dart
similarity index 98%
rename from tests/compiler/dart2js/dill_loader_test.dart
rename to tests/compiler/dart2js/end_to_end/dill_loader_test.dart
index 05b9a43..dd9c4c1 100644
--- a/tests/compiler/dart2js/dill_loader_test.dart
+++ b/tests/compiler/dart2js/end_to_end/dill_loader_test.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-import 'memory_compiler.dart';
+import '../helpers/memory_compiler.dart';
 import 'package:async_helper/async_helper.dart';
 import 'package:compiler/src/apiimpl.dart' show CompilerImpl;
 import 'package:compiler/src/common_elements.dart';
diff --git a/tests/compiler/dart2js/dump_info_test.dart b/tests/compiler/dart2js/end_to_end/dump_info2_test.dart
similarity index 98%
rename from tests/compiler/dart2js/dump_info_test.dart
rename to tests/compiler/dart2js/end_to_end/dump_info2_test.dart
index 4d57673..4f99c8e 100644
--- a/tests/compiler/dart2js/dump_info_test.dart
+++ b/tests/compiler/dart2js/end_to_end/dump_info2_test.dart
@@ -1,13 +1,14 @@
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
+
 // Test that parameters keep their names in the output.
 
 import 'dart:convert';
 import 'package:async_helper/async_helper.dart';
 import 'package:compiler/src/commandline_options.dart';
 import 'package:expect/expect.dart';
-import 'memory_compiler.dart';
+import '../helpers/memory_compiler.dart';
 
 const String TEST_BASIC = r"""
 library main;
diff --git a/tests/compiler/dart2js/end_to_end/exit_code_test.dart b/tests/compiler/dart2js/end_to_end/exit_code_test.dart
index 49f7676..51df9a9 100644
--- a/tests/compiler/dart2js/end_to_end/exit_code_test.dart
+++ b/tests/compiler/dart2js/end_to_end/exit_code_test.dart
@@ -60,9 +60,9 @@
     return super.run(uri);
   }
 
-  LoadedLibraries processLoadedLibraries(LoadedLibraries loadedLibraries) {
+  void processLoadedLibraries(LoadedLibraries loadedLibraries) {
     test('Compiler.processLoadedLibraries');
-    return super.processLoadedLibraries(loadedLibraries);
+    super.processLoadedLibraries(loadedLibraries);
   }
 
   test(String marker) {
diff --git a/tests/compiler/dart2js/generate_code_with_compile_time_errors_test.dart b/tests/compiler/dart2js/end_to_end/generate_code_with_compile_time_errors_test.dart
similarity index 96%
rename from tests/compiler/dart2js/generate_code_with_compile_time_errors_test.dart
rename to tests/compiler/dart2js/end_to_end/generate_code_with_compile_time_errors_test.dart
index 321b440..6ae5ab8 100644
--- a/tests/compiler/dart2js/generate_code_with_compile_time_errors_test.dart
+++ b/tests/compiler/dart2js/end_to_end/generate_code_with_compile_time_errors_test.dart
@@ -11,8 +11,8 @@
 import 'package:async_helper/async_helper.dart';
 import 'package:compiler/src/compiler.dart';
 import 'package:compiler/src/js_backend/js_backend.dart';
-import 'memory_compiler.dart';
-import 'output_collector.dart';
+import '../helpers/memory_compiler.dart';
+import '../helpers/output_collector.dart';
 
 const MEMORY_SOURCE_FILES = const {
   'main.dart': ''' 
diff --git a/tests/compiler/dart2js/end_to_end/library_env_test.dart b/tests/compiler/dart2js/end_to_end/library_env_test.dart
index fc9b41e..f1084b5 100644
--- a/tests/compiler/dart2js/end_to_end/library_env_test.dart
+++ b/tests/compiler/dart2js/end_to_end/library_env_test.dart
@@ -8,7 +8,7 @@
 import 'dart:async';
 import 'dart:io';
 
-import '../memory_source_file_helper.dart';
+import '../helpers/memory_source_file_helper.dart';
 
 import "package:async_helper/async_helper.dart";
 
diff --git a/tests/compiler/dart2js/output_type_test.dart b/tests/compiler/dart2js/end_to_end/output_type_test.dart
similarity index 100%
rename from tests/compiler/dart2js/output_type_test.dart
rename to tests/compiler/dart2js/end_to_end/output_type_test.dart
diff --git a/tests/compiler/dart2js/platform_config_parser_test.dart b/tests/compiler/dart2js/end_to_end/platform_config_parser_test.dart
similarity index 100%
rename from tests/compiler/dart2js/platform_config_parser_test.dart
rename to tests/compiler/dart2js/end_to_end/platform_config_parser_test.dart
diff --git a/tests/compiler/dart2js/show_package_warnings_test.dart b/tests/compiler/dart2js/end_to_end/show_package_warnings_test.dart
similarity index 98%
rename from tests/compiler/dart2js/show_package_warnings_test.dart
rename to tests/compiler/dart2js/end_to_end/show_package_warnings_test.dart
index 284d6ae..3811a01 100644
--- a/tests/compiler/dart2js/show_package_warnings_test.dart
+++ b/tests/compiler/dart2js/end_to_end/show_package_warnings_test.dart
@@ -8,7 +8,7 @@
 import 'package:async_helper/async_helper.dart';
 import 'package:expect/expect.dart';
 import 'package:compiler/src/commandline_options.dart';
-import 'memory_compiler.dart';
+import '../helpers/memory_compiler.dart';
 
 /// Error code that creates 1 warning, 1 hint, and 1 info.
 const ERROR_CODE = """
diff --git a/tests/compiler/dart2js/uri_retention_test.dart b/tests/compiler/dart2js/end_to_end/uri_retention_test.dart
similarity index 95%
rename from tests/compiler/dart2js/uri_retention_test.dart
rename to tests/compiler/dart2js/end_to_end/uri_retention_test.dart
index 1654612..1fb8a72 100644
--- a/tests/compiler/dart2js/uri_retention_test.dart
+++ b/tests/compiler/dart2js/end_to_end/uri_retention_test.dart
@@ -10,7 +10,7 @@
 import 'package:compiler/compiler_new.dart';
 import 'package:compiler/src/commandline_options.dart';
 import 'package:expect/expect.dart';
-import 'memory_compiler.dart' show runCompiler, OutputCollector;
+import '../helpers/memory_compiler.dart' show runCompiler, OutputCollector;
 
 Future<String> compileSources(sources, {bool minify}) async {
   var options = <String>[];
diff --git a/tests/compiler/dart2js/user_crash_test.dart b/tests/compiler/dart2js/end_to_end/user_crash_test.dart
similarity index 87%
rename from tests/compiler/dart2js/user_crash_test.dart
rename to tests/compiler/dart2js/end_to_end/user_crash_test.dart
index e26e508..27ecab2 100644
--- a/tests/compiler/dart2js/user_crash_test.dart
+++ b/tests/compiler/dart2js/end_to_end/user_crash_test.dart
@@ -5,11 +5,15 @@
 import 'dart:async';
 import 'package:async_helper/async_helper.dart';
 import 'package:expect/expect.dart';
+import 'package:front_end/src/fasta/messages.dart'
+    show templateCantReadFile, messageMissingMain;
 import 'package:compiler/compiler_new.dart';
-import 'memory_compiler.dart';
+import '../helpers/memory_compiler.dart';
 
 final EXCEPTION = 'Crash-marker';
 
+final Uri entryPoint = Uri.parse('memory:main.dart');
+
 main() {
   runTests() async {
     test('Empty program', await run());
@@ -39,9 +43,11 @@
             packagesDiscoveryProvider: (_) => new Future.error(EXCEPTION)),
         expectedExceptions: [EXCEPTION]);
 
+    var cantReadFile =
+        templateCantReadFile.withArguments(entryPoint, EXCEPTION);
     List<String> expectedLines = [
-      'Error: Input file not found: memory:main.dart.',
-      'memory:main.dart:\nError: Crash-marker',
+      "Error: ${cantReadFile.message}",
+      "${entryPoint}:\nError: ${messageMissingMain.message}",
     ];
     test('Throw in input provider',
         await run(memorySourceFiles: new CrashingMap()),
@@ -69,7 +75,7 @@
       "Unexpected number of exceptions.");
   for (int i = 0; i < expectedLines.length; i++) {
     if (expectedLines[i] != null) {
-      Expect.equals(expectedLines[i], result.lines[i]);
+      Expect.stringEquals(expectedLines[i], result.lines[i]);
     }
   }
 }
@@ -82,7 +88,7 @@
   await runZoned(() async {
     try {
       await runCompiler(
-          entryPoint: Uri.parse('memory:main.dart'),
+          entryPoint: entryPoint,
           memorySourceFiles: memorySourceFiles,
           diagnosticHandler: diagnostics,
           packagesDiscoveryProvider: packagesDiscoveryProvider);
diff --git a/tests/compiler/dart2js/equivalence/id_equivalence.dart b/tests/compiler/dart2js/equivalence/id_equivalence.dart
index 6564b65..73f4299 100644
--- a/tests/compiler/dart2js/equivalence/id_equivalence.dart
+++ b/tests/compiler/dart2js/equivalence/id_equivalence.dart
@@ -3,7 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:compiler/src/common.dart';
-import 'package:compiler/src/kernel/element_map.dart';
+import 'package:compiler/src/ir/util.dart';
 import 'package:compiler/src/js_model/locals.dart';
 import 'package:expect/expect.dart';
 import 'package:kernel/ast.dart' as ir;
diff --git a/tests/compiler/dart2js/equivalence/id_equivalence_helper.dart b/tests/compiler/dart2js/equivalence/id_equivalence_helper.dart
index 1bda357..5762f41 100644
--- a/tests/compiler/dart2js/equivalence/id_equivalence_helper.dart
+++ b/tests/compiler/dart2js/equivalence/id_equivalence_helper.dart
@@ -14,7 +14,7 @@
 import 'package:expect/expect.dart';
 import 'package:sourcemap_testing/src/annotated_code_helper.dart';
 
-import '../memory_compiler.dart';
+import '../helpers/memory_compiler.dart';
 import '../equivalence/id_equivalence.dart';
 
 /// `true` if ANSI colors are supported by stdout.
@@ -84,6 +84,9 @@
   /// Called before testing to setup flags needed for data collection.
   void setup() {}
 
+  /// Called before testing to setup flags needed for data collection.
+  void onCompilation(Compiler compiler) {}
+
   /// Function that computes a data mapping for [member].
   ///
   /// Fills [actualMap] with the data and [sourceSpanMap] with the source spans
@@ -149,6 +152,7 @@
     Expect.isTrue(result.isSuccess, "Unexpected compilation error.");
   }
   Compiler compiler = result.compiler;
+  dataComputer.onCompilation(compiler);
   dynamic closedWorld = testFrontend
       ? compiler.resolutionWorldBuilder.closedWorldForTesting
       : compiler.backendClosedWorldForTesting;
diff --git a/tests/compiler/dart2js/equivalence/show_helper.dart b/tests/compiler/dart2js/equivalence/show_helper.dart
index 3d5ac07..9dd2342 100644
--- a/tests/compiler/dart2js/equivalence/show_helper.dart
+++ b/tests/compiler/dart2js/equivalence/show_helper.dart
@@ -66,13 +66,17 @@
   } else {
     SourceFileProvider provider = data.compiler.provider;
     for (Uri uri in data.actualMaps.keys) {
-      if (show != null && !show.any((f) => '$uri'.endsWith(f))) {
+      Uri fileUri = uri;
+      if (fileUri.scheme == 'org-dartlang-sdk') {
+        fileUri = Uri.base.resolve(fileUri.path.substring(1));
+      }
+      if (show != null && !show.any((f) => '$fileUri'.endsWith(f))) {
         continue;
       }
-      SourceFile sourceFile = await provider.autoReadFromFile(uri);
+      SourceFile sourceFile = await provider.autoReadFromFile(fileUri);
       String sourceCode = sourceFile?.slowText();
       if (sourceCode == null) {
-        sourceCode = new File.fromUri(uri).readAsStringSync();
+        sourceCode = new File.fromUri(fileUri).readAsStringSync();
       }
       if (sourceCode == null) {
         print('--source code missing for $uri--------------------------------');
diff --git a/tests/compiler/dart2js/generic_methods/function_type_variable_test.dart b/tests/compiler/dart2js/generic_methods/function_type_variable_test.dart
index eec0b3e..8d2feb0 100644
--- a/tests/compiler/dart2js/generic_methods/function_type_variable_test.dart
+++ b/tests/compiler/dart2js/generic_methods/function_type_variable_test.dart
@@ -6,7 +6,7 @@
 import 'package:compiler/src/elements/entities.dart';
 import 'package:compiler/src/elements/types.dart';
 import 'package:expect/expect.dart';
-import '../type_test_helper.dart';
+import '../helpers/type_test_helper.dart';
 
 const List<FunctionTypeData> existentialTypeData = const <FunctionTypeData>[
   const FunctionTypeData('void', 'F1', '<T>(T t)'),
diff --git a/tests/compiler/dart2js/generic_methods/generic_method_type_test.dart b/tests/compiler/dart2js/generic_methods/generic_method_type_test.dart
index 1bded63..410f5fc 100644
--- a/tests/compiler/dart2js/generic_methods/generic_method_type_test.dart
+++ b/tests/compiler/dart2js/generic_methods/generic_method_type_test.dart
@@ -7,7 +7,7 @@
 import 'package:compiler/src/elements/types.dart';
 import 'package:compiler/src/universe/call_structure.dart';
 import 'package:expect/expect.dart';
-import '../type_test_helper.dart';
+import '../helpers/type_test_helper.dart';
 
 List<FunctionTypeData> signatures = const <FunctionTypeData>[
   const FunctionTypeData("void", "0", "()"),
diff --git a/tests/compiler/dart2js/generic_methods/instantiation_stub_test.dart b/tests/compiler/dart2js/generic_methods/instantiation_stub_test.dart
index 3a423a4..802c06d 100644
--- a/tests/compiler/dart2js/generic_methods/instantiation_stub_test.dart
+++ b/tests/compiler/dart2js/generic_methods/instantiation_stub_test.dart
@@ -10,7 +10,7 @@
 import 'package:compiler/src/world.dart';
 import 'package:expect/expect.dart';
 import '../helpers/program_lookup.dart';
-import '../memory_compiler.dart';
+import '../helpers/memory_compiler.dart';
 
 const String code = '''
 import 'package:meta/dart2js.dart';
diff --git a/tests/compiler/dart2js/generic_methods/world_test.dart b/tests/compiler/dart2js/generic_methods/world_test.dart
index 97899ee..8578a79 100644
--- a/tests/compiler/dart2js/generic_methods/world_test.dart
+++ b/tests/compiler/dart2js/generic_methods/world_test.dart
@@ -8,7 +8,7 @@
 import 'package:compiler/src/universe/world_builder.dart';
 import 'package:expect/expect.dart';
 
-import '../memory_compiler.dart';
+import '../helpers/memory_compiler.dart';
 
 const String code = r'''
 import 'package:meta/dart2js.dart';
diff --git a/tests/compiler/dart2js/compiler_helper.dart b/tests/compiler/dart2js/helpers/compiler_helper.dart
similarity index 99%
rename from tests/compiler/dart2js/compiler_helper.dart
rename to tests/compiler/dart2js/helpers/compiler_helper.dart
index e85ade1..345fb21 100644
--- a/tests/compiler/dart2js/compiler_helper.dart
+++ b/tests/compiler/dart2js/helpers/compiler_helper.dart
@@ -5,32 +5,22 @@
 library compiler_helper;
 
 import 'dart:async';
-import "package:expect/expect.dart";
-
 import 'package:compiler/compiler_new.dart';
-
 import 'package:compiler/src/common_elements.dart';
-
 import 'package:compiler/src/elements/entities.dart';
-
 import 'package:compiler/src/js_backend/js_backend.dart' as js;
-
 import 'package:compiler/src/commandline_options.dart';
+import 'package:compiler/src/world.dart';
+import 'package:compiler/src/compiler.dart' show Compiler;
+import 'package:expect/expect.dart';
+import 'package:front_end/src/fasta/util/link.dart' show Link;
+import 'memory_compiler.dart';
+import 'output_collector.dart';
 
 export 'package:compiler/src/diagnostics/messages.dart';
 export 'package:compiler/src/diagnostics/source_span.dart';
 export 'package:compiler/src/diagnostics/spannable.dart';
 export 'package:compiler/src/util/util.dart';
-
-import 'package:compiler/src/world.dart';
-
-import 'package:compiler/src/compiler.dart' show Compiler;
-
-import 'package:front_end/src/fasta/util/link.dart' show Link;
-
-import 'memory_compiler.dart';
-
-import 'output_collector.dart';
 export 'output_collector.dart';
 
 /// Compile [code] and returns either the code for [methodName] or, if
diff --git a/tests/compiler/dart2js/helpers/d8_helper.dart b/tests/compiler/dart2js/helpers/d8_helper.dart
index 816a1bf..612f617 100644
--- a/tests/compiler/dart2js/helpers/d8_helper.dart
+++ b/tests/compiler/dart2js/helpers/d8_helper.dart
@@ -10,11 +10,12 @@
 import 'dart:io';
 
 import 'package:compiler/compiler_new.dart';
+import 'package:compiler/src/common.dart';
 import 'package:compiler/src/dart2js.dart' as dart2js;
 import 'package:compiler/src/filenames.dart';
 import 'package:expect/expect.dart';
 import 'package:sourcemap_testing/src/stacktrace_helper.dart';
-import '../memory_compiler.dart';
+import '../helpers/memory_compiler.dart';
 
 Future createTemp(Uri entryPoint, Map<String, String> memorySourceFiles,
     {bool printSteps: false}) async {
@@ -38,6 +39,7 @@
     String expectedOutput,
     bool printJs: false,
     bool printSteps: false}) async {
+  retainDataForTesting = true;
   entryPoint ??= Uri.parse('memory:main.dart');
   Uri mainFile =
       await createTemp(entryPoint, memorySourceFiles, printSteps: printSteps);
diff --git a/tests/compiler/dart2js/diagnostic_helper.dart b/tests/compiler/dart2js/helpers/diagnostic_helper.dart
similarity index 100%
rename from tests/compiler/dart2js/diagnostic_helper.dart
rename to tests/compiler/dart2js/helpers/diagnostic_helper.dart
diff --git a/tests/compiler/dart2js/link_helper.dart b/tests/compiler/dart2js/helpers/link_helper.dart
similarity index 100%
rename from tests/compiler/dart2js/link_helper.dart
rename to tests/compiler/dart2js/helpers/link_helper.dart
diff --git a/tests/compiler/dart2js/memory_compiler.dart b/tests/compiler/dart2js/helpers/memory_compiler.dart
similarity index 98%
rename from tests/compiler/dart2js/memory_compiler.dart
rename to tests/compiler/dart2js/helpers/memory_compiler.dart
index b682c5f..c8f1708 100644
--- a/tests/compiler/dart2js/memory_compiler.dart
+++ b/tests/compiler/dart2js/helpers/memory_compiler.dart
@@ -14,6 +14,7 @@
         CompilerOutput,
         Diagnostic,
         PackagesDiscoveryProvider;
+import 'package:compiler/src/common.dart';
 import 'package:compiler/src/diagnostics/messages.dart' show Message;
 import 'package:compiler/src/null_compiler_output.dart' show NullCompilerOutput;
 import 'package:compiler/src/options.dart' show CompilerOptions;
@@ -113,6 +114,7 @@
     Uri packageRoot,
     Uri packageConfig,
     PackagesDiscoveryProvider packagesDiscoveryProvider}) {
+  retainDataForTesting = true;
   Uri libraryRoot = Uri.base.resolve('sdk/');
   Uri platformBinaries = computePlatformBinariesLocation();
 
diff --git a/tests/compiler/dart2js/memory_source_file_helper.dart b/tests/compiler/dart2js/helpers/memory_source_file_helper.dart
similarity index 100%
rename from tests/compiler/dart2js/memory_source_file_helper.dart
rename to tests/compiler/dart2js/helpers/memory_source_file_helper.dart
diff --git a/tests/compiler/dart2js/output_collector.dart b/tests/compiler/dart2js/helpers/output_collector.dart
similarity index 100%
rename from tests/compiler/dart2js/output_collector.dart
rename to tests/compiler/dart2js/helpers/output_collector.dart
diff --git a/tests/compiler/dart2js/helpers/program_lookup.dart b/tests/compiler/dart2js/helpers/program_lookup.dart
index 7ac0fed..ba7d268 100644
--- a/tests/compiler/dart2js/helpers/program_lookup.dart
+++ b/tests/compiler/dart2js/helpers/program_lookup.dart
@@ -10,6 +10,13 @@
 import 'package:compiler/src/js_emitter/model.dart';
 import 'package:compiler/src/js/js.dart' as js;
 
+ClassEntity lookupClass(ElementEnvironment elementEnvironment, String name) {
+  ClassEntity cls =
+      elementEnvironment.lookupClass(elementEnvironment.mainLibrary, name);
+  Expect.isNotNull(cls, "No class '$name' found in the main library.");
+  return cls;
+}
+
 MemberEntity lookupMember(ElementEnvironment elementEnvironment, String name) {
   MemberEntity member;
   int dotIndex = name.indexOf('.');
diff --git a/tests/compiler/dart2js/stats_test.dart b/tests/compiler/dart2js/helpers/stats_test.dart
similarity index 100%
rename from tests/compiler/dart2js/stats_test.dart
rename to tests/compiler/dart2js/helpers/stats_test.dart
diff --git a/tests/compiler/dart2js/type_test_helper.dart b/tests/compiler/dart2js/helpers/type_test_helper.dart
similarity index 95%
rename from tests/compiler/dart2js/type_test_helper.dart
rename to tests/compiler/dart2js/helpers/type_test_helper.dart
index b5f162a..c4304da 100644
--- a/tests/compiler/dart2js/type_test_helper.dart
+++ b/tests/compiler/dart2js/helpers/type_test_helper.dart
@@ -8,10 +8,10 @@
 import 'package:expect/expect.dart';
 import 'package:compiler/src/common_elements.dart';
 import 'package:compiler/src/commandline_options.dart';
+import 'package:compiler/src/compiler.dart';
 import 'package:compiler/src/elements/types.dart';
 import 'package:compiler/src/compiler.dart' show Compiler;
 import 'package:compiler/src/elements/entities.dart';
-import 'package:compiler/src/frontend_strategy.dart';
 import 'package:compiler/src/kernel/kernel_strategy.dart';
 import 'package:compiler/src/world.dart' show JClosedWorld, KClosedWorld;
 import 'memory_compiler.dart' as memory;
@@ -30,21 +30,17 @@
       bool testBackendWorld: false,
       List<String> options: const <String>[],
       Map<String, String> fieldTypeMap: const <String, String>{}}) async {
-    Uri uri;
-    Compiler compiler;
-    memory.DiagnosticCollector collector;
-    collector = new memory.DiagnosticCollector();
-    uri = Uri.parse('memory:main.dart');
+    memory.DiagnosticCollector collector = new memory.DiagnosticCollector();
+    Uri uri = Uri.parse('memory:main.dart');
     memory.CompilationResult result = await memory.runCompiler(
         entryPoint: uri,
         memorySourceFiles: {'main.dart': source},
         options: [Flags.disableTypeInference]..addAll(options),
         diagnosticHandler: collector,
         beforeRun: (compiler) {
-          ImpactCacheDeleter.retainCachesForTesting = true;
           compiler.stopAfterTypeInference = true;
         });
-    compiler = result.compiler;
+    Compiler compiler = result.compiler;
     if (expectNoErrors || expectNoWarningsOrErrors) {
       var errors = collector.errors;
       Expect.isTrue(errors.isEmpty, 'Unexpected errors: ${errors}');
diff --git a/tests/compiler/dart2js/impact/data/classes.dart b/tests/compiler/dart2js/impact/data/classes.dart
index 20267d2..a31b32f 100644
--- a/tests/compiler/dart2js/impact/data/classes.dart
+++ b/tests/compiler/dart2js/impact/data/classes.dart
@@ -240,7 +240,7 @@
 }
 
 /*strong.element: testInstanceGenericMethod:
- dynamic=[genericMethod<bool>(1)],
+ dynamic=[GenericClass.genericMethod<bool>(1)],
  static=[
   GenericClass.generative(0),
   assertIsSubtype,
diff --git a/tests/compiler/dart2js/impact/data/expressions.dart b/tests/compiler/dart2js/impact/data/expressions.dart
index ed4ea6d..b28d3e5 100644
--- a/tests/compiler/dart2js/impact/data/expressions.dart
+++ b/tests/compiler/dart2js/impact/data/expressions.dart
@@ -70,7 +70,7 @@
 testNot() => !false;
 
 /*element: testUnaryMinus:
- dynamic=[unary-],
+ dynamic=[int.unary-],
  type=[inst:JSDouble,inst:JSInt,inst:JSNumber,inst:JSPositiveInt,inst:JSUInt31,inst:JSUInt32]
 */
 testUnaryMinus() => -1;
diff --git a/tests/compiler/dart2js/impact/data/jsinterop.dart b/tests/compiler/dart2js/impact/data/jsinterop.dart
index 1687434..b36d583 100644
--- a/tests/compiler/dart2js/impact/data/jsinterop.dart
+++ b/tests/compiler/dart2js/impact/data/jsinterop.dart
@@ -44,7 +44,7 @@
 }
 
 /*strong.element: testJsInteropClass:
- dynamic=[method(0)],
+ dynamic=[JavaScriptObject.method(0)],
  static=[JsInteropClass.(0)]
 */
 testJsInteropClass() => new JsInteropClass().method();
@@ -76,7 +76,7 @@
 }
 
 /*strong.element: testOptionalGenericFunctionTypeArgument:
- dynamic=[method(0)],
+ dynamic=[JavaScriptObject.method(0)],
  static=[GenericClass.(0)]
 */
 testOptionalGenericFunctionTypeArgument() => new GenericClass().method();
diff --git a/tests/compiler/dart2js/impact/data/literals.dart b/tests/compiler/dart2js/impact/data/literals.dart
index a23b41b..d08c904 100644
--- a/tests/compiler/dart2js/impact/data/literals.dart
+++ b/tests/compiler/dart2js/impact/data/literals.dart
@@ -99,7 +99,7 @@
 testConstSymbol() => const Symbol('main');
 
 /*strong.element: complexSymbolField1:
- dynamic=[==,length],
+ dynamic=[String.length,int.==],
  type=[inst:JSBool,inst:JSDouble,inst:JSInt,inst:JSNumber,inst:JSPositiveInt,inst:JSString,inst:JSUInt31,inst:JSUInt32,param:bool]
 */
 const complexSymbolField1 = "true".length == 4;
@@ -107,7 +107,47 @@
 /*strong.element: complexSymbolField2:dynamic=[toString(0)],static=[S],type=[inst:JSBool,inst:JSNull,inst:JSString,param:String]*/
 const complexSymbolField2 = "true" "false" "${true}${null}";
 
-/*strong.element: complexSymbolField3:dynamic=[+,unary-],static=[GenericClass.generative(0),String.fromEnvironment(1),Symbol.,assertIsSubtype,bool.fromEnvironment(1,defaultValue),checkSubtype,getRuntimeTypeArgument,getRuntimeTypeArgumentIntercepted,getRuntimeTypeInfo,getTypeArgumentByIndex,identical(2),int.fromEnvironment(1,defaultValue),override,setRuntimeTypeInfo,testComplexConstSymbol,throwTypeError],type=[inst:ConstantMap<dynamic,dynamic>,inst:ConstantProtoMap<dynamic,dynamic>,inst:ConstantStringMap<dynamic,dynamic>,inst:GeneralConstantMap<dynamic,dynamic>,inst:JSArray<dynamic>,inst:JSBool,inst:JSDouble,inst:JSExtendableArray<dynamic>,inst:JSFixedArray<dynamic>,inst:JSInt,inst:JSMutableArray<dynamic>,inst:JSNumber,inst:JSPositiveInt,inst:JSString,inst:JSUInt31,inst:JSUInt32,inst:JSUnmodifiableArray<dynamic>,inst:List<int>,inst:Symbol,param:Map<Object,Object>]*/
+/*strong.element: complexSymbolField3:
+  dynamic=[int.+,int.unary-],
+  static=[
+   GenericClass.generative(0),
+   String.fromEnvironment(1),
+   Symbol.,
+   assertIsSubtype,
+   bool.fromEnvironment(1,defaultValue),
+   checkSubtype,
+   getRuntimeTypeArgument,
+   getRuntimeTypeArgumentIntercepted,
+   getRuntimeTypeInfo,
+   getTypeArgumentByIndex,
+   identical(2),
+   int.fromEnvironment(1,defaultValue),
+   override,
+   setRuntimeTypeInfo,
+   testComplexConstSymbol,
+   throwTypeError],
+  type=[
+   inst:ConstantMap<dynamic,dynamic>,
+   inst:ConstantProtoMap<dynamic,dynamic>,
+   inst:ConstantStringMap<dynamic,dynamic>,
+   inst:GeneralConstantMap<dynamic,dynamic>,
+   inst:JSArray<dynamic>,
+   inst:JSBool,
+   inst:JSDouble,
+   inst:JSExtendableArray<dynamic>,
+   inst:JSFixedArray<dynamic>,
+   inst:JSInt,
+   inst:JSMutableArray<dynamic>,
+   inst:JSNumber,
+   inst:JSPositiveInt,
+   inst:JSString,
+   inst:JSUInt31,
+   inst:JSUInt32,
+   inst:JSUnmodifiableArray<dynamic>,
+   inst:List<int>,
+   inst:Symbol,
+   param:Map<Object,Object>]
+*/
 const complexSymbolField3 = const {
   0: const bool.fromEnvironment('a', defaultValue: true),
   false: const int.fromEnvironment('b', defaultValue: 42),
diff --git a/tests/compiler/dart2js/impact/data/native.dart b/tests/compiler/dart2js/impact/data/native.dart
index d147208..47d2ce2 100644
--- a/tests/compiler/dart2js/impact/data/native.dart
+++ b/tests/compiler/dart2js/impact/data/native.dart
@@ -77,7 +77,7 @@
 }
 
 /*strong.element: testNativeField:
- dynamic=[field],
+ dynamic=[NativeClass.field],
  static=[defineProperty],
  type=[inst:JSBool,param:NativeClass]
 */
diff --git a/tests/compiler/dart2js/impact/data/runtime_type_strong.dart b/tests/compiler/dart2js/impact/data/runtime_type_strong.dart
index 621b451..3f0452b 100644
--- a/tests/compiler/dart2js/impact/data/runtime_type_strong.dart
+++ b/tests/compiler/dart2js/impact/data/runtime_type_strong.dart
@@ -5,7 +5,7 @@
 /*element: Class1a.:static=[Object.(0)]*/
 class Class1a<T> {
   /*element: Class1a.==:
-   dynamic=[==,runtimeType],
+   dynamic=[Class1a.runtimeType,Type.==,runtimeType],
    runtimeType=[equals:Class1a<Class1a.T>/dynamic]
   */
   bool operator ==(other) {
@@ -16,7 +16,7 @@
 /*element: Class1b.:static=[Class1a.(0)]*/
 class Class1b<T> extends Class1a<T> {
   /*element: Class1b.==:
-   dynamic=[==,runtimeType],
+   dynamic=[Class1b.runtimeType,Type.==,runtimeType],
    runtimeType=[equals:dynamic/Class1b<Class1b.T>]
   */
   bool operator ==(other) {
@@ -27,7 +27,7 @@
 /*element: Class1c.:static=[Object.(0)]*/
 class Class1c<T> implements Class1a<T> {
   /*element: Class1c.==:
-   dynamic=[==,runtimeType],
+   dynamic=[==,Class1c.runtimeType,Type.==,runtimeType],
    runtimeType=[equals:Class1c<Class1c.T>/dynamic],
    type=[inst:JSNull]
   */
@@ -39,7 +39,7 @@
 /*element: Class1d.:static=[Object.(0)]*/
 class Class1d<T> implements Class1a<T> {
   /*element: Class1d.==:
-   dynamic=[==,runtimeType],
+   dynamic=[==,Class1d.runtimeType,Type.==,runtimeType],
    runtimeType=[equals:dynamic/Class1d<Class1d.T>],
    type=[inst:JSNull]
   */
@@ -61,7 +61,7 @@
 class Class4 {}
 
 /*element: toString1:
- dynamic=[runtimeType,toString(0)],
+ dynamic=[Class2.runtimeType,toString(0)],
  runtimeType=[string:Class2<int>],
  static=[
   S,
@@ -84,7 +84,7 @@
 toString1(Class2<int> c) => '${c.runtimeType}';
 
 /*element: toString2:
- dynamic=[==,runtimeType,toString(0)],
+ dynamic=[==,Class2.runtimeType,toString(0)],
  runtimeType=[string:Class2<int>],
  static=[
   S,
@@ -108,7 +108,7 @@
 toString2(Class2<int> c) => '${c?.runtimeType}';
 
 /*element: toString3:
- dynamic=[runtimeType,toString(0)],
+ dynamic=[Class2.runtimeType,Type.toString(0)],
  runtimeType=[string:Class2<int>],
  static=[
   checkSubtype,
@@ -129,7 +129,7 @@
 toString3(Class2<int> c) => c.runtimeType.toString();
 
 /*element: toString4:
- dynamic=[==,runtimeType,toString(0)],
+ dynamic=[==,Class2.runtimeType,Type.toString(0)],
  runtimeType=[string:Class2<int>],
  static=[
   checkSubtype,
@@ -151,7 +151,7 @@
 toString4(Class2<int> c) => c.runtimeType?.toString();
 
 /*element: toString5:
- dynamic=[==,runtimeType,toString(0)],
+ dynamic=[==,Class2.runtimeType,Type.toString(0)],
  runtimeType=[string:Class2<int>],
  static=[
   checkSubtype,
@@ -173,7 +173,7 @@
 toString5(Class2<int> c) => c?.runtimeType?.toString();
 
 /*element: toString6:
- dynamic=[==,runtimeType,toString(0)],
+ dynamic=[==,Class2.runtimeType,Type.toString(0)],
  runtimeType=[string:Class2<int>],
  static=[
   checkSubtype,
@@ -195,7 +195,7 @@
 toString6(Class2<int> c) => c?.runtimeType.toString();
 
 /*element: unknown:
- dynamic=[runtimeType],
+ dynamic=[Class2.runtimeType],
  runtimeType=[unknown:Class2<int>],
  static=[
   checkSubtype,
@@ -216,7 +216,7 @@
 unknown(Class2<int> c) => c.runtimeType;
 
 /*element: equals1:
- dynamic=[==,runtimeType],
+ dynamic=[==,Class1a.runtimeType,Class1d.runtimeType,Type.==],
  runtimeType=[equals:Class1a<int>/Class1d<int>],
  static=[
   checkSubtype,
@@ -239,147 +239,147 @@
 equals1(Class1a<int> a, Class1d<int> b) => a?.runtimeType == b?.runtimeType;
 
 /*element: almostEquals1:
- dynamic=[==,runtimeType],
+ dynamic=[Class3.runtimeType,Type.==],
  runtimeType=[unknown:Class3],
  type=[inst:JSBool,inst:JSNull,param:Class3]
 */
 almostEquals1(Class3 a) => a.runtimeType == null;
 
 /*element: almostEquals2:
- dynamic=[==,runtimeType],
+ dynamic=[==,Class3.runtimeType,Type.==],
  runtimeType=[unknown:Class3],
  type=[inst:JSBool,inst:JSNull,param:Class3]
 */
 almostEquals2(Class3 a) => a?.runtimeType == null;
 
 /*element: almostEquals3:
- dynamic=[==,runtimeType],
+ dynamic=[Class3.runtimeType,Null.==],
  runtimeType=[unknown:Class3],
  type=[inst:JSBool,inst:JSNull,param:Class3]
 */
 almostEquals3(Class3 a) => null == a.runtimeType;
 
 /*element: almostEquals4:
- dynamic=[==,runtimeType],
+ dynamic=[==,Class3.runtimeType,Null.==],
  runtimeType=[unknown:Class3],
  type=[inst:JSBool,inst:JSNull,param:Class3]
 */
 almostEquals4(Class3 a) => null == a?.runtimeType;
 
 /*element: almostEquals5:
- dynamic=[==,field,runtimeType],
+ dynamic=[Class3.field,Class3.runtimeType,Type.==],
  runtimeType=[unknown:Class3],
  type=[inst:JSBool,param:Class3]
 */
 almostEquals5(Class3 a) => a.runtimeType == a.field;
 
 /*element: almostEquals6:
- dynamic=[==,field,runtimeType],
+ dynamic=[==,Class3.field,Class3.runtimeType,Type.==],
  runtimeType=[unknown:Class3],
  type=[inst:JSBool,inst:JSNull,param:Class3]
 */
 almostEquals6(Class3 a) => a?.runtimeType == a.field;
 
 /*element: almostEquals7:
- dynamic=[==,field,runtimeType],
+ dynamic=[==,Class3.field,Class3.runtimeType,Type.==],
  runtimeType=[unknown:Class3],
  type=[inst:JSBool,inst:JSNull,param:Class3]
 */
 almostEquals7(Class3 a) => a.runtimeType == a?.field;
 
 /*element: almostEquals8:
- dynamic=[==,field,runtimeType],
+ dynamic=[==,Class3.field,Class3.runtimeType,Type.==],
  runtimeType=[unknown:Class3],
  type=[inst:JSBool,inst:JSNull,param:Class3]
 */
 almostEquals8(Class3 a) => a?.runtimeType == a?.field;
 
 /*element: almostEquals9:
- dynamic=[==,field,runtimeType],
+ dynamic=[==,Class3.field,Class3.runtimeType],
  runtimeType=[unknown:Class3],
  type=[inst:JSBool,param:Class3]
 */
 almostEquals9(Class3 a) => a.field == a.runtimeType;
 
 /*element: almostEquals10:
- dynamic=[==,field,runtimeType],
+ dynamic=[==,Class3.field,Class3.runtimeType],
  runtimeType=[unknown:Class3],
  type=[inst:JSBool,inst:JSNull,param:Class3]
 */
 almostEquals10(Class3 a) => a?.field == a.runtimeType;
 
 /*element: almostEquals11:
- dynamic=[==,field,runtimeType],
+ dynamic=[==,Class3.field,Class3.runtimeType],
  runtimeType=[unknown:Class3],
  type=[inst:JSBool,inst:JSNull,param:Class3]
 */
 almostEquals11(Class3 a) => a.field == a?.runtimeType;
 
 /*element: almostEquals12:
- dynamic=[==,field,runtimeType],
+ dynamic=[==,Class3.field,Class3.runtimeType],
  runtimeType=[unknown:Class3],
  type=[inst:JSBool,inst:JSNull,param:Class3]
 */
 almostEquals12(Class3 a) => a?.field == a?.runtimeType;
 
 /*element: almostToString1:
- dynamic=[runtimeType,toString],
+ dynamic=[Class3.runtimeType,Type.toString],
  runtimeType=[unknown:Class3],
  type=[inst:JSBool,param:Class3]
 */
 almostToString1(Class3 a) => a.runtimeType.toString;
 
 /*element: almostToString2:
- dynamic=[==,runtimeType,toString],
+ dynamic=[==,Class3.runtimeType,Type.toString],
  runtimeType=[unknown:Class3],
  type=[inst:JSBool,inst:JSNull,param:Class3]
 */
 almostToString2(Class3 a) => a?.runtimeType?.toString;
 
 /*element: almostToString3:
- dynamic=[noSuchMethod(1),runtimeType],
+ dynamic=[Class3.runtimeType,Type.noSuchMethod(1)],
  runtimeType=[unknown:Class3],
  type=[inst:JSBool,inst:JSNull,param:Class3]
 */
 almostToString3(Class3 a) => a.runtimeType.noSuchMethod(null);
 
 /*element: almostToString4:
- dynamic=[==,noSuchMethod(1),runtimeType],
+ dynamic=[==,Class3.runtimeType,Type.noSuchMethod(1)],
  runtimeType=[unknown:Class3],
  type=[inst:JSBool,inst:JSNull,param:Class3]
 */
 almostToString4(Class3 a) => a?.runtimeType.noSuchMethod(null);
 
 /*element: notEquals1:
- dynamic=[==,runtimeType],
+ dynamic=[Class3.runtimeType,Class4.runtimeType,Type.==],
  runtimeType=[equals:Class3/Class4],
  type=[inst:JSBool,param:Class3,param:Class4]
 */
 notEquals1(Class3 a, Class4 b) => a.runtimeType != b.runtimeType;
 
 /*element: notEquals2:
- dynamic=[==,runtimeType],
+ dynamic=[==,Class3.runtimeType,Class4.runtimeType,Type.==],
  runtimeType=[equals:Class3/Class4],
  type=[inst:JSBool,inst:JSNull,param:Class3,param:Class4]
 */
 notEquals2(Class3 a, Class4 b) => a?.runtimeType != b.runtimeType;
 
 /*element: notEquals3:
- dynamic=[==,runtimeType],
+ dynamic=[==,Class3.runtimeType,Class4.runtimeType,Type.==],
  runtimeType=[equals:Class3/Class4],
  type=[inst:JSBool,inst:JSNull,param:Class3,param:Class4]
 */
 notEquals3(Class3 a, Class4 b) => a.runtimeType != b?.runtimeType;
 
 /*element: notEquals4:
- dynamic=[==,runtimeType],
+ dynamic=[==,Class3.runtimeType,Class4.runtimeType,Type.==],
  runtimeType=[equals:Class3/Class4],
  type=[inst:JSBool,inst:JSNull,param:Class3,param:Class4]
 */
 notEquals4(Class3 a, Class4 b) => a?.runtimeType != b?.runtimeType;
 
 /*element: main:
- dynamic=[==],
+ dynamic=[Class1a.==],
  static=[
   Class1a.(0),
   Class1b.(0),
diff --git a/tests/compiler/dart2js/impact/impact_test.dart b/tests/compiler/dart2js/impact/impact_test.dart
index 6f1a653..5bdc7ef 100644
--- a/tests/compiler/dart2js/impact/impact_test.dart
+++ b/tests/compiler/dart2js/impact/impact_test.dart
@@ -7,7 +7,7 @@
 import 'package:compiler/src/common/resolution.dart';
 import 'package:compiler/src/compiler.dart';
 import 'package:compiler/src/elements/entities.dart';
-import 'package:compiler/src/frontend_strategy.dart';
+import 'package:compiler/src/ir/util.dart';
 import 'package:compiler/src/kernel/element_map.dart';
 import 'package:compiler/src/kernel/kernel_strategy.dart';
 import 'package:compiler/src/universe/feature.dart';
@@ -36,11 +36,6 @@
   const ImpactDataComputer();
 
   @override
-  void setup() {
-    ImpactCacheDeleter.retainCachesForTesting = true;
-  }
-
-  @override
   void computeMemberData(
       Compiler compiler, MemberEntity member, Map<Id, ActualData> actualMap,
       {bool verbose: false}) {
diff --git a/tests/compiler/dart2js/inference/callers_test.dart b/tests/compiler/dart2js/inference/callers_test.dart
index edaaedb..e0a1a72 100644
--- a/tests/compiler/dart2js/inference/callers_test.dart
+++ b/tests/compiler/dart2js/inference/callers_test.dart
@@ -9,10 +9,10 @@
 import 'package:compiler/src/compiler.dart';
 import 'package:compiler/src/diagnostics/diagnostic_listener.dart';
 import 'package:compiler/src/elements/entities.dart';
-import 'package:compiler/src/inferrer/inferrer_engine.dart';
 import 'package:compiler/src/inferrer/type_graph_inferrer.dart';
+import 'package:compiler/src/js_model/element_map.dart';
+import 'package:compiler/src/js_model/js_strategy.dart';
 import 'package:compiler/src/kernel/element_map.dart';
-import 'package:compiler/src/kernel/kernel_backend_strategy.dart';
 import 'package:kernel/ast.dart' as ir;
 import '../equivalence/id_equivalence.dart';
 import '../equivalence/id_equivalence_helper.dart';
@@ -30,16 +30,11 @@
   const CallersDataComputer();
 
   @override
-  void setup() {
-    InferrerEngineImpl.retainDataForTesting = true;
-  }
-
-  @override
   void computeMemberData(
       Compiler compiler, MemberEntity member, Map<Id, ActualData> actualMap,
       {bool verbose: false}) {
-    KernelBackendStrategy backendStrategy = compiler.backendStrategy;
-    KernelToElementMapForBuilding elementMap = backendStrategy.elementMap;
+    JsBackendStrategy backendStrategy = compiler.backendStrategy;
+    JsToElementMap elementMap = backendStrategy.elementMap;
     MemberDefinition definition = elementMap.getMemberDefinition(member);
     new CallersIrComputer(
             compiler.reporter,
@@ -54,7 +49,7 @@
 /// AST visitor for computing side effects data for a member.
 class CallersIrComputer extends IrDataExtractor {
   final TypeGraphInferrer inferrer;
-  final KernelToElementMapForBuilding _elementMap;
+  final JsToElementMap _elementMap;
   final ClosureDataLookup _closureDataLookup;
 
   CallersIrComputer(DiagnosticReporter reporter, Map<Id, ActualData> actualMap,
diff --git a/tests/compiler/dart2js/inference/data/general.dart b/tests/compiler/dart2js/inference/data/general.dart
index 2b7f50d..afe68f0 100644
--- a/tests/compiler/dart2js/inference/data/general.dart
+++ b/tests/compiler/dart2js/inference/data/general.dart
@@ -424,7 +424,7 @@
   return a;
 }
 
-/*element: testSwitch3:Union([null|exact=JSString], [subclass=JSNumber])*/
+/*element: testSwitch3:Union([exact=JSString], [null|subclass=JSNumber])*/
 testSwitch3() {
   dynamic a = 42;
   var b;
@@ -461,7 +461,7 @@
   }
 }
 
-/*element: testContinue1:Union([null|exact=JSString], [subclass=JSNumber])*/
+/*element: testContinue1:Union([exact=JSString], [null|subclass=JSNumber])*/
 testContinue1() {
   dynamic a = 42;
   var b;
diff --git a/tests/compiler/dart2js/inference/data/native2.dart b/tests/compiler/dart2js/inference/data/native2.dart
new file mode 100644
index 0000000..bae53e9
--- /dev/null
+++ b/tests/compiler/dart2js/inference/data/native2.dart
@@ -0,0 +1,21 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// ignore: IMPORT_INTERNAL_LIBRARY
+import 'dart:_foreign_helper' as foreign show JS;
+import 'dart:html';
+
+/*element: main:[null]*/
+main() {
+  createElement();
+  createRectangle();
+}
+
+/*element: createElement:[null|subclass=Element]*/
+Element createElement()
+    // ignore: NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE
+    native;
+
+/*element: createRectangle:[subclass=DomRectReadOnly]*/
+createRectangle() => foreign.JS('Rectangle', "#", null);
diff --git a/tests/compiler/dart2js/inference/data/native3.dart b/tests/compiler/dart2js/inference/data/native3.dart
new file mode 100644
index 0000000..73e458f
--- /dev/null
+++ b/tests/compiler/dart2js/inference/data/native3.dart
@@ -0,0 +1,15 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+
+/*element: main:[null]*/
+main() {
+  createRectangle();
+}
+
+/*element: createRectangle:[null|subclass=DomRectReadOnly]*/
+Rectangle createRectangle()
+    // ignore: NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE
+    native;
diff --git a/tests/compiler/dart2js/inference/inference_data_test.dart b/tests/compiler/dart2js/inference/inference_data_test.dart
index 436126a..4b7a74e 100644
--- a/tests/compiler/dart2js/inference/inference_data_test.dart
+++ b/tests/compiler/dart2js/inference/inference_data_test.dart
@@ -10,8 +10,9 @@
 import 'package:compiler/src/diagnostics/diagnostic_listener.dart';
 import 'package:compiler/src/elements/entities.dart';
 import 'package:compiler/src/js_backend/inferred_data.dart';
+import 'package:compiler/src/js_model/element_map.dart';
+import 'package:compiler/src/js_model/js_strategy.dart';
 import 'package:compiler/src/kernel/element_map.dart';
-import 'package:compiler/src/kernel/kernel_backend_strategy.dart';
 import 'package:compiler/src/world.dart';
 import 'package:kernel/ast.dart' as ir;
 import '../equivalence/id_equivalence.dart';
@@ -42,8 +43,8 @@
   void computeMemberData(
       Compiler compiler, MemberEntity member, Map<Id, ActualData> actualMap,
       {bool verbose: false}) {
-    KernelBackendStrategy backendStrategy = compiler.backendStrategy;
-    KernelToElementMapForBuilding elementMap = backendStrategy.elementMap;
+    JsBackendStrategy backendStrategy = compiler.backendStrategy;
+    JsToElementMap elementMap = backendStrategy.elementMap;
     MemberDefinition definition = elementMap.getMemberDefinition(member);
     new InferredDataIrComputer(
             compiler.reporter,
@@ -59,7 +60,7 @@
 /// AST visitor for computing side effects data for a member.
 class InferredDataIrComputer extends IrDataExtractor {
   final JClosedWorld closedWorld;
-  final KernelToElementMapForBuilding _elementMap;
+  final JsToElementMap _elementMap;
   final ClosureDataLookup _closureDataLookup;
   final InferredData inferredData;
 
diff --git a/tests/compiler/dart2js/inference/inference_test_helper.dart b/tests/compiler/dart2js/inference/inference_test_helper.dart
index 293e0d5..cfaf1e1 100644
--- a/tests/compiler/dart2js/inference/inference_test_helper.dart
+++ b/tests/compiler/dart2js/inference/inference_test_helper.dart
@@ -11,9 +11,10 @@
 import 'package:compiler/src/elements/entities.dart';
 import 'package:compiler/src/inferrer/typemasks/masks.dart';
 import 'package:compiler/src/types/types.dart';
+import 'package:compiler/src/js_model/element_map.dart';
+import 'package:compiler/src/js_model/js_strategy.dart';
 import 'package:compiler/src/js_model/locals.dart';
 import 'package:compiler/src/kernel/element_map.dart';
-import 'package:compiler/src/kernel/kernel_backend_strategy.dart';
 import 'package:compiler/src/inferrer/builder_kernel.dart';
 import 'package:kernel/ast.dart' as ir;
 import '../equivalence/id_equivalence.dart';
@@ -54,8 +55,8 @@
   void computeMemberData(
       Compiler compiler, MemberEntity member, Map<Id, ActualData> actualMap,
       {bool verbose: false}) {
-    KernelBackendStrategy backendStrategy = compiler.backendStrategy;
-    KernelToElementMapForBuilding elementMap = backendStrategy.elementMap;
+    JsBackendStrategy backendStrategy = compiler.backendStrategy;
+    JsToElementMap elementMap = backendStrategy.elementMap;
     GlobalLocalsMap localsMap = backendStrategy.globalLocalsMapForTesting;
     MemberDefinition definition = elementMap.getMemberDefinition(member);
     new TypeMaskIrComputer(
@@ -74,7 +75,7 @@
 class TypeMaskIrComputer extends IrDataExtractor {
   final GlobalTypeInferenceResults results;
   GlobalTypeInferenceMemberResult result;
-  final KernelToElementMapForBuilding _elementMap;
+  final JsToElementMap _elementMap;
   final KernelToLocalsMap _localsMap;
   final ClosureDataLookup _closureDataLookup;
 
diff --git a/tests/compiler/dart2js/inference/list_tracer_test.dart b/tests/compiler/dart2js/inference/list_tracer_test.dart
index e475be6..9377f4b 100644
--- a/tests/compiler/dart2js/inference/list_tracer_test.dart
+++ b/tests/compiler/dart2js/inference/list_tracer_test.dart
@@ -8,7 +8,7 @@
 
 import 'type_mask_test_helper.dart';
 import '../helpers/element_lookup.dart';
-import '../memory_compiler.dart';
+import '../helpers/memory_compiler.dart';
 
 String generateTest(String listAllocation) {
   return """
diff --git a/tests/compiler/dart2js/inference/load_deferred_library_test.dart b/tests/compiler/dart2js/inference/load_deferred_library_test.dart
index c9e89ff..07b2e26 100644
--- a/tests/compiler/dart2js/inference/load_deferred_library_test.dart
+++ b/tests/compiler/dart2js/inference/load_deferred_library_test.dart
@@ -9,13 +9,14 @@
 import 'package:compiler/src/compiler.dart';
 import 'package:compiler/src/elements/entities.dart';
 import 'package:compiler/src/inferrer/typemasks/masks.dart';
+import 'package:compiler/src/js_model/element_map.dart';
 import 'package:compiler/src/js_model/js_strategy.dart';
 import 'package:compiler/src/kernel/element_map.dart';
 import 'package:compiler/src/types/abstract_value_domain.dart';
 import 'package:compiler/src/world.dart';
 import 'package:expect/expect.dart';
 import 'package:kernel/ast.dart' as ir;
-import '../memory_compiler.dart';
+import '../helpers/memory_compiler.dart';
 
 const String source = '''
 import 'package:expect/expect.dart' deferred as expect;
diff --git a/tests/compiler/dart2js/inference/map_tracer_test.dart b/tests/compiler/dart2js/inference/map_tracer_test.dart
index aa7e497..2135e08 100644
--- a/tests/compiler/dart2js/inference/map_tracer_test.dart
+++ b/tests/compiler/dart2js/inference/map_tracer_test.dart
@@ -12,7 +12,7 @@
 
 import 'type_mask_test_helper.dart';
 import '../helpers/element_lookup.dart';
-import '../memory_compiler.dart';
+import '../helpers/memory_compiler.dart';
 
 String generateTest(String mapAllocation) {
   return """
diff --git a/tests/compiler/dart2js/inference/side_effects_test.dart b/tests/compiler/dart2js/inference/side_effects_test.dart
index 4908291..e5d8e40 100644
--- a/tests/compiler/dart2js/inference/side_effects_test.dart
+++ b/tests/compiler/dart2js/inference/side_effects_test.dart
@@ -10,8 +10,9 @@
 import 'package:compiler/src/diagnostics/diagnostic_listener.dart';
 import 'package:compiler/src/elements/entities.dart';
 import 'package:compiler/src/js_backend/inferred_data.dart';
+import 'package:compiler/src/js_model/element_map.dart';
+import 'package:compiler/src/js_model/js_strategy.dart';
 import 'package:compiler/src/kernel/element_map.dart';
-import 'package:compiler/src/kernel/kernel_backend_strategy.dart';
 import 'package:compiler/src/world.dart';
 import 'package:kernel/ast.dart' as ir;
 import '../equivalence/id_equivalence.dart';
@@ -36,8 +37,8 @@
   void computeMemberData(
       Compiler compiler, MemberEntity member, Map<Id, ActualData> actualMap,
       {bool verbose: false}) {
-    KernelBackendStrategy backendStrategy = compiler.backendStrategy;
-    KernelToElementMapForBuilding elementMap = backendStrategy.elementMap;
+    JsBackendStrategy backendStrategy = compiler.backendStrategy;
+    JsToElementMap elementMap = backendStrategy.elementMap;
     MemberDefinition definition = elementMap.getMemberDefinition(member);
     new SideEffectsIrComputer(
             compiler.reporter,
@@ -53,7 +54,7 @@
 /// AST visitor for computing side effects data for a member.
 class SideEffectsIrComputer extends IrDataExtractor {
   final JClosedWorld closedWorld;
-  final KernelToElementMapForBuilding _elementMap;
+  final JsToElementMap _elementMap;
   final ClosureDataLookup _closureDataLookup;
   final InferredData inferredData;
 
diff --git a/tests/compiler/dart2js/inference/type_combination_test.dart b/tests/compiler/dart2js/inference/type_combination_test.dart
index 77e2bfe..cddae20 100644
--- a/tests/compiler/dart2js/inference/type_combination_test.dart
+++ b/tests/compiler/dart2js/inference/type_combination_test.dart
@@ -10,7 +10,7 @@
 import 'package:compiler/src/inferrer/typemasks/masks.dart';
 import 'package:compiler/src/world.dart';
 import 'type_mask_test_helper.dart';
-import '../memory_compiler.dart';
+import '../helpers/memory_compiler.dart';
 
 TypeMask nullType;
 TypeMask objectType;
diff --git a/tests/compiler/dart2js/inference/type_mask2_test.dart b/tests/compiler/dart2js/inference/type_mask2_test.dart
index 4ceb18b..d817014 100644
--- a/tests/compiler/dart2js/inference/type_mask2_test.dart
+++ b/tests/compiler/dart2js/inference/type_mask2_test.dart
@@ -10,7 +10,7 @@
 import 'package:compiler/src/elements/entities.dart';
 import 'package:compiler/src/inferrer/typemasks/masks.dart';
 import 'package:compiler/src/world.dart' show JClosedWorld;
-import '../type_test_helper.dart';
+import '../helpers/type_test_helper.dart';
 
 isCheckedMode() {
   try {
diff --git a/tests/compiler/dart2js/inference/type_mask_disjoint_test.dart b/tests/compiler/dart2js/inference/type_mask_disjoint_test.dart
index c3dd1a9..ab1ab7a 100644
--- a/tests/compiler/dart2js/inference/type_mask_disjoint_test.dart
+++ b/tests/compiler/dart2js/inference/type_mask_disjoint_test.dart
@@ -10,7 +10,7 @@
 import 'package:compiler/src/inferrer/typemasks/masks.dart';
 import 'package:compiler/src/world.dart';
 
-import '../memory_compiler.dart';
+import '../helpers/memory_compiler.dart';
 
 const String CODE = """
 class A {}
diff --git a/tests/compiler/dart2js/inference/type_mask_test.dart b/tests/compiler/dart2js/inference/type_mask_test.dart
index c22d721..53e6077 100644
--- a/tests/compiler/dart2js/inference/type_mask_test.dart
+++ b/tests/compiler/dart2js/inference/type_mask_test.dart
@@ -3,13 +3,13 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:async_helper/async_helper.dart';
-import 'package:expect/expect.dart';
-import 'package:compiler/src/inferrer/typemasks/masks.dart';
-
+import 'package:compiler/src/common.dart';
 import 'package:compiler/src/common_elements.dart';
 import 'package:compiler/src/compiler.dart';
+import 'package:compiler/src/inferrer/typemasks/masks.dart';
 import 'package:compiler/src/world.dart';
-import '../memory_compiler.dart';
+import 'package:expect/expect.dart';
+import '../helpers/memory_compiler.dart';
 
 const String CODE = """
 class A {}
@@ -22,6 +22,8 @@
 """;
 
 main() {
+  retainDataForTesting = true;
+
   runTests() async {
     CompilationResult result =
         await runCompiler(memorySourceFiles: {'main.dart': CODE});
diff --git a/tests/compiler/dart2js/inference/union_type_test.dart b/tests/compiler/dart2js/inference/union_type_test.dart
index bec8ae3..e938293 100644
--- a/tests/compiler/dart2js/inference/union_type_test.dart
+++ b/tests/compiler/dart2js/inference/union_type_test.dart
@@ -6,7 +6,7 @@
 import "package:expect/expect.dart";
 import 'package:compiler/src/inferrer/typemasks/masks.dart';
 import "package:compiler/src/world.dart";
-import '../type_test_helper.dart';
+import '../helpers/type_test_helper.dart';
 
 main() {
   runTest() async {
diff --git a/tests/compiler/dart2js/inlining/data/static_initializer.dart b/tests/compiler/dart2js/inlining/data/static_initializer.dart
new file mode 100644
index 0000000..11838285
--- /dev/null
+++ b/tests/compiler/dart2js/inlining/data/static_initializer.dart
@@ -0,0 +1,50 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/*element: main:[]*/
+main() {
+  _var1;
+  _var2;
+  _var3;
+}
+
+var _var1 = <String>[_shortString(), _longStringMany()];
+var _var2 = <String>[_shortString(), _longStringMany(), _longStringOnce()];
+
+/*element: _shortString:[_var1,_var2]*/
+String _shortString() => r"""
+hello""";
+
+/*element: _longStringMany:[]*/
+String _longStringMany() => r"""
+I wandered lonely as a cloud
+That floats on high o'er vales and hills,
+When all at once I saw a crowd,
+A host, of golden daffodils;
+Beside the lake, beneath the trees,
+Fluttering and dancing in the breeze.
+""";
+
+/*element: _longStringOnce:[_var2]*/
+String _longStringOnce() => r"""
+Continuous as the stars that shine
+And twinkle on the milky way,
+They stretched in never-ending line
+Along the margin of a bay:
+Ten thousand saw I at a glance,
+Tossing their heads in sprightly dance.
+""";
+
+var _var3 = <int>[Foo().a, (Foo()..a).a];
+
+/*element: Foo.:[]*/
+class Foo {
+  int z = 99;
+  /*element: Foo.a:[_var3]*/
+  get a => b;
+  /*element: Foo.b:[_var3]*/
+  get b => c;
+  /*element: Foo.c:[]*/
+  get c => z++;
+}
diff --git a/tests/compiler/dart2js/inlining/inlining_test.dart b/tests/compiler/dart2js/inlining/inlining_test.dart
index 110b7b3..8312b79 100644
--- a/tests/compiler/dart2js/inlining/inlining_test.dart
+++ b/tests/compiler/dart2js/inlining/inlining_test.dart
@@ -10,8 +10,9 @@
 import 'package:compiler/src/diagnostics/diagnostic_listener.dart';
 import 'package:compiler/src/elements/entities.dart';
 import 'package:compiler/src/js_backend/backend.dart';
+import 'package:compiler/src/js_model/element_map.dart';
+import 'package:compiler/src/js_model/js_strategy.dart';
 import 'package:compiler/src/kernel/element_map.dart';
-import 'package:compiler/src/kernel/kernel_backend_strategy.dart';
 import 'package:compiler/src/ssa/builder_kernel.dart' as kernel;
 import 'package:compiler/src/universe/world_impact.dart';
 import 'package:compiler/src/universe/use.dart';
@@ -29,11 +30,6 @@
 class InliningDataComputer extends DataComputer {
   const InliningDataComputer();
 
-  @override
-  void setup() {
-    JavaScriptBackend.cacheCodegenImpactForTesting = true;
-  }
-
   /// Compute type inference data for [member] from kernel based inference.
   ///
   /// Fills [actualMap] with the data.
@@ -41,8 +37,8 @@
   void computeMemberData(
       Compiler compiler, MemberEntity member, Map<Id, ActualData> actualMap,
       {bool verbose: false}) {
-    KernelBackendStrategy backendStrategy = compiler.backendStrategy;
-    KernelToElementMapForBuilding elementMap = backendStrategy.elementMap;
+    JsBackendStrategy backendStrategy = compiler.backendStrategy;
+    JsToElementMap elementMap = backendStrategy.elementMap;
     MemberDefinition definition = elementMap.getMemberDefinition(member);
     new InliningIrComputer(compiler.reporter, actualMap, elementMap, member,
             compiler.backend, backendStrategy.closureDataLookup)
@@ -53,7 +49,7 @@
 /// AST visitor for computing inference data for a member.
 class InliningIrComputer extends IrDataExtractor {
   final JavaScriptBackend backend;
-  final KernelToElementMapForBuilding _elementMap;
+  final JsToElementMap _elementMap;
   final ClosureDataLookup _closureDataLookup;
 
   InliningIrComputer(
diff --git a/tests/compiler/dart2js/inlining/meta_annotations2_test.dart b/tests/compiler/dart2js/inlining/meta_annotations2_test.dart
index ba54022..27e0277 100644
--- a/tests/compiler/dart2js/inlining/meta_annotations2_test.dart
+++ b/tests/compiler/dart2js/inlining/meta_annotations2_test.dart
@@ -7,7 +7,7 @@
 import "package:expect/expect.dart";
 import "package:async_helper/async_helper.dart";
 import 'package:compiler/compiler_new.dart';
-import '../memory_compiler.dart';
+import '../helpers/memory_compiler.dart';
 
 const MEMORY_SOURCE_FILES = const {
   'main.dart': r'''
diff --git a/tests/compiler/dart2js/inlining/meta_annotations3_test.dart b/tests/compiler/dart2js/inlining/meta_annotations3_test.dart
index e34c263..ca5024a 100644
--- a/tests/compiler/dart2js/inlining/meta_annotations3_test.dart
+++ b/tests/compiler/dart2js/inlining/meta_annotations3_test.dart
@@ -7,7 +7,7 @@
 import "package:expect/expect.dart";
 import "package:async_helper/async_helper.dart";
 import 'package:compiler/compiler_new.dart';
-import '../memory_compiler.dart';
+import '../helpers/memory_compiler.dart';
 
 const MEMORY_SOURCE_FILES = const {
   'main.dart': r'''
diff --git a/tests/compiler/dart2js/inlining/meta_annotations_test.dart b/tests/compiler/dart2js/inlining/meta_annotations_test.dart
index a820afe..600ae9d 100644
--- a/tests/compiler/dart2js/inlining/meta_annotations_test.dart
+++ b/tests/compiler/dart2js/inlining/meta_annotations_test.dart
@@ -7,9 +7,8 @@
 import 'package:compiler/src/common_elements.dart';
 import 'package:compiler/src/compiler.dart';
 import 'package:compiler/src/elements/entities.dart';
-import 'package:compiler/src/js_backend/annotations.dart' as optimizerHints;
 import 'package:compiler/src/world.dart' show KClosedWorld;
-import '../memory_compiler.dart';
+import '../helpers/memory_compiler.dart';
 
 const Map<String, String> MEMORY_SOURCE_FILES = const {
   'main.dart': r"""
@@ -54,13 +53,11 @@
       Expect.isNotNull(method);
       Expect.equals(
           expectNoInline,
-          optimizerHints.noInline(closedWorld.elementEnvironment,
-              closedWorld.commonElements, method),
+          closedWorld.annotationsData.nonInlinableFunctions.contains(method),
           "Unexpected annotation of @noInline on '$method'.");
       Expect.equals(
           expectTryInline,
-          optimizerHints.tryInline(closedWorld.elementEnvironment,
-              closedWorld.commonElements, method),
+          closedWorld.annotationsData.tryInlineFunctions.contains(method),
           "Unexpected annotation of @tryInline on '$method'.");
     }
 
diff --git a/tests/compiler/dart2js/js/js_constant_test.dart b/tests/compiler/dart2js/js/js_constant_test.dart
index f373884..0bc4b44 100644
--- a/tests/compiler/dart2js/js/js_constant_test.dart
+++ b/tests/compiler/dart2js/js/js_constant_test.dart
@@ -5,8 +5,8 @@
 import 'package:async_helper/async_helper.dart';
 import 'package:compiler/src/elements/entities.dart';
 import 'package:expect/expect.dart';
-import '../compiler_helper.dart';
-import '../memory_compiler.dart';
+import '../helpers/compiler_helper.dart';
+import '../helpers/memory_compiler.dart';
 
 const String TEST_1 = r"""
   import 'dart:_foreign_helper';
diff --git a/tests/compiler/dart2js/js/js_spec_optimization_test.dart b/tests/compiler/dart2js/js/js_spec_optimization_test.dart
index 8b97114..3ea2c61 100644
--- a/tests/compiler/dart2js/js/js_spec_optimization_test.dart
+++ b/tests/compiler/dart2js/js/js_spec_optimization_test.dart
@@ -5,8 +5,8 @@
 import 'package:async_helper/async_helper.dart';
 import 'package:compiler/src/elements/entities.dart';
 import 'package:expect/expect.dart';
-import '../compiler_helper.dart';
-import '../memory_compiler.dart';
+import '../helpers/compiler_helper.dart';
+import '../helpers/memory_compiler.dart';
 
 const String TEST_1 = r"""
   import 'dart:_foreign_helper';
diff --git a/tests/compiler/dart2js/jsinterop/declaration_test.dart b/tests/compiler/dart2js/jsinterop/declaration_test.dart
index d8f0fac6..92e8054 100644
--- a/tests/compiler/dart2js/jsinterop/declaration_test.dart
+++ b/tests/compiler/dart2js/jsinterop/declaration_test.dart
@@ -8,7 +8,7 @@
 import 'package:async_helper/async_helper.dart';
 import 'package:compiler/src/common.dart';
 import 'package:compiler/src/commandline_options.dart';
-import '../memory_compiler.dart';
+import '../helpers/memory_compiler.dart';
 
 const List<Test> TESTS = const <Test>[
   const Test('Empty js-interop class.', '''
diff --git a/tests/compiler/dart2js/jsinterop/interop_anonymous_unreachable_test.dart b/tests/compiler/dart2js/jsinterop/interop_anonymous_unreachable_test.dart
index b1084d2..62512f6 100644
--- a/tests/compiler/dart2js/jsinterop/interop_anonymous_unreachable_test.dart
+++ b/tests/compiler/dart2js/jsinterop/interop_anonymous_unreachable_test.dart
@@ -6,7 +6,7 @@
 
 import 'package:async_helper/async_helper.dart';
 import 'package:expect/expect.dart';
-import '../compiler_helper.dart';
+import '../helpers/compiler_helper.dart';
 
 testUnreachableCrash() async {
   print("-- unreachable code doesn't crash the compiler --");
diff --git a/tests/compiler/dart2js/jsinterop/world_test.dart b/tests/compiler/dart2js/jsinterop/world_test.dart
index e49b646..d1626de 100644
--- a/tests/compiler/dart2js/jsinterop/world_test.dart
+++ b/tests/compiler/dart2js/jsinterop/world_test.dart
@@ -14,7 +14,7 @@
 import 'package:compiler/src/universe/selector.dart';
 import 'package:compiler/src/world.dart';
 import '../helpers/element_lookup.dart';
-import '../memory_compiler.dart';
+import '../helpers/memory_compiler.dart';
 
 void main() {
   asyncTest(() async {
diff --git a/tests/compiler/dart2js/jumps/jump_test.dart b/tests/compiler/dart2js/jumps/jump_test.dart
index c8e9e12..90ceaf8 100644
--- a/tests/compiler/dart2js/jumps/jump_test.dart
+++ b/tests/compiler/dart2js/jumps/jump_test.dart
@@ -10,9 +10,10 @@
 import 'package:compiler/src/diagnostics/diagnostic_listener.dart';
 import 'package:compiler/src/elements/entities.dart';
 import 'package:compiler/src/elements/jumps.dart';
+import 'package:compiler/src/js_model/element_map.dart';
+import 'package:compiler/src/js_model/js_strategy.dart';
 import 'package:compiler/src/js_model/locals.dart';
 import 'package:compiler/src/kernel/element_map.dart';
-import 'package:compiler/src/kernel/kernel_backend_strategy.dart';
 import '../equivalence/id_equivalence.dart';
 import '../equivalence/id_equivalence_helper.dart';
 import 'package:kernel/ast.dart' as ir;
@@ -37,8 +38,8 @@
   void computeMemberData(
       Compiler compiler, MemberEntity member, Map<Id, ActualData> actualMap,
       {bool verbose: false}) {
-    KernelBackendStrategy backendStrategy = compiler.backendStrategy;
-    KernelToElementMapForBuilding elementMap = backendStrategy.elementMap;
+    JsBackendStrategy backendStrategy = compiler.backendStrategy;
+    JsToElementMap elementMap = backendStrategy.elementMap;
     GlobalLocalsMap localsMap = backendStrategy.globalLocalsMapForTesting;
     MemberDefinition definition = elementMap.getMemberDefinition(member);
     new JumpsIrChecker(
diff --git a/tests/compiler/dart2js/model/class_set_test.dart b/tests/compiler/dart2js/model/class_set_test.dart
index 05c754b..790a8a5 100644
--- a/tests/compiler/dart2js/model/class_set_test.dart
+++ b/tests/compiler/dart2js/model/class_set_test.dart
@@ -13,7 +13,7 @@
 import 'package:compiler/src/util/enumset.dart';
 import 'package:compiler/src/world.dart';
 import 'package:front_end/src/fasta/util/link.dart' show Link;
-import '../type_test_helper.dart';
+import '../helpers/type_test_helper.dart';
 
 void main() {
   asyncTest(() async {
@@ -36,8 +36,8 @@
       ///    D   E F G
       ///
       class A {}
-      class B extends A {}
       class C extends A {}
+      class B extends A {}
       class D extends B {}
       class E extends C {}
       class F extends C {}
@@ -361,8 +361,8 @@
       ///         H I
       ///
       class A implements X {}
-      class B extends A {}
       class C extends A {}
+      class B extends A {}
       class D extends B {}
       class E extends C {}
       class F extends C implements B {}
diff --git a/tests/compiler/dart2js/model/constant_expression_evaluate_test.dart b/tests/compiler/dart2js/model/constant_expression_evaluate_test.dart
index 8cf68f5..8a4f0d8 100644
--- a/tests/compiler/dart2js/model/constant_expression_evaluate_test.dart
+++ b/tests/compiler/dart2js/model/constant_expression_evaluate_test.dart
@@ -19,9 +19,8 @@
 import 'package:compiler/src/elements/entities.dart';
 import 'package:compiler/src/elements/types.dart';
 import 'package:compiler/src/kernel/kernel_strategy.dart';
-import 'package:compiler/src/kernel/element_map.dart';
 import 'package:compiler/src/kernel/element_map_impl.dart';
-import '../memory_compiler.dart';
+import '../helpers/memory_compiler.dart';
 
 class TestData {
   final String name;
@@ -668,7 +667,7 @@
   if (!skipStrongList.contains(data.name)) {
     await runTest((Compiler compiler, FieldEntity field) {
       KernelFrontEndStrategy frontendStrategy = compiler.frontendStrategy;
-      KernelToElementMap elementMap = frontendStrategy.elementMap;
+      KernelToElementMapImpl elementMap = frontendStrategy.elementMap;
       return new KernelEvaluationEnvironment(elementMap, null, field,
           constantRequired: field.isConst);
     });
diff --git a/tests/compiler/dart2js/model/constant_expression_test.dart b/tests/compiler/dart2js/model/constant_expression_test.dart
index f9064ae..4ab5072 100644
--- a/tests/compiler/dart2js/model/constant_expression_test.dart
+++ b/tests/compiler/dart2js/model/constant_expression_test.dart
@@ -11,7 +11,7 @@
 import 'package:compiler/src/constants/expressions.dart';
 import 'package:compiler/src/kernel/element_map_impl.dart';
 import 'package:compiler/src/elements/entities.dart';
-import '../memory_compiler.dart';
+import '../helpers/memory_compiler.dart';
 import 'constant_expression_evaluate_test.dart' show MemoryEnvironment;
 
 class TestData {
diff --git a/tests/compiler/dart2js/model/constant_value_test.dart b/tests/compiler/dart2js/model/constant_value_test.dart
index 5f5fa16..aebfbb3 100644
--- a/tests/compiler/dart2js/model/constant_value_test.dart
+++ b/tests/compiler/dart2js/model/constant_value_test.dart
@@ -10,7 +10,7 @@
 import 'package:compiler/src/elements/entities.dart';
 import 'package:compiler/src/elements/types.dart';
 import 'package:compiler/src/constants/values.dart';
-import '../type_test_helper.dart';
+import '../helpers/type_test_helper.dart';
 
 void main() {
   enableDebugMode();
diff --git a/tests/compiler/dart2js/model/enqueuer_test.dart b/tests/compiler/dart2js/model/enqueuer_test.dart
index 126e217..60c3fe6 100644
--- a/tests/compiler/dart2js/model/enqueuer_test.dart
+++ b/tests/compiler/dart2js/model/enqueuer_test.dart
@@ -21,7 +21,7 @@
 import 'package:compiler/src/universe/world_builder.dart';
 import 'package:compiler/src/world.dart';
 import 'package:expect/expect.dart';
-import '../memory_compiler.dart';
+import '../helpers/memory_compiler.dart';
 
 class Test {
   final String name;
@@ -250,7 +250,8 @@
     checkInvariant(enqueuer, elementEnvironment);
 
     Object createConstraint(ClassEntity cls) {
-      return new StrongModeConstraint(cls);
+      return new StrongModeConstraint(compiler.frontendStrategy.commonElements,
+          compiler.frontendStrategy.nativeBasicData, cls);
     }
 
     for (Impact impact in impacts) {
diff --git a/tests/compiler/dart2js/enumset_test.dart b/tests/compiler/dart2js/model/enumset_test.dart
similarity index 100%
rename from tests/compiler/dart2js/enumset_test.dart
rename to tests/compiler/dart2js/model/enumset_test.dart
diff --git a/tests/compiler/dart2js/model/forwarding_stub_test.dart b/tests/compiler/dart2js/model/forwarding_stub_test.dart
index ddc9f46..1784cf3 100644
--- a/tests/compiler/dart2js/model/forwarding_stub_test.dart
+++ b/tests/compiler/dart2js/model/forwarding_stub_test.dart
@@ -8,7 +8,7 @@
 import 'package:compiler/src/elements/entities.dart';
 import 'package:compiler/src/world.dart';
 import 'package:expect/expect.dart';
-import '../memory_compiler.dart';
+import '../helpers/memory_compiler.dart';
 
 const String source = '''
 
diff --git a/tests/compiler/dart2js/model/future_or_test.dart b/tests/compiler/dart2js/model/future_or_test.dart
index 2245e4e..cbb513c 100644
--- a/tests/compiler/dart2js/model/future_or_test.dart
+++ b/tests/compiler/dart2js/model/future_or_test.dart
@@ -6,7 +6,7 @@
 import 'package:compiler/src/elements/entities.dart';
 import 'package:compiler/src/elements/types.dart';
 import 'package:expect/expect.dart';
-import '../type_test_helper.dart';
+import '../helpers/type_test_helper.dart';
 
 main() {
   asyncTest(() async {
diff --git a/tests/compiler/dart2js/model/in_memory_split_test.dart b/tests/compiler/dart2js/model/in_memory_split_test.dart
new file mode 100644
index 0000000..8c1a080
--- /dev/null
+++ b/tests/compiler/dart2js/model/in_memory_split_test.dart
@@ -0,0 +1,42 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:async_helper/async_helper.dart';
+import 'package:compiler/src/compiler.dart';
+import 'package:compiler/src/js_backend/inferred_data.dart';
+import 'package:compiler/src/types/types.dart';
+import 'package:compiler/src/world.dart';
+import 'package:expect/expect.dart';
+import '../helpers/memory_compiler.dart';
+
+String code = '''
+main() {}
+''';
+main() {
+  asyncTest(() async {
+    CompilationResult result = await runCompiler(
+        memorySourceFiles: {'main.dart': code},
+        beforeRun: (Compiler compiler) {
+          compiler.stopAfterTypeInference = true;
+        });
+    Expect.isTrue(result.isSuccess);
+    Compiler compiler = result.compiler;
+    GlobalTypeInferenceResults globalInferenceResults =
+        cloneInferenceResults(compiler.globalInference.resultsForTesting);
+    compiler.generateJavaScriptCode(globalInferenceResults);
+  });
+}
+
+GlobalTypeInferenceResults cloneInferenceResults(
+    GlobalTypeInferenceResultsImpl result) {
+  JClosedWorld closedWorld = result.closedWorld;
+  InferredData inferredData = result.inferredData;
+  return new GlobalTypeInferenceResultsImpl(
+      closedWorld,
+      inferredData,
+      result.memberResults,
+      result.parameterResults,
+      result.checkedForGrowableLists,
+      result.returnsListElementTypeSet);
+}
diff --git a/tests/compiler/dart2js/in_user_code_test.dart b/tests/compiler/dart2js/model/in_user_code_test.dart
similarity index 97%
rename from tests/compiler/dart2js/in_user_code_test.dart
rename to tests/compiler/dart2js/model/in_user_code_test.dart
index 580fdf6..1e65ecb 100644
--- a/tests/compiler/dart2js/in_user_code_test.dart
+++ b/tests/compiler/dart2js/model/in_user_code_test.dart
@@ -8,7 +8,7 @@
 import 'package:async_helper/async_helper.dart';
 import 'package:expect/expect.dart';
 import 'package:compiler/src/compiler.dart' show Compiler;
-import 'memory_compiler.dart';
+import '../helpers/memory_compiler.dart';
 
 const SOURCE = const {
   'main.dart': """
diff --git a/tests/compiler/dart2js/indentation_test.dart b/tests/compiler/dart2js/model/indentation_test.dart
similarity index 100%
rename from tests/compiler/dart2js/indentation_test.dart
rename to tests/compiler/dart2js/model/indentation_test.dart
diff --git a/tests/compiler/dart2js/instantiated_classes_test.dart b/tests/compiler/dart2js/model/instantiated_classes_test.dart
similarity index 98%
rename from tests/compiler/dart2js/instantiated_classes_test.dart
rename to tests/compiler/dart2js/model/instantiated_classes_test.dart
index 4289d6f..3c3e074 100644
--- a/tests/compiler/dart2js/instantiated_classes_test.dart
+++ b/tests/compiler/dart2js/model/instantiated_classes_test.dart
@@ -9,7 +9,7 @@
 import 'package:async_helper/async_helper.dart';
 import 'package:compiler/src/elements/entities.dart'
     show ClassEntity, LibraryEntity;
-import 'type_test_helper.dart';
+import '../helpers/type_test_helper.dart';
 
 void main() {
   Future runTests() async {
diff --git a/tests/compiler/dart2js/link_test.dart b/tests/compiler/dart2js/model/link_test.dart
similarity index 97%
rename from tests/compiler/dart2js/link_test.dart
rename to tests/compiler/dart2js/model/link_test.dart
index 5033eea..85ea006 100644
--- a/tests/compiler/dart2js/link_test.dart
+++ b/tests/compiler/dart2js/model/link_test.dart
@@ -4,7 +4,7 @@
 
 import "package:expect/expect.dart";
 import 'package:front_end/src/fasta/util/link.dart' show Link;
-import 'link_helper.dart';
+import '../helpers/link_helper.dart';
 
 main() {
   test(const Link<Comparable>().prepend('three').prepend(2).prepend('one'),
diff --git a/tests/compiler/dart2js/maplet_test.dart b/tests/compiler/dart2js/model/maplet_test.dart
similarity index 100%
rename from tests/compiler/dart2js/maplet_test.dart
rename to tests/compiler/dart2js/model/maplet_test.dart
diff --git a/tests/compiler/dart2js/model/mixin_typevariable_test.dart b/tests/compiler/dart2js/model/mixin_typevariable_test.dart
index 5cfca15..7768343 100644
--- a/tests/compiler/dart2js/model/mixin_typevariable_test.dart
+++ b/tests/compiler/dart2js/model/mixin_typevariable_test.dart
@@ -8,7 +8,7 @@
 import 'package:compiler/src/elements/entities.dart';
 import 'package:compiler/src/elements/types.dart';
 import 'package:expect/expect.dart';
-import '../type_test_helper.dart';
+import '../helpers/type_test_helper.dart';
 
 void main() {
   asyncTest(() async {
diff --git a/tests/compiler/dart2js/model/native_test.dart b/tests/compiler/dart2js/model/native_test.dart
index 2172f02..3e7284b 100644
--- a/tests/compiler/dart2js/model/native_test.dart
+++ b/tests/compiler/dart2js/model/native_test.dart
@@ -8,7 +8,7 @@
 import 'package:compiler/src/elements/entities.dart';
 import 'package:compiler/src/world.dart';
 import 'package:expect/expect.dart';
-import '../memory_compiler.dart';
+import '../helpers/memory_compiler.dart';
 
 enum Kind {
   regular,
@@ -72,6 +72,13 @@
       '35',
       '36',
       '37',
+      // TODO(34345): Non-external static members should not be allowed.
+      '43',
+      '44',
+      '45',
+      '52',
+      '53',
+      '54',
     ]);
     await runTest('tests/compiler/dart2js_extra/non_jsinterop_test.dart', '', {
       'Class': Kind.regular,
@@ -124,6 +131,13 @@
       '35',
       '36',
       '37',
+      // TODO(34345): Non-external static members should not be allowed.
+      '43',
+      '44',
+      '45',
+      '52',
+      '53',
+      '54',
     ]);
     // TODO(johnniwinther): Add similar test for native declarations.
   });
diff --git a/tests/compiler/dart2js/needs_no_such_method_test.dart b/tests/compiler/dart2js/model/needs_no_such_method_test.dart
similarity index 98%
rename from tests/compiler/dart2js/needs_no_such_method_test.dart
rename to tests/compiler/dart2js/model/needs_no_such_method_test.dart
index c6470a9..219d946 100644
--- a/tests/compiler/dart2js/needs_no_such_method_test.dart
+++ b/tests/compiler/dart2js/model/needs_no_such_method_test.dart
@@ -11,7 +11,7 @@
 import 'package:compiler/src/universe/class_hierarchy.dart';
 import 'package:compiler/src/universe/selector.dart';
 import 'package:compiler/src/world.dart' show JClosedWorld;
-import 'type_test_helper.dart';
+import '../helpers/type_test_helper.dart';
 
 void main() {
   asyncTest(() async {
@@ -42,11 +42,13 @@
     print('---- testing $instantiated ---------------------------------------');
     StringBuffer main = new StringBuffer();
     main.writeln(CLASSES);
-    main.write('main() {');
+    main.writeln('main() {');
+    main.writeln('  dynamic d;');
+    main.writeln('  d.foo(); d.bar(); d.baz();');
     for (String cls in instantiated) {
-      main.write('new $cls();');
+      main.writeln('  new $cls();');
     }
-    main.write('}');
+    main.writeln('}');
     testMode = '$instantiated';
 
     var env =
diff --git a/tests/compiler/dart2js/no_such_method_enabled_test.dart b/tests/compiler/dart2js/model/no_such_method_enabled_test.dart
similarity index 89%
rename from tests/compiler/dart2js/no_such_method_enabled_test.dart
rename to tests/compiler/dart2js/model/no_such_method_enabled_test.dart
index b98c045..6410edf 100644
--- a/tests/compiler/dart2js/no_such_method_enabled_test.dart
+++ b/tests/compiler/dart2js/model/no_such_method_enabled_test.dart
@@ -9,7 +9,7 @@
 import 'package:compiler/src/js_backend/no_such_method_registry.dart';
 import 'package:compiler/src/world.dart';
 import 'package:expect/expect.dart';
-import 'memory_compiler.dart';
+import '../helpers/memory_compiler.dart';
 
 class NoSuchMethodInfo {
   final String className;
@@ -44,8 +44,10 @@
 
 const List<NoSuchMethodTest> TESTS = const <NoSuchMethodTest>[
   const NoSuchMethodTest("""
-class A {
-  foo() => 3;
+abstract class I {
+  foo();
+}
+class A implements I {
   noSuchMethod(x) => super.noSuchMethod(x);
 }
 main() {
@@ -55,8 +57,10 @@
     const NoSuchMethodInfo('A', hasForwardingSyntax: true, isDefault: true),
   ]),
   const NoSuchMethodTest("""
-class A extends B {
-  foo() => 3;
+abstract class I {
+  foo();
+}
+class A extends B implements I {
   noSuchMethod(x) => super.noSuchMethod(x);
 }
 class B {}
@@ -67,8 +71,10 @@
     const NoSuchMethodInfo('A', hasForwardingSyntax: true, isDefault: true),
   ]),
   const NoSuchMethodTest("""
-class A extends B {
-  foo() => 3;
+abstract class I {
+  foo();
+}
+class A extends B implements I {
   noSuchMethod(x) {
     return super.noSuchMethod(x);
   }
@@ -81,8 +87,10 @@
     const NoSuchMethodInfo('A', hasForwardingSyntax: true, isDefault: true),
   ]),
   const NoSuchMethodTest("""
-class A extends B {
-  foo() => 3;
+abstract class I {
+  foo();
+}
+class A extends B implements I {
   noSuchMethod(x) => super.noSuchMethod(x);
 }
 class B {
@@ -97,8 +105,10 @@
     const NoSuchMethodInfo('B', hasForwardingSyntax: true, isDefault: true),
   ]),
   const NoSuchMethodTest("""
-class A extends B {
-  foo() => 3;
+abstract class I {
+  foo();
+}
+class A extends B implements I {
   noSuchMethod(x) => super.noSuchMethod(x);
 }
 class B {
@@ -123,16 +133,32 @@
     const NoSuchMethodInfo('A', isOther: true, isComplexReturn: true),
   ], isNoSuchMethodUsed: true),
   const NoSuchMethodTest("""
-class A {
+abstract class I {
+  foo();
+}
+class A implements I {
   noSuchMethod(x, [y]) => super.noSuchMethod(x);
 }
 main() {
-  print((new A() as dynamic).foo());
+  print(new A().foo());
 }
 """, const <NoSuchMethodInfo>[
     const NoSuchMethodInfo('A', hasForwardingSyntax: true, isDefault: true),
   ]),
   const NoSuchMethodTest("""
+abstract class I {
+  foo();
+}
+class A implements I {
+  noSuchMethod(x, [y]) => super.noSuchMethod(y);
+}
+main() {
+  print(new A().foo());
+}
+""", const <NoSuchMethodInfo>[
+    const NoSuchMethodInfo('A', isOther: true, isComplexNoReturn: true),
+  ], isNoSuchMethodUsed: true),
+  const NoSuchMethodTest("""
 class A {
   noSuchMethod(x, [y]) => super.noSuchMethod(x) + y;
 }
@@ -180,15 +206,31 @@
     const NoSuchMethodInfo('A', isOther: true, isComplexReturn: true),
   ], isNoSuchMethodUsed: true),
   const NoSuchMethodTest("""
-class A {
+abstract class I {
+  foo();
+}
+class A implements I {
   noSuchMethod(x) => super.noSuchMethod(x) as dynamic;
 }
 main() {
-  print((new A() as dynamic).foo());
+  print(new A().foo());
 }
 """, const <NoSuchMethodInfo>[
     const NoSuchMethodInfo('A', hasForwardingSyntax: true, isDefault: true),
   ]),
+  const NoSuchMethodTest("""
+abstract class I {
+  foo();
+}
+class A implements I {
+  noSuchMethod(x) => super.noSuchMethod(x) as int;
+}
+main() {
+  print(new A().foo());
+}
+""", const <NoSuchMethodInfo>[
+    const NoSuchMethodInfo('A', isOther: true, isComplexNoReturn: true),
+  ], isNoSuchMethodUsed: true),
 ];
 
 main() {
@@ -198,6 +240,7 @@
       print(test.code);
       CompilationResult result =
           await runCompiler(memorySourceFiles: {'main.dart': test.code});
+      Expect.isTrue(result.isSuccess);
       Compiler compiler = result.compiler;
       checkTest(compiler, test);
     }
diff --git a/tests/compiler/dart2js/model/no_such_method_forwarders_test.dart b/tests/compiler/dart2js/model/no_such_method_forwarders_test.dart
index 69655bd..27bece5 100644
--- a/tests/compiler/dart2js/model/no_such_method_forwarders_test.dart
+++ b/tests/compiler/dart2js/model/no_such_method_forwarders_test.dart
@@ -9,7 +9,7 @@
 import 'package:compiler/src/world.dart';
 import 'package:expect/expect.dart';
 import '../helpers/element_lookup.dart';
-import '../memory_compiler.dart';
+import '../helpers/memory_compiler.dart';
 
 const String source = '''
 abstract class I<T> {
@@ -98,6 +98,8 @@
   new F3();
   new G3();
   new H3();
+  dynamic d;
+  d.method();
 }
 ''';
 
diff --git a/tests/compiler/dart2js/receiver_type_test.dart b/tests/compiler/dart2js/model/receiver_type_test.dart
similarity index 97%
rename from tests/compiler/dart2js/receiver_type_test.dart
rename to tests/compiler/dart2js/model/receiver_type_test.dart
index d8ad1ac..663c6e3 100644
--- a/tests/compiler/dart2js/receiver_type_test.dart
+++ b/tests/compiler/dart2js/model/receiver_type_test.dart
@@ -9,7 +9,7 @@
 import 'package:compiler/src/universe/selector.dart';
 import 'package:compiler/src/world.dart';
 import 'package:expect/expect.dart';
-import 'type_test_helper.dart';
+import '../helpers/type_test_helper.dart';
 
 main() {
   asyncTest(() async {
diff --git a/tests/compiler/dart2js/setlet_test.dart b/tests/compiler/dart2js/model/setlet_test.dart
similarity index 100%
rename from tests/compiler/dart2js/setlet_test.dart
rename to tests/compiler/dart2js/model/setlet_test.dart
diff --git a/tests/compiler/dart2js/sha1_long_test_vectors.dart b/tests/compiler/dart2js/model/sha1_long_test_vectors.dart
similarity index 100%
rename from tests/compiler/dart2js/sha1_long_test_vectors.dart
rename to tests/compiler/dart2js/model/sha1_long_test_vectors.dart
diff --git a/tests/compiler/dart2js/sha1_short_test_vectors.dart b/tests/compiler/dart2js/model/sha1_short_test_vectors.dart
similarity index 100%
rename from tests/compiler/dart2js/sha1_short_test_vectors.dart
rename to tests/compiler/dart2js/model/sha1_short_test_vectors.dart
diff --git a/tests/compiler/dart2js/sha1_test.dart b/tests/compiler/dart2js/model/sha1_test.dart
similarity index 100%
rename from tests/compiler/dart2js/sha1_test.dart
rename to tests/compiler/dart2js/model/sha1_test.dart
diff --git a/tests/compiler/dart2js/model/strong_mode_closed_world_test.dart b/tests/compiler/dart2js/model/strong_mode_closed_world_test.dart
index 8c7c8d3..d721dc7 100644
--- a/tests/compiler/dart2js/model/strong_mode_closed_world_test.dart
+++ b/tests/compiler/dart2js/model/strong_mode_closed_world_test.dart
@@ -7,12 +7,10 @@
 import 'package:compiler/src/compiler.dart';
 import 'package:compiler/src/common_elements.dart';
 import 'package:compiler/src/elements/entities.dart';
-import 'package:compiler/src/universe/world_builder.dart';
 import 'package:compiler/src/world.dart';
-import '../memory_compiler.dart';
+import '../helpers/memory_compiler.dart';
 
 main() {
-  useStrongModeWorldStrategy = true;
   asyncTest(() async {
     await runTest();
   });
@@ -113,6 +111,18 @@
 
 class R extends Q {}
 
+class Class1a {
+  call(a, b, c) {} // Call structure only used in Class1a and Class2b.
+}
+
+class Class1b {
+  call(a, b, c) {}
+}
+
+class Class2 {
+  Class1a c;
+}
+
 main() {
   A a = new A();
   B b = new B();
@@ -134,6 +144,9 @@
   R r;
   r.method3();
   r = new R(); // Create R after call.
+  new Class1a();
+  new Class1b();
+  new Class2().c(0, 1, 2);
 }
 '''
   });
@@ -151,6 +164,9 @@
     'N': [],
     'P': ['method1', 'getter', 'setter'],
     'Q': ['method3'],
+    'Class1a': ['call'],
+    'Class1b': [],
+    'Class2': ['c'],
   };
 
   KClosedWorld closedWorld =
diff --git a/tests/compiler/dart2js/model/strong_mode_impact_test.dart b/tests/compiler/dart2js/model/strong_mode_impact_test.dart
index 2ad2eb5..1b2f5ad 100644
--- a/tests/compiler/dart2js/model/strong_mode_impact_test.dart
+++ b/tests/compiler/dart2js/model/strong_mode_impact_test.dart
@@ -4,14 +4,14 @@
 
 import 'package:expect/expect.dart';
 import 'package:async_helper/async_helper.dart';
+import 'package:compiler/src/common.dart';
 import 'package:compiler/src/compiler.dart';
 import 'package:compiler/src/common_elements.dart';
 import 'package:compiler/src/elements/entities.dart';
-import 'package:compiler/src/frontend_strategy.dart';
 import 'package:compiler/src/world.dart';
 import 'package:compiler/src/universe/use.dart';
 import 'package:compiler/src/universe/world_impact.dart';
-import '../memory_compiler.dart';
+import '../helpers/memory_compiler.dart';
 
 main() {
   asyncTest(() async {
@@ -71,7 +71,7 @@
     'method13': new Impact(implicitCasts: ['int'], parameterChecks: ['String']),
   };
 
-  ImpactCacheDeleter.retainCachesForTesting = true;
+  retainDataForTesting = true;
   CompilationResult result =
       await runCompiler(memorySourceFiles: {'main.dart': source});
   Expect.isTrue(result.isSuccess);
diff --git a/tests/compiler/dart2js/model/subtype_test.dart b/tests/compiler/dart2js/model/subtype_test.dart
index c265ea0..9a43a69 100644
--- a/tests/compiler/dart2js/model/subtype_test.dart
+++ b/tests/compiler/dart2js/model/subtype_test.dart
@@ -9,7 +9,7 @@
 import 'package:compiler/src/elements/entities.dart' show ClassEntity;
 import 'package:compiler/src/elements/types.dart';
 import 'package:expect/expect.dart';
-import '../type_test_helper.dart';
+import '../helpers/type_test_helper.dart';
 
 void main() {
   asyncTest(() async {
@@ -59,7 +59,7 @@
       main() {
         new C();
       }
-      """).then((env) {
+      """, expectNoErrors: true).then((env) {
     void expect(bool expectSubtype, DartType T, DartType S,
         {bool expectMoreSpecific}) {
       testTypes(env, T, S, expectSubtype, expectMoreSpecific);
@@ -318,7 +318,7 @@
         a.m4(null, null);
         a.m5(null, null);
       }
-      """).then((env) {
+      """, expectNoErrors: true).then((env) {
     void expect(bool expectSubtype, DartType T, DartType S,
         {bool expectMoreSpecific}) {
       testTypes(env, T, S, expectSubtype, expectMoreSpecific);
@@ -371,7 +371,8 @@
   main() {
     ${createUses(functionTypesData)}
   }
-  """))
+  """),
+          expectNoErrors: true)
       .then(functionSubtypingHelper);
 }
 
@@ -381,7 +382,8 @@
   main() {
     ${createUses(functionTypesData)}
   }
-  """))
+  """),
+          expectNoErrors: true)
       .then(functionSubtypingHelper);
 }
 
@@ -463,7 +465,8 @@
   main() {
     ${createUses(optionalFunctionTypesData)}
   }
-  """))
+  """),
+          expectNoErrors: true)
       .then((env) => functionSubtypingOptionalHelper(env));
 }
 
@@ -473,7 +476,8 @@
   main() {
     ${createUses(optionalFunctionTypesData)}
   }
-  """))
+  """),
+          expectNoErrors: true)
       .then((env) => functionSubtypingOptionalHelper(env));
 }
 
@@ -543,7 +547,8 @@
   main() {
     ${createUses(namedFunctionTypesData)}
   }
-  """))
+  """),
+          expectNoErrors: true)
       .then((env) => functionSubtypingNamedHelper(env));
 }
 
@@ -553,7 +558,8 @@
   main() {
     ${createUses(namedFunctionTypesData)}
   }
-  """))
+  """),
+          expectNoErrors: true)
       .then((env) => functionSubtypingNamedHelper(env));
 }
 
@@ -601,10 +607,6 @@
       class D<T extends int> {}
       class E<T extends S, S extends num> {}
       class F<T extends num, S extends T> {}
-      class G<T extends T> {}
-      class H<T extends S, S extends T> {}
-      class I<T extends S, S extends U, U extends T> {}
-      class J<T extends S, S extends U, U extends S> {}
 
       main() {
         new A();
@@ -613,12 +615,8 @@
         new D();
         new E<num, int>();
         new F();
-        new G();
-        new H();
-        new I();
-        new J();
       }
-      """).then((env) {
+      """, expectNoErrors: true).then((env) {
     void expect(bool expectSubtype, DartType T, DartType S,
         {bool expectMoreSpecific}) {
       testTypes(env, T, S, expectSubtype, expectMoreSpecific);
@@ -642,19 +640,6 @@
     ClassEntity F = env.getClass('F');
     TypeVariableType F_T = getTypeVariable(F, 0);
     TypeVariableType F_S = getTypeVariable(F, 1);
-    ClassEntity G = env.getClass('G');
-    TypeVariableType G_T = getTypeVariable(G, 0);
-    ClassEntity H = env.getClass('H');
-    TypeVariableType H_T = getTypeVariable(H, 0);
-    TypeVariableType H_S = getTypeVariable(H, 1);
-    ClassEntity I = env.getClass('I');
-    TypeVariableType I_T = getTypeVariable(I, 0);
-    TypeVariableType I_S = getTypeVariable(I, 1);
-    TypeVariableType I_U = getTypeVariable(I, 2);
-    ClassEntity J = env.getClass('J');
-    TypeVariableType J_T = getTypeVariable(J, 0);
-    TypeVariableType J_S = getTypeVariable(J, 1);
-    TypeVariableType J_U = getTypeVariable(J, 2);
 
     DartType Object_ = env['Object'];
     DartType num_ = env['num'];
@@ -735,96 +720,6 @@
     expect(true, F_S, F_S);
     expect(true, F_S, F_T);
     expect(false, F_S, A_T);
-
-    // class G<T extends T> {}
-    expect(true, G_T, Object_);
-    expect(false, G_T, num_);
-    expect(false, G_T, int_);
-    expect(false, G_T, String_);
-    expect(true, G_T, dynamic_);
-    expect(true, G_T, G_T);
-    expect(false, G_T, A_T);
-
-    // class H<T extends S, S extends T> {}
-    expect(true, H_T, Object_);
-    expect(false, H_T, num_);
-    expect(false, H_T, int_);
-    expect(false, H_T, String_);
-    expect(true, H_T, dynamic_);
-    expect(true, H_T, H_T);
-    expect(true, H_T, H_S);
-    expect(false, H_T, A_T);
-
-    expect(true, H_S, Object_);
-    expect(false, H_S, num_);
-    expect(false, H_S, int_);
-    expect(false, H_S, String_);
-    expect(true, H_S, dynamic_);
-    expect(true, H_S, H_T);
-    expect(true, H_S, H_S);
-    expect(false, H_S, A_T);
-
-    // class I<T extends S, S extends U, U extends T> {}
-    expect(true, I_T, Object_);
-    expect(false, I_T, num_);
-    expect(false, I_T, int_);
-    expect(false, I_T, String_);
-    expect(true, I_T, dynamic_);
-    expect(true, I_T, I_T);
-    expect(true, I_T, I_S);
-    expect(true, I_T, I_U);
-    expect(false, I_T, A_T);
-
-    expect(true, I_S, Object_);
-    expect(false, I_S, num_);
-    expect(false, I_S, int_);
-    expect(false, I_S, String_);
-    expect(true, I_S, dynamic_);
-    expect(true, I_S, I_T);
-    expect(true, I_S, I_S);
-    expect(true, I_S, I_U);
-    expect(false, I_S, A_T);
-
-    expect(true, I_U, Object_);
-    expect(false, I_U, num_);
-    expect(false, I_U, int_);
-    expect(false, I_U, String_);
-    expect(true, I_U, dynamic_);
-    expect(true, I_U, I_T);
-    expect(true, I_U, I_S);
-    expect(true, I_U, I_U);
-    expect(false, I_U, A_T);
-
-    // class J<T extends S, S extends U, U extends S> {}
-    expect(true, J_T, Object_);
-    expect(false, J_T, num_);
-    expect(false, J_T, int_);
-    expect(false, J_T, String_);
-    expect(true, J_T, dynamic_);
-    expect(true, J_T, J_T);
-    expect(true, J_T, J_S);
-    expect(true, J_T, J_U);
-    expect(false, J_T, A_T);
-
-    expect(true, J_S, Object_);
-    expect(false, J_S, num_);
-    expect(false, J_S, int_);
-    expect(false, J_S, String_);
-    expect(true, J_S, dynamic_);
-    expect(false, J_S, J_T);
-    expect(true, J_S, J_S);
-    expect(true, J_S, J_U);
-    expect(false, J_S, A_T);
-
-    expect(true, J_U, Object_);
-    expect(false, J_U, num_);
-    expect(false, J_U, int_);
-    expect(false, J_U, String_);
-    expect(true, J_U, dynamic_);
-    expect(false, J_U, J_T);
-    expect(true, J_U, J_S);
-    expect(true, J_U, J_U);
-    expect(false, J_U, A_T);
   });
 }
 
@@ -855,7 +750,7 @@
         takeVoid(null);
         takeObject(null);
       }
-      """).then((env) {
+      """, expectNoErrors: true).then((env) {
     void expect(bool expectSubtype, DartType T, DartType S) {
       Expect.equals(expectSubtype, env.isSubtype(T, S), '$T <: $S');
       if (expectSubtype) {
diff --git a/tests/compiler/dart2js/model/subtypeset_test.dart b/tests/compiler/dart2js/model/subtypeset_test.dart
index 59da374..dda257b 100644
--- a/tests/compiler/dart2js/model/subtypeset_test.dart
+++ b/tests/compiler/dart2js/model/subtypeset_test.dart
@@ -11,7 +11,7 @@
 import 'package:compiler/src/elements/entities.dart';
 import 'package:compiler/src/universe/class_set.dart';
 import 'package:compiler/src/world.dart';
-import '../type_test_helper.dart';
+import '../helpers/type_test_helper.dart';
 
 void main() {
   asyncTest(() async {
diff --git a/tests/compiler/dart2js/model/supermixin_test.dart b/tests/compiler/dart2js/model/supermixin_test.dart
new file mode 100644
index 0000000..b0ed2a4
--- /dev/null
+++ b/tests/compiler/dart2js/model/supermixin_test.dart
@@ -0,0 +1,69 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:async_helper/async_helper.dart';
+import 'package:compiler/src/commandline_options.dart';
+import 'package:compiler/src/common_elements.dart';
+import 'package:compiler/src/elements/entities.dart';
+import 'package:expect/expect.dart';
+import '../helpers/program_lookup.dart';
+import '../helpers/memory_compiler.dart';
+
+const String source = r'''
+import 'package:expect/expect.dart';
+
+class SuperA {
+  method1(a) => 'A$a';
+}
+
+class SuperB extends SuperA {
+  method1(a) => 'B$a';
+}
+
+class Mixin extends SuperA {
+  method1(a) => super.method1('M$a');
+  method2(a) => 'M$a';
+}
+
+class Class extends SuperB with Mixin {}
+
+main() {
+  var c = new Class();
+  Expect.equals("BMC", c.method1('C'));
+  Expect.equals("MC", c.method2('C'));
+}
+''';
+
+main() {
+  asyncTest(() async {
+    CompilationResult result = await runCompiler(
+        memorySourceFiles: {'main.dart': source},
+        options: <String>[Flags.disableInlining]);
+    Expect.isTrue(result.isSuccess);
+
+    ElementEnvironment elementEnvironment =
+        result.compiler.backendClosedWorldForTesting.elementEnvironment;
+
+    ClassEntity cls = lookupClass(elementEnvironment, 'Class');
+    ClassEntity mixin = lookupClass(elementEnvironment, 'Mixin');
+    ClassEntity superA = lookupClass(elementEnvironment, 'SuperA');
+    ClassEntity superB = lookupClass(elementEnvironment, 'SuperB');
+    ClassEntity superClass = elementEnvironment.getSuperClass(cls);
+
+    Expect.isTrue(elementEnvironment.isSuperMixinApplication(superClass));
+    Expect.equals(mixin, elementEnvironment.getEffectiveMixinClass(superClass));
+    Expect.equals(superA, elementEnvironment.getSuperClass(mixin));
+    Expect.equals(superB, elementEnvironment.getSuperClass(superClass));
+
+    MemberEntity method1 = lookupMember(elementEnvironment, 'Class.method1');
+    Expect.equals(superClass, method1.enclosingClass);
+    MemberEntity method2 = lookupMember(elementEnvironment, 'Class.method2');
+    Expect.equals(mixin, method2.enclosingClass);
+
+    ProgramLookup lookup = new ProgramLookup(result.compiler);
+    ClassData data = lookup.getClassData(superClass);
+    Expect.isNotNull(data.getMethod(method1));
+    Expect.isNull(data.getMethod(method2));
+  });
+}
diff --git a/tests/compiler/dart2js/token_naming_test.dart b/tests/compiler/dart2js/model/token_naming_test.dart
similarity index 100%
rename from tests/compiler/dart2js/token_naming_test.dart
rename to tests/compiler/dart2js/model/token_naming_test.dart
diff --git a/tests/compiler/dart2js/model/type_substitution_test.dart b/tests/compiler/dart2js/model/type_substitution_test.dart
index 6aec923..50cc055 100644
--- a/tests/compiler/dart2js/model/type_substitution_test.dart
+++ b/tests/compiler/dart2js/model/type_substitution_test.dart
@@ -9,7 +9,7 @@
 import 'package:compiler/src/common_elements.dart';
 import 'package:compiler/src/elements/entities.dart';
 import 'package:compiler/src/elements/types.dart';
-import '../type_test_helper.dart';
+import '../helpers/type_test_helper.dart';
 
 DartType getType(ElementEnvironment elementEnvironment, String name) {
   ClassEntity cls =
diff --git a/tests/compiler/dart2js/uri_extras_test.dart b/tests/compiler/dart2js/model/uri_extras_test.dart
similarity index 100%
rename from tests/compiler/dart2js/uri_extras_test.dart
rename to tests/compiler/dart2js/model/uri_extras_test.dart
diff --git a/tests/compiler/dart2js/model/world_test.dart b/tests/compiler/dart2js/model/world_test.dart
index a4b49ce..c49ff3d 100644
--- a/tests/compiler/dart2js/model/world_test.dart
+++ b/tests/compiler/dart2js/model/world_test.dart
@@ -12,7 +12,7 @@
 import 'package:compiler/src/universe/class_hierarchy.dart';
 import 'package:compiler/src/universe/class_set.dart';
 import 'package:compiler/src/world.dart' show JClosedWorld;
-import '../type_test_helper.dart';
+import '../helpers/type_test_helper.dart';
 
 void main() {
   runTests() async {
diff --git a/tests/compiler/dart2js/rti/backend_type_helper_test.dart b/tests/compiler/dart2js/rti/backend_type_helper_test.dart
index 6bccaa8..8cf6de4 100644
--- a/tests/compiler/dart2js/rti/backend_type_helper_test.dart
+++ b/tests/compiler/dart2js/rti/backend_type_helper_test.dart
@@ -11,7 +11,7 @@
 import 'package:compiler/src/world.dart';
 import 'package:expect/expect.dart';
 import '../helpers/program_lookup.dart';
-import '../memory_compiler.dart';
+import '../helpers/memory_compiler.dart';
 
 main() {
   runTest() async {
diff --git a/tests/compiler/dart2js/rti/data/generic_methods_dynamic_05_strong.dart b/tests/compiler/dart2js/rti/data/generic_methods_dynamic_05_strong.dart
index 522514b..dcd1539 100644
--- a/tests/compiler/dart2js/rti/data/generic_methods_dynamic_05_strong.dart
+++ b/tests/compiler/dart2js/rti/data/generic_methods_dynamic_05_strong.dart
@@ -4,11 +4,11 @@
 
 // Test derived from language_2/generic_methods_dynamic_test/05
 
-/*omit.class: global#JSArray:deps=[EmptyIterable,List,ListIterable,SubListIterable],explicit=[JSArray],needsArgs*/
-/*strong.class: global#JSArray:deps=[ArrayIterator,EmptyIterable,List,ListIterable,SubListIterable],direct,explicit=[Iterable<JSArray.E>,JSArray,JSArray.E,JSArray<ArrayIterator.E>,List<JSArray.E>],implicit=[JSArray.E],needsArgs*/
+/*omit.class: global#JSArray:deps=[List],explicit=[JSArray],needsArgs*/
+/*strong.class: global#JSArray:deps=[ArrayIterator,List],direct,explicit=[JSArray,JSArray.E,JSArray<ArrayIterator.E>],implicit=[JSArray.E],needsArgs*/
 
-/*omit.class: global#List:deps=[C.bar,EmptyIterable,Iterable,JSArray,ListIterable],explicit=[List,List<B>],needsArgs*/
-/*strong.class: global#List:deps=[C.bar,EmptyIterable,Iterable,JSArray,ListIterable,makeListFixedLength],direct,explicit=[List,List.E,List<B>,List<JSArray.E>,List<String>,List<makeListFixedLength.T>],implicit=[List.E],needsArgs*/
+/*omit.class: global#List:deps=[C.bar],explicit=[List,List<B>],needsArgs*/
+/*strong.class: global#List:deps=[C.bar],explicit=[List,List<B>,List<String>],indirect,needsArgs*/
 
 import "package:expect/expect.dart";
 
diff --git a/tests/compiler/dart2js/rti/data/list_literal_strong.dart b/tests/compiler/dart2js/rti/data/list_literal_strong.dart
index c682cf3..a6d181f 100644
--- a/tests/compiler/dart2js/rti/data/list_literal_strong.dart
+++ b/tests/compiler/dart2js/rti/data/list_literal_strong.dart
@@ -2,10 +2,11 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-/*strong.class: global#List:deps=[Class.m,EmptyIterable,Iterable,JSArray,ListIterable,SetMixin,makeListFixedLength],direct,explicit=[List,List.E,List<JSArray.E>,List<String>,List<makeListFixedLength.T>],implicit=[List.E],needsArgs*/
-/*omit.class: global#List:deps=[Class.m,EmptyIterable,Iterable,JSArray,ListIterable,SetMixin],explicit=[List],implicit=[List.E],indirect,needsArgs*/
+/*strong.class: global#List:deps=[Class.m],explicit=[List,List<String>],indirect,needsArgs*/
+/*omit.class: global#List:deps=[Class.m],explicit=[List],indirect,needsArgs*/
 
-/*omit.class: global#JSArray:deps=[EmptyIterable,List,ListIterable,SetMixin,SubListIterable],explicit=[JSArray],implicit=[JSArray.E],indirect,needsArgs*/
+/*strong.class: global#JSArray:deps=[ArrayIterator,List],explicit=[JSArray,JSArray.E,JSArray<ArrayIterator.E>],implicit=[JSArray.E],indirect,needsArgs*/
+/*omit.class: global#JSArray:deps=[List],explicit=[JSArray],implicit=[JSArray.E],indirect,needsArgs*/
 
 main() {
   var c = new Class();
diff --git a/tests/compiler/dart2js/rti/data/list_to_set.dart b/tests/compiler/dart2js/rti/data/list_to_set.dart
index 60c98f7..c448ab9 100644
--- a/tests/compiler/dart2js/rti/data/list_to_set.dart
+++ b/tests/compiler/dart2js/rti/data/list_to_set.dart
@@ -2,11 +2,11 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-/*strong.class: global#List:deps=[Class,EmptyIterable,Iterable,JSArray,ListIterable,SetMixin,makeListFixedLength],direct,explicit=[List,List.E,List<JSArray.E>,List<String>,List<makeListFixedLength.T>],implicit=[List.E],needsArgs*/
-/*omit.class: global#List:deps=[Class,EmptyIterable,Iterable,JSArray,ListIterable,SetMixin],explicit=[List],implicit=[List.E],indirect,needsArgs*/
+/*strong.class: global#List:deps=[Class],explicit=[List,List<String>],indirect,needsArgs*/
+/*omit.class: global#List:deps=[Class],explicit=[List],indirect,needsArgs*/
 
-/*strong.class: global#JSArray:deps=[ArrayIterator,EmptyIterable,List,ListIterable,SetMixin,SubListIterable],explicit=[Iterable<JSArray.E>,JSArray,JSArray.E,JSArray<ArrayIterator.E>,List<JSArray.E>],implicit=[JSArray.E],indirect,needsArgs*/
-/*omit.class: global#JSArray:deps=[EmptyIterable,List,ListIterable,SetMixin,SubListIterable],explicit=[JSArray],implicit=[JSArray.E],indirect,needsArgs*/
+/*strong.class: global#JSArray:deps=[ArrayIterator,List],explicit=[JSArray,JSArray.E,JSArray<ArrayIterator.E>],implicit=[JSArray.E],indirect,needsArgs*/
+/*omit.class: global#JSArray:deps=[List],explicit=[JSArray],implicit=[JSArray.E],indirect,needsArgs*/
 
 main() {
   var c = new Class<int>();
diff --git a/tests/compiler/dart2js/rti/data/list_to_set_strong.dart b/tests/compiler/dart2js/rti/data/list_to_set_strong.dart
deleted file mode 100644
index 60c98f7..0000000
--- a/tests/compiler/dart2js/rti/data/list_to_set_strong.dart
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-/*strong.class: global#List:deps=[Class,EmptyIterable,Iterable,JSArray,ListIterable,SetMixin,makeListFixedLength],direct,explicit=[List,List.E,List<JSArray.E>,List<String>,List<makeListFixedLength.T>],implicit=[List.E],needsArgs*/
-/*omit.class: global#List:deps=[Class,EmptyIterable,Iterable,JSArray,ListIterable,SetMixin],explicit=[List],implicit=[List.E],indirect,needsArgs*/
-
-/*strong.class: global#JSArray:deps=[ArrayIterator,EmptyIterable,List,ListIterable,SetMixin,SubListIterable],explicit=[Iterable<JSArray.E>,JSArray,JSArray.E,JSArray<ArrayIterator.E>,List<JSArray.E>],implicit=[JSArray.E],indirect,needsArgs*/
-/*omit.class: global#JSArray:deps=[EmptyIterable,List,ListIterable,SetMixin,SubListIterable],explicit=[JSArray],implicit=[JSArray.E],indirect,needsArgs*/
-
-main() {
-  var c = new Class<int>();
-  var list = c.m();
-  var set = list.toSet();
-  set is Set<String>;
-}
-
-/*class: Class:implicit=[Class.T],indirect,needsArgs*/
-class Class<T> {
-  m() {
-    return <T>[];
-  }
-}
diff --git a/tests/compiler/dart2js/rti/data/local_function_list_literal_strong.dart b/tests/compiler/dart2js/rti/data/local_function_list_literal_strong.dart
index c6f518c..d58058e 100644
--- a/tests/compiler/dart2js/rti/data/local_function_list_literal_strong.dart
+++ b/tests/compiler/dart2js/rti/data/local_function_list_literal_strong.dart
@@ -4,8 +4,8 @@
 
 import 'package:expect/expect.dart';
 
-/*strong.class: global#JSArray:deps=[ArrayIterator,EmptyIterable,List,ListIterable,SubListIterable],direct,explicit=[Iterable<JSArray.E>,JSArray,JSArray.E,JSArray<ArrayIterator.E>,List<JSArray.E>],implicit=[JSArray.E],needsArgs*/
-/*omit.class: global#JSArray:deps=[EmptyIterable,List,ListIterable,SubListIterable],explicit=[JSArray],needsArgs*/
+/*strong.class: global#JSArray:deps=[ArrayIterator,List],direct,explicit=[JSArray,JSArray.E,JSArray<ArrayIterator.E>],implicit=[JSArray.E],needsArgs*/
+/*omit.class: global#JSArray:deps=[List],explicit=[JSArray],needsArgs*/
 
 /*strong.element: method:implicit=[method.T],indirect,needsArgs*/
 /*omit.element: method:needsArgs*/
diff --git a/tests/compiler/dart2js/rti/data/map_to_set.dart b/tests/compiler/dart2js/rti/data/map_to_set.dart
index 80569bd..28e5bf2 100644
--- a/tests/compiler/dart2js/rti/data/map_to_set.dart
+++ b/tests/compiler/dart2js/rti/data/map_to_set.dart
@@ -3,13 +3,13 @@
 // BSD-style license that can be found in the LICENSE file.
 
 /*omit.class: global#Map:deps=[Class],needsArgs*/
-/*strong.class: global#Map:deps=[Class,JsLinkedHashMap,MapMixin],explicit=[Map,Map<JsLinkedHashMap.K,JsLinkedHashMap.V>,Map<MapMixin.K,MapMixin.V>],indirect,needsArgs*/
+/*strong.class: global#Map:deps=[Class],explicit=[Map],indirect,needsArgs*/
 
 /*omit.class: global#LinkedHashMap:deps=[Map],needsArgs*/
 /*strong.class: global#LinkedHashMap:deps=[Map],direct,explicit=[LinkedHashMap<LinkedHashMap.K,LinkedHashMap.V>],implicit=[LinkedHashMap.K,LinkedHashMap.V],needsArgs*/
 
 /*omit.class: global#JsLinkedHashMap:deps=[LinkedHashMap],implicit=[JsLinkedHashMap.K],needsArgs*/
-/*strong.class: global#JsLinkedHashMap:deps=[LinkedHashMap],explicit=[JsLinkedHashMap.K,JsLinkedHashMap.V,Map<JsLinkedHashMap.K,JsLinkedHashMap.V>,void Function(JsLinkedHashMap.K,JsLinkedHashMap.V)],implicit=[JsLinkedHashMap.K,JsLinkedHashMap.V],indirect,needsArgs*/
+/*strong.class: global#JsLinkedHashMap:deps=[LinkedHashMap],direct,explicit=[JsLinkedHashMap.K,JsLinkedHashMap.V,void Function(JsLinkedHashMap.K,JsLinkedHashMap.V)],implicit=[JsLinkedHashMap.K,JsLinkedHashMap.V],needsArgs*/
 
 /*omit.class: global#double:explicit=[double]*/
 /*strong.class: global#double:explicit=[double],implicit=[double]*/
diff --git a/tests/compiler/dart2js/rti/data/map_to_set_strong.dart b/tests/compiler/dart2js/rti/data/map_to_set_strong.dart
deleted file mode 100644
index 89dfbbe..0000000
--- a/tests/compiler/dart2js/rti/data/map_to_set_strong.dart
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-/*strong.class: global#Map:deps=[Class,JsLinkedHashMap,MapMixin],explicit=[Map,Map<JsLinkedHashMap.K,JsLinkedHashMap.V>,Map<MapMixin.K,MapMixin.V>],indirect,needsArgs*/
-/*omit.class: global#Map:deps=[Class],needsArgs*/
-
-/*strong.class: global#LinkedHashMap:deps=[Map],direct,explicit=[LinkedHashMap<LinkedHashMap.K,LinkedHashMap.V>],implicit=[LinkedHashMap.K,LinkedHashMap.V],needsArgs*/
-/*omit.class: global#LinkedHashMap:deps=[Map],needsArgs*/
-
-/*strong.class: global#JsLinkedHashMap:deps=[LinkedHashMap],explicit=[JsLinkedHashMap.K,JsLinkedHashMap.V,Map<JsLinkedHashMap.K,JsLinkedHashMap.V>,void Function(JsLinkedHashMap.K,JsLinkedHashMap.V)],implicit=[JsLinkedHashMap.K,JsLinkedHashMap.V],indirect,needsArgs*/
-/*omit.class: global#JsLinkedHashMap:deps=[LinkedHashMap],implicit=[JsLinkedHashMap.K],needsArgs*/
-
-/*strong.class: global#double:explicit=[double],implicit=[double]*/
-/*omit.class: global#double:explicit=[double]*/
-
-/*class: global#JSDouble:*/
-
-main() {
-  var c = new Class<double, int>();
-  var map = c.m();
-  var set = map.keys.toSet();
-  set is Set<String>;
-}
-
-/*strong.class: Class:implicit=[Class.S,Class.T],indirect,needsArgs*/
-/*omit.class: Class:needsArgs*/
-class Class<T, S> {
-  m() {
-    return <T, S>{};
-  }
-}
diff --git a/tests/compiler/dart2js/rti/disable_rti_test.dart b/tests/compiler/dart2js/rti/disable_rti_test.dart
index 0c52e5e..b933aad 100644
--- a/tests/compiler/dart2js/rti/disable_rti_test.dart
+++ b/tests/compiler/dart2js/rti/disable_rti_test.dart
@@ -12,7 +12,7 @@
 import 'package:compiler/src/world.dart';
 import 'package:expect/expect.dart';
 import '../helpers/program_lookup.dart';
-import '../memory_compiler.dart';
+import '../helpers/memory_compiler.dart';
 
 const String code = '''
 class A {}
diff --git a/tests/compiler/dart2js/rti/factory_call_test.dart b/tests/compiler/dart2js/rti/factory_call_test.dart
index 6524254..9430101 100644
--- a/tests/compiler/dart2js/rti/factory_call_test.dart
+++ b/tests/compiler/dart2js/rti/factory_call_test.dart
@@ -12,7 +12,7 @@
 import 'package:compiler/src/world.dart';
 import 'package:expect/expect.dart';
 import '../helpers/program_lookup.dart';
-import '../memory_compiler.dart';
+import '../helpers/memory_compiler.dart';
 
 const String code = '''
 import 'package:meta/dart2js.dart';
diff --git a/tests/compiler/dart2js/rti/instance_call_test.dart b/tests/compiler/dart2js/rti/instance_call_test.dart
index 1a547de..d219c0f 100644
--- a/tests/compiler/dart2js/rti/instance_call_test.dart
+++ b/tests/compiler/dart2js/rti/instance_call_test.dart
@@ -16,7 +16,7 @@
 import 'package:compiler/src/universe/selector.dart';
 import 'package:expect/expect.dart';
 import '../helpers/program_lookup.dart';
-import '../memory_compiler.dart';
+import '../helpers/memory_compiler.dart';
 
 const String code = '''
 import 'package:meta/dart2js.dart';
diff --git a/tests/compiler/dart2js/is_test_with_type_parameters_test.dart b/tests/compiler/dart2js/rti/is_test_with_type_parameters_test.dart
similarity index 100%
rename from tests/compiler/dart2js/is_test_with_type_parameters_test.dart
rename to tests/compiler/dart2js/rti/is_test_with_type_parameters_test.dart
diff --git a/tests/compiler/dart2js/rti/rti_emission_test.dart b/tests/compiler/dart2js/rti/rti_emission_test.dart
index b925439..84a206c 100644
--- a/tests/compiler/dart2js/rti/rti_emission_test.dart
+++ b/tests/compiler/dart2js/rti/rti_emission_test.dart
@@ -9,10 +9,12 @@
 import 'package:compiler/src/compiler.dart';
 import 'package:compiler/src/diagnostics/diagnostic_listener.dart';
 import 'package:compiler/src/elements/entities.dart';
+import 'package:compiler/src/ir/util.dart';
 import 'package:compiler/src/js_backend/runtime_types.dart';
 import 'package:compiler/src/js_emitter/model.dart';
+import 'package:compiler/src/js_model/element_map.dart';
+import 'package:compiler/src/js_model/js_strategy.dart';
 import 'package:compiler/src/kernel/element_map.dart';
-import 'package:compiler/src/kernel/kernel_backend_strategy.dart';
 import 'package:kernel/ast.dart' as ir;
 import '../equivalence/id_equivalence.dart';
 import '../equivalence/id_equivalence_helper.dart';
@@ -20,7 +22,6 @@
 
 main(List<String> args) {
   asyncTest(() async {
-    cacheRtiDataForTesting = true;
     Directory dataDir =
         new Directory.fromUri(Platform.script.resolve('emission'));
     await checkTests(dataDir, const RtiEmissionDataComputer(),
@@ -91,19 +92,14 @@
   const RtiEmissionDataComputer();
 
   @override
-  void setup() {
-    cacheRtiDataForTesting = true;
-  }
-
-  @override
   bool get computesClassData => true;
 
   @override
   void computeMemberData(
       Compiler compiler, MemberEntity member, Map<Id, ActualData> actualMap,
       {bool verbose: false}) {
-    KernelBackendStrategy backendStrategy = compiler.backendStrategy;
-    KernelToElementMapForBuilding elementMap = backendStrategy.elementMap;
+    JsBackendStrategy backendStrategy = compiler.backendStrategy;
+    JsToElementMap elementMap = backendStrategy.elementMap;
     MemberDefinition definition = elementMap.getMemberDefinition(member);
     new RtiMemberEmissionIrComputer(compiler.reporter, actualMap, elementMap,
             member, compiler, backendStrategy.closureDataLookup)
@@ -114,8 +110,8 @@
   void computeClassData(
       Compiler compiler, ClassEntity cls, Map<Id, ActualData> actualMap,
       {bool verbose: false}) {
-    KernelBackendStrategy backendStrategy = compiler.backendStrategy;
-    KernelToElementMapForBuilding elementMap = backendStrategy.elementMap;
+    JsBackendStrategy backendStrategy = compiler.backendStrategy;
+    JsToElementMap elementMap = backendStrategy.elementMap;
     new RtiClassEmissionIrComputer(compiler, elementMap, actualMap)
         .computeClassValue(cls);
   }
@@ -123,7 +119,7 @@
 
 class RtiClassEmissionIrComputer extends DataRegistry with ComputeValueMixin {
   final Compiler compiler;
-  final KernelToElementMapForBuilding _elementMap;
+  final JsToElementMap _elementMap;
   final Map<Id, ActualData> actualMap;
 
   RtiClassEmissionIrComputer(this.compiler, this._elementMap, this.actualMap);
@@ -140,7 +136,7 @@
 
 class RtiMemberEmissionIrComputer extends IrDataExtractor
     with ComputeValueMixin {
-  final KernelToElementMapForBuilding _elementMap;
+  final JsToElementMap _elementMap;
   final ClosureDataLookup _closureDataLookup;
   final Compiler compiler;
 
diff --git a/tests/compiler/dart2js/rti/rti_need_test_helper.dart b/tests/compiler/dart2js/rti/rti_need_test_helper.dart
index b90042e..95d5fd1 100644
--- a/tests/compiler/dart2js/rti/rti_need_test_helper.dart
+++ b/tests/compiler/dart2js/rti/rti_need_test_helper.dart
@@ -11,9 +11,11 @@
 import 'package:compiler/src/diagnostics/diagnostic_listener.dart';
 import 'package:compiler/src/elements/entities.dart';
 import 'package:compiler/src/elements/types.dart';
+import 'package:compiler/src/ir/util.dart';
 import 'package:compiler/src/js_backend/runtime_types.dart';
+import 'package:compiler/src/js_model/js_strategy.dart';
+import 'package:compiler/src/js_model/element_map.dart';
 import 'package:compiler/src/kernel/element_map.dart';
-import 'package:compiler/src/kernel/kernel_backend_strategy.dart';
 import 'package:compiler/src/kernel/kernel_strategy.dart';
 import 'package:compiler/src/universe/feature.dart';
 import 'package:compiler/src/universe/selector.dart';
@@ -28,7 +30,6 @@
 }
 
 runTests(List<String> args, [int shardIndex]) {
-  cacheRtiDataForTesting = true;
   asyncTest(() async {
     Directory dataDir = new Directory.fromUri(Platform.script.resolve('data'));
     await checkTests(dataDir, const RtiNeedDataComputer(),
@@ -233,11 +234,6 @@
   const RtiNeedDataComputer();
 
   @override
-  void setup() {
-    cacheRtiDataForTesting = true;
-  }
-
-  @override
   bool get computesClassData => true;
 
   /// Compute RTI need data for [member] from the new frontend.
@@ -247,8 +243,8 @@
   void computeMemberData(
       Compiler compiler, MemberEntity member, Map<Id, ActualData> actualMap,
       {bool verbose: false}) {
-    KernelBackendStrategy backendStrategy = compiler.backendStrategy;
-    KernelToElementMapForBuilding elementMap = backendStrategy.elementMap;
+    JsBackendStrategy backendStrategy = compiler.backendStrategy;
+    JsToElementMap elementMap = backendStrategy.elementMap;
     MemberDefinition definition = elementMap.getMemberDefinition(member);
     new RtiMemberNeedIrComputer(compiler.reporter, actualMap, elementMap,
             member, compiler, backendStrategy.closureDataLookup)
@@ -262,8 +258,8 @@
   void computeClassData(
       Compiler compiler, ClassEntity cls, Map<Id, ActualData> actualMap,
       {bool verbose: false}) {
-    KernelBackendStrategy backendStrategy = compiler.backendStrategy;
-    KernelToElementMapForBuilding elementMap = backendStrategy.elementMap;
+    JsBackendStrategy backendStrategy = compiler.backendStrategy;
+    JsToElementMap elementMap = backendStrategy.elementMap;
     new RtiClassNeedIrComputer(compiler, elementMap, actualMap)
         .computeClassValue(cls);
   }
@@ -306,12 +302,11 @@
 
   @override
   Local getFrontendClosure(MemberEntity member) {
-    KernelBackendStrategy backendStrategy = compiler.backendStrategy;
+    JsBackendStrategy backendStrategy = compiler.backendStrategy;
     ir.Node node = backendStrategy.elementMap.getMemberDefinition(member).node;
     if (node is ir.FunctionDeclaration || node is ir.FunctionExpression) {
       KernelFrontEndStrategy frontendStrategy = compiler.frontendStrategy;
-      KernelToElementMapForImpact frontendElementMap =
-          frontendStrategy.elementMap;
+      KernelToElementMap frontendElementMap = frontendStrategy.elementMap;
       return frontendElementMap.getLocalFunction(node);
     }
     return null;
@@ -321,7 +316,7 @@
 class RtiClassNeedIrComputer extends DataRegistry
     with ComputeValueMixin, IrMixin {
   final Compiler compiler;
-  final KernelToElementMapForBuilding _elementMap;
+  final JsToElementMap _elementMap;
   final Map<Id, ActualData> actualMap;
 
   RtiClassNeedIrComputer(this.compiler, this._elementMap, this.actualMap);
@@ -339,7 +334,7 @@
 /// AST visitor for computing inference data for a member.
 class RtiMemberNeedIrComputer extends IrDataExtractor
     with ComputeValueMixin, IrMixin {
-  final KernelToElementMapForBuilding _elementMap;
+  final JsToElementMap _elementMap;
   final ClosureDataLookup _closureDataLookup;
   final Compiler compiler;
 
diff --git a/tests/compiler/dart2js/rti/runtime_type_hint_test.dart b/tests/compiler/dart2js/rti/runtime_type_hint_test.dart
index 98af71d..e7f7829 100644
--- a/tests/compiler/dart2js/rti/runtime_type_hint_test.dart
+++ b/tests/compiler/dart2js/rti/runtime_type_hint_test.dart
@@ -7,7 +7,7 @@
 import 'package:compiler/src/diagnostics/messages.dart';
 import 'package:expect/expect.dart';
 
-import '../memory_compiler.dart';
+import '../helpers/memory_compiler.dart';
 
 test(String code, List<String> options, List<MessageKind> expectedHints) async {
   DiagnosticCollector collector = new DiagnosticCollector();
diff --git a/tests/compiler/dart2js/rti/type_representation_test.dart b/tests/compiler/dart2js/rti/type_representation_test.dart
index 51a06d3..d93fab1 100644
--- a/tests/compiler/dart2js/rti/type_representation_test.dart
+++ b/tests/compiler/dart2js/rti/type_representation_test.dart
@@ -18,8 +18,8 @@
 import 'package:compiler/src/world.dart';
 import 'package:expect/expect.dart';
 import '../helpers/element_lookup.dart';
-import '../memory_compiler.dart';
-import '../type_test_helper.dart';
+import '../helpers/memory_compiler.dart';
+import '../helpers/type_test_helper.dart';
 
 void main() {
   asyncTest(() async {
diff --git a/tests/compiler/dart2js/sourcemaps/helpers/sourcemap_helper.dart b/tests/compiler/dart2js/sourcemaps/helpers/sourcemap_helper.dart
index 270e686..e17247a 100644
--- a/tests/compiler/dart2js/sourcemaps/helpers/sourcemap_helper.dart
+++ b/tests/compiler/dart2js/sourcemaps/helpers/sourcemap_helper.dart
@@ -19,8 +19,8 @@
 import 'package:compiler/src/js/js_source_mapping.dart';
 import 'package:compiler/src/js_backend/js_backend.dart';
 import 'package:compiler/src/source_file_provider.dart';
-import '../../memory_compiler.dart';
-import '../../output_collector.dart';
+import '../../helpers/memory_compiler.dart';
+import '../../helpers/output_collector.dart';
 
 class SourceFileSink implements OutputSink {
   final String filename;
diff --git a/tests/compiler/dart2js/sourcemaps/location_collector_test.dart b/tests/compiler/dart2js/sourcemaps/location_collector_test.dart
index 375f5b2..b5ebf2a 100644
--- a/tests/compiler/dart2js/sourcemaps/location_collector_test.dart
+++ b/tests/compiler/dart2js/sourcemaps/location_collector_test.dart
@@ -9,7 +9,7 @@
 import 'package:expect/expect.dart';
 import 'package:kernel/ast.dart' show Location;
 
-import '../output_collector.dart';
+import '../helpers/output_collector.dart';
 
 test(List events, Map<int, List<int>> expectedPositions) {
   BufferedOutputSink sink = new BufferedOutputSink();
diff --git a/tests/compiler/dart2js/sourcemaps/mapping_test.dart b/tests/compiler/dart2js/sourcemaps/mapping_test.dart
index ffc05ca..a69f0a6 100644
--- a/tests/compiler/dart2js/sourcemaps/mapping_test.dart
+++ b/tests/compiler/dart2js/sourcemaps/mapping_test.dart
@@ -11,7 +11,7 @@
 import 'package:source_maps/source_maps.dart';
 import 'package:sourcemap_testing/src/annotated_code_helper.dart';
 
-import '../memory_compiler.dart';
+import '../helpers/memory_compiler.dart';
 
 const List<String> TESTS = const <String>[
   '''
diff --git a/tests/compiler/dart2js/sourcemaps/name_test.dart b/tests/compiler/dart2js/sourcemaps/name_test.dart
index e1340d7..257458e 100644
--- a/tests/compiler/dart2js/sourcemaps/name_test.dart
+++ b/tests/compiler/dart2js/sourcemaps/name_test.dart
@@ -10,8 +10,8 @@
 import 'package:compiler/src/compiler.dart';
 import 'package:compiler/src/elements/entities.dart';
 import 'package:compiler/src/io/kernel_source_information.dart';
-import 'package:compiler/src/kernel/kernel_backend_strategy.dart';
-import '../memory_compiler.dart';
+import 'package:compiler/src/js_model/js_strategy.dart';
+import '../helpers/memory_compiler.dart';
 
 const String SOURCE = '''
 
@@ -79,7 +79,7 @@
         memorySourceFiles: {'main.dart': SOURCE},
         options: [Flags.disableInlining]);
     Compiler compiler = result.compiler;
-    KernelBackendStrategy backendStrategy = compiler.backendStrategy;
+    JsBackendStrategy backendStrategy = compiler.backendStrategy;
     var env = compiler.backendClosedWorldForTesting.elementEnvironment;
     LibraryEntity mainApp = env.mainLibrary;
 
diff --git a/tests/compiler/dart2js/sourcemaps/nomapping_test.dart b/tests/compiler/dart2js/sourcemaps/nomapping_test.dart
index 04b493d..b38c1c6 100644
--- a/tests/compiler/dart2js/sourcemaps/nomapping_test.dart
+++ b/tests/compiler/dart2js/sourcemaps/nomapping_test.dart
@@ -11,7 +11,7 @@
 import 'package:expect/expect.dart';
 import 'package:source_maps/source_maps.dart';
 
-import '../memory_compiler.dart';
+import '../helpers/memory_compiler.dart';
 
 const List<String> TESTS = const <String>[
   '''
diff --git a/tests/compiler/dart2js/sourcemaps/source_map_test.dart b/tests/compiler/dart2js/sourcemaps/source_map_test.dart
index a062acf..ddb75bf 100644
--- a/tests/compiler/dart2js/sourcemaps/source_map_test.dart
+++ b/tests/compiler/dart2js/sourcemaps/source_map_test.dart
@@ -10,7 +10,7 @@
 import 'package:async_helper/async_helper.dart';
 import 'package:compiler/compiler_new.dart';
 import 'package:expect/expect.dart';
-import '../memory_compiler.dart';
+import '../helpers/memory_compiler.dart';
 
 const SOURCE = const {
   '/main.dart': """
diff --git a/tests/compiler/dart2js_extra/dart2js_extra.status b/tests/compiler/dart2js_extra/dart2js_extra.status
index 4e25eef..2e6c022 100644
--- a/tests/compiler/dart2js_extra/dart2js_extra.status
+++ b/tests/compiler/dart2js_extra/dart2js_extra.status
@@ -23,8 +23,14 @@
 jsinterop_test/37: MissingCompileTimeError # Issue 33834
 jsinterop_test/38: MissingCompileTimeError # Issue 34174
 jsinterop_test/42: MissingCompileTimeError # Issue 34174
+jsinterop_test/43: MissingCompileTimeError # Issue 34345
+jsinterop_test/44: MissingCompileTimeError # Issue 34345
+jsinterop_test/45: MissingCompileTimeError # Issue 34345
 jsinterop_test/46: MissingCompileTimeError # Issue 34174
 jsinterop_test/51: MissingCompileTimeError # Issue 34174
+jsinterop_test/52: MissingCompileTimeError # Issue 34345
+jsinterop_test/53: MissingCompileTimeError # Issue 34345
+jsinterop_test/54: MissingCompileTimeError # Issue 34345
 many_instantiations_test/01: Crash # Issue 33819
 no_such_method_test: Fail # Wrong Invocation.memberName.
 non_jsinterop_test/01: MissingCompileTimeError # Issue 34174
@@ -37,8 +43,14 @@
 non_jsinterop_test/37: MissingCompileTimeError # Issue 33834
 non_jsinterop_test/38: MissingCompileTimeError # Issue 34174
 non_jsinterop_test/42: MissingCompileTimeError # Issue 34174
+non_jsinterop_test/43: MissingCompileTimeError # Issue 34345
+non_jsinterop_test/44: MissingCompileTimeError # Issue 34345
+non_jsinterop_test/45: MissingCompileTimeError # Issue 34345
 non_jsinterop_test/46: MissingCompileTimeError # Issue 34174
 non_jsinterop_test/51: MissingCompileTimeError # Issue 34174
+non_jsinterop_test/52: MissingCompileTimeError # Issue 34345
+non_jsinterop_test/53: MissingCompileTimeError # Issue 34345
+non_jsinterop_test/54: MissingCompileTimeError # Issue 34345
 private_symbol_literal_test/01: MissingCompileTimeError
 private_symbol_literal_test/02: MissingCompileTimeError
 private_symbol_literal_test/03: MissingCompileTimeError
diff --git a/tests/compiler/dart2js_extra/js_interop_implements_test.dart b/tests/compiler/dart2js_extra/js_interop_implements_test.dart
new file mode 100644
index 0000000..a4c8a72
--- /dev/null
+++ b/tests/compiler/dart2js_extra/js_interop_implements_test.dart
@@ -0,0 +1,37 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test that methods implemented (not extended) in js-interop classes are still
+// considered live.
+
+@JS()
+library anonymous_js_test;
+
+import 'package:js/js.dart';
+
+@JS()
+@anonymous
+abstract class A {
+  external factory A();
+  external String get a;
+  external set a(String a);
+}
+
+@JS()
+@anonymous
+abstract class B implements A {
+  external factory B();
+  external String get b;
+  external set b(String b);
+}
+
+void main() {
+  final b = B();
+  // This setter is missing if we don't assume the receiver could be an
+  // unknown but concrete implementation of A.
+  b.a = 'Hi';
+  b.b = 'Hello';
+  if (b.a != 'Hi') throw 'b.a';
+  if (b.b != 'Hello') throw 'b.b';
+}
diff --git a/tests/compiler/dart2js_extra/jsinterop_test.dart b/tests/compiler/dart2js_extra/jsinterop_test.dart
index 7c3c719..f689269 100644
--- a/tests/compiler/dart2js_extra/jsinterop_test.dart
+++ b/tests/compiler/dart2js_extra/jsinterop_test.dart
@@ -76,9 +76,9 @@
   instanceMethod() {}
 
   static var staticField;
-  get staticGetter => null;
-  set staticSetter(_) {}
-  staticMethod() {}
+  static get staticGetter => null;
+  static set staticSetter(_) {}
+  static staticMethod() {}
 
   @JS('a') // JS_INTEROP_MEMBER_IN_NON_JS_INTEROP_CLASS  //# 14: compile-time error
   var instanceJsInteropField; //# 14: continued
@@ -96,13 +96,13 @@
   static var staticJsInteropField; //# 18: continued
 
   @JS('a') // JS_INTEROP_MEMBER_IN_NON_JS_INTEROP_CLASS  //# 19: compile-time error
-  get staticJsInteropGetter => null; //# 19: continued
+  static get staticJsInteropGetter => null; //# 19: continued
 
   @JS('a') // JS_INTEROP_MEMBER_IN_NON_JS_INTEROP_CLASS  //# 20: compile-time error
-  set staticJsInteropSetter(_) {} //# 20: continued
+  static set staticJsInteropSetter(_) {} //# 20: continued
 
   @JS('a') // JS_INTEROP_MEMBER_IN_NON_JS_INTEROP_CLASS  //# 21: compile-time error
-  staticJsInteropMethod() {} //# 21: continued
+  static staticJsInteropMethod() {} //# 21: continued
 
   // NON_NATIVE_EXTERNAL               //# 22: compile-time error
   external get externalInstanceGetter; //# 22: continued
@@ -114,13 +114,13 @@
   external externalInstanceMethod(); //# 24: continued
 
   // NON_NATIVE_EXTERNAL             //# 25: compile-time error
-  external get externalStaticGetter; //# 25: continued
+  external static get externalStaticGetter; //# 25: continued
 
   // NON_NATIVE_EXTERNAL                //# 26: compile-time error
-  external set externalStaticSetter(_); //# 26: continued
+  external static set externalStaticSetter(_); //# 26: continued
 
   // NON_NATIVE_EXTERNAL           //# 27: compile-time error
-  external externalStaticMethod(); //# 27: continued
+  external static externalStaticMethod(); //# 27: continued
 
   @JS('a') // JS_INTEROP_MEMBER_IN_NON_JS_INTEROP_CLASS  //# 28: compile-time error
   external get externalInstanceJsInteropGetter; //# 28: continued
@@ -132,13 +132,13 @@
   external externalInstanceJsInteropMethod(); //# 30: continued
 
   @JS('a') // JS_INTEROP_MEMBER_IN_NON_JS_INTEROP_CLASS  //# 31: compile-time error
-  external get externalStaticJsInteropGetter; //# 31: continued
+  external static get externalStaticJsInteropGetter; //# 31: continued
 
   @JS('a') // JS_INTEROP_MEMBER_IN_NON_JS_INTEROP_CLASS  //# 32: compile-time error
-  external set externalStaticJsInteropSetter(_); //# 32: continued
+  external static set externalStaticJsInteropSetter(_); //# 32: continued
 
   @JS('a') // JS_INTEROP_MEMBER_IN_NON_JS_INTEROP_CLASS  //# 33: compile-time error
-  external externalStaticJsInteropMethod(); //# 33: continued
+  external static externalStaticJsInteropMethod(); //# 33: continued
 }
 
 @JS('d')
@@ -180,13 +180,13 @@
   static var staticField; //# 42: continued
 
   // JS_INTEROP_CLASS_NON_EXTERNAL_MEMBER //# 43: compile-time error
-  get staticGetter => null; //# 43: continued
+  static get staticGetter => null; //# 43: continued
 
   // JS_INTEROP_CLASS_NON_EXTERNAL_MEMBER //# 44: compile-time error
-  set staticSetter(_) {} //# 44: continued
+  static set staticSetter(_) {} //# 44: continued
 
   // JS_INTEROP_CLASS_NON_EXTERNAL_MEMBER //# 45: compile-time error
-  staticMethod() {} //# 45: continued
+  static staticMethod() {} //# 45: continued
 
   @JS('a') // IMPLICIT_JS_INTEROP_FIELD_NOT_SUPPORTED //# 46: compile-time error
   var instanceJsInteropField; //# 46: continued
@@ -204,21 +204,21 @@
   static var staticJsInteropField; //# 51: continued
 
   @JS('a') // JS_INTEROP_CLASS_NON_EXTERNAL_MEMBER //# 52: compile-time error
-  get staticJsInteropGetter => null; //# 52: continued
+  static get staticJsInteropGetter => null; //# 52: continued
 
   @JS('a') // JS_INTEROP_CLASS_NON_EXTERNAL_MEMBER //# 53: compile-time error
-  set staticJsInteropSetter(_) {} //# 53: continued
+  static set staticJsInteropSetter(_) {} //# 53: continued
 
   @JS('a') // JS_INTEROP_CLASS_NON_EXTERNAL_MEMBER //# 54: compile-time error
-  staticJsInteropMethod() {} //# 54: continued
+  static staticJsInteropMethod() {} //# 54: continued
 
   external get externalInstanceGetter;
   external set externalInstanceSetter(_);
   external externalInstanceMethod();
 
-  external get externalStaticGetter;
-  external set externalStaticSetter(_);
-  external externalStaticMethod();
+  external static get externalStaticGetter;
+  external static set externalStaticSetter(_);
+  external static externalStaticMethod();
 
   @JS('a')
   external get externalInstanceJsInteropGetter;
@@ -230,13 +230,41 @@
   external externalInstanceJsInteropMethod();
 
   @JS('a')
-  external get externalStaticJsInteropGetter;
+  external static get externalStaticJsInteropGetter;
 
   @JS('a')
-  external set externalStaticJsInteropSetter(_);
+  external static set externalStaticJsInteropSetter(_);
 
   @JS('a')
-  external externalStaticJsInteropMethod();
+  external static externalStaticJsInteropMethod();
 }
 
-main() {}
+main() {
+  if (false) {
+    topLevelSetter = topLevelField = topLevelGetter;
+    topLevelFunction();
+    externalTopLevelSetter = externalTopLevelGetter;
+    externalTopLevelFunction();
+    externalTopLevelJsInteropSetter = externalTopLevelJsInteropGetter;
+    externalTopLevelJsInteropFunction();
+    Class c1 = new Class.generative();
+    new Class.fact();
+    c1.instanceSetter = c1.instanceField = c1.instanceGetter;
+    c1.instanceMethod();
+    Class.staticSetter = Class.staticField = Class.staticGetter;
+    Class.staticMethod();
+    JsInteropClass c2 = new JsInteropClass.externalGenerative();
+    new JsInteropClass.externalFact();
+    new JsInteropClass.externalJsInteropGenerative();
+    new JsInteropClass.externalJsInteropFact();
+    c2.externalInstanceSetter = c2.externalInstanceGetter;
+    c2.externalInstanceMethod();
+    c2.externalInstanceJsInteropSetter = c2.externalInstanceJsInteropGetter;
+    c2.externalInstanceJsInteropMethod();
+    JsInteropClass.externalStaticSetter = JsInteropClass.externalStaticGetter;
+    JsInteropClass.externalStaticMethod();
+    JsInteropClass.externalStaticJsInteropSetter =
+        JsInteropClass.externalStaticJsInteropGetter;
+    JsInteropClass.externalStaticJsInteropMethod();
+  }
+}
diff --git a/tests/compiler/dart2js_extra/non_jsinterop_test.dart b/tests/compiler/dart2js_extra/non_jsinterop_test.dart
index f676126..d4cd22c 100644
--- a/tests/compiler/dart2js_extra/non_jsinterop_test.dart
+++ b/tests/compiler/dart2js_extra/non_jsinterop_test.dart
@@ -78,9 +78,9 @@
   instanceMethod() {}
 
   static var staticField;
-  get staticGetter => null;
-  set staticSetter(_) {}
-  staticMethod() {}
+  static get staticGetter => null;
+  static set staticSetter(_) {}
+  static staticMethod() {}
 
   @JS('a') // JS_INTEROP_MEMBER_IN_NON_JS_INTEROP_CLASS  //# 14: compile-time error
   var instanceJsInteropField; //# 14: continued
@@ -98,13 +98,13 @@
   static var staticJsInteropField; //# 18: continued
 
   @JS('a') // JS_INTEROP_MEMBER_IN_NON_JS_INTEROP_CLASS  //# 19: compile-time error
-  get staticJsInteropGetter => null; //# 19: continued
+  static get staticJsInteropGetter => null; //# 19: continued
 
   @JS('a') // JS_INTEROP_MEMBER_IN_NON_JS_INTEROP_CLASS  //# 20: compile-time error
-  set staticJsInteropSetter(_) {} //# 20: continued
+  static set staticJsInteropSetter(_) {} //# 20: continued
 
   @JS('a') // JS_INTEROP_MEMBER_IN_NON_JS_INTEROP_CLASS  //# 21: compile-time error
-  staticJsInteropMethod() {} //# 21: continued
+  static staticJsInteropMethod() {} //# 21: continued
 
   // NON_NATIVE_EXTERNAL               //# 22: compile-time error
   external get externalInstanceGetter; //# 22: continued
@@ -116,13 +116,13 @@
   external externalInstanceMethod(); //# 24: continued
 
   // NON_NATIVE_EXTERNAL             //# 25: compile-time error
-  external get externalStaticGetter; //# 25: continued
+  external static get externalStaticGetter; //# 25: continued
 
   // NON_NATIVE_EXTERNAL                //# 26: compile-time error
-  external set externalStaticSetter(_); //# 26: continued
+  external static set externalStaticSetter(_); //# 26: continued
 
   // NON_NATIVE_EXTERNAL           //# 27: compile-time error
-  external externalStaticMethod(); //# 27: continued
+  external static externalStaticMethod(); //# 27: continued
 
   @JS('a') // JS_INTEROP_MEMBER_IN_NON_JS_INTEROP_CLASS  //# 28: compile-time error
   external get externalInstanceJsInteropGetter; //# 28: continued
@@ -134,13 +134,13 @@
   external externalInstanceJsInteropMethod(); //# 30: continued
 
   @JS('a') // JS_INTEROP_MEMBER_IN_NON_JS_INTEROP_CLASS  //# 31: compile-time error
-  external get externalStaticJsInteropGetter; //# 31: continued
+  external static get externalStaticJsInteropGetter; //# 31: continued
 
   @JS('a') // JS_INTEROP_MEMBER_IN_NON_JS_INTEROP_CLASS  //# 32: compile-time error
-  external set externalStaticJsInteropSetter(_); //# 32: continued
+  external static set externalStaticJsInteropSetter(_); //# 32: continued
 
   @JS('a') // JS_INTEROP_MEMBER_IN_NON_JS_INTEROP_CLASS  //# 33: compile-time error
-  external externalStaticJsInteropMethod(); //# 33: continued
+  external static externalStaticJsInteropMethod(); //# 33: continued
 }
 
 @JS('d')
@@ -182,13 +182,13 @@
   static var staticField; //# 42: continued
 
   // JS_INTEROP_CLASS_NON_EXTERNAL_MEMBER //# 43: compile-time error
-  get staticGetter => null; //# 43: continued
+  static get staticGetter => null; //# 43: continued
 
   // JS_INTEROP_CLASS_NON_EXTERNAL_MEMBER //# 44: compile-time error
-  set staticSetter(_) {} //# 44: continued
+  static set staticSetter(_) {} //# 44: continued
 
   // JS_INTEROP_CLASS_NON_EXTERNAL_MEMBER //# 45: compile-time error
-  staticMethod() {} //# 45: continued
+  static staticMethod() {} //# 45: continued
 
   @JS('a') // IMPLICIT_JS_INTEROP_FIELD_NOT_SUPPORTED //# 46: compile-time error
   var instanceJsInteropField; //# 46: continued
@@ -206,21 +206,21 @@
   static var staticJsInteropField; //# 51: continued
 
   @JS('a') // JS_INTEROP_CLASS_NON_EXTERNAL_MEMBER //# 52: compile-time error
-  get staticJsInteropGetter => null; //# 52: continued
+  static get staticJsInteropGetter => null; //# 52: continued
 
   @JS('a') // JS_INTEROP_CLASS_NON_EXTERNAL_MEMBER //# 53: compile-time error
-  set staticJsInteropSetter(_) {} //# 53: continued
+  static set staticJsInteropSetter(_) {} //# 53: continued
 
   @JS('a') // JS_INTEROP_CLASS_NON_EXTERNAL_MEMBER //# 54: compile-time error
-  staticJsInteropMethod() {} //# 54: continued
+  static staticJsInteropMethod() {} //# 54: continued
 
   external get externalInstanceGetter;
   external set externalInstanceSetter(_);
   external externalInstanceMethod();
 
-  external get externalStaticGetter;
-  external set externalStaticSetter(_);
-  external externalStaticMethod();
+  external static get externalStaticGetter;
+  external static set externalStaticSetter(_);
+  external static externalStaticMethod();
 
   @JS('a')
   external get externalInstanceJsInteropGetter;
@@ -232,13 +232,39 @@
   external externalInstanceJsInteropMethod();
 
   @JS('a')
-  external get externalStaticJsInteropGetter;
+  external static get externalStaticJsInteropGetter;
 
   @JS('a')
-  external set externalStaticJsInteropSetter(_);
+  external static set externalStaticJsInteropSetter(_);
 
   @JS('a')
-  external externalStaticJsInteropMethod();
+  external static externalStaticJsInteropMethod();
 }
 
-main() {}
+main() {
+  if (false) {
+    topLevelSetter = topLevelField = topLevelGetter;
+    topLevelFunction();
+    externalTopLevelJsInteropSetter = externalTopLevelJsInteropGetter;
+    externalTopLevelJsInteropFunction();
+    Class c1 = new Class.generative();
+    new Class.fact();
+    c1.instanceSetter = c1.instanceField = c1.instanceGetter;
+    c1.instanceMethod();
+    Class.staticSetter = Class.staticField = Class.staticGetter;
+    Class.staticMethod();
+    JsInteropClass c2 = new JsInteropClass.externalGenerative();
+    new JsInteropClass.externalFact();
+    new JsInteropClass.externalJsInteropGenerative();
+    new JsInteropClass.externalJsInteropFact();
+    c2.externalInstanceSetter = c2.externalInstanceGetter;
+    c2.externalInstanceMethod();
+    c2.externalInstanceJsInteropSetter = c2.externalInstanceJsInteropGetter;
+    c2.externalInstanceJsInteropMethod();
+    JsInteropClass.externalStaticSetter = JsInteropClass.externalStaticGetter;
+    JsInteropClass.externalStaticMethod();
+    JsInteropClass.externalStaticJsInteropSetter =
+        JsInteropClass.externalStaticJsInteropGetter;
+    JsInteropClass.externalStaticJsInteropMethod();
+  }
+}
diff --git a/tests/compiler/dart2js_extra/supermixin/supermixin10_test.dart b/tests/compiler/dart2js_extra/supermixin/supermixin10_test.dart
new file mode 100644
index 0000000..361e98b
--- /dev/null
+++ b/tests/compiler/dart2js_extra/supermixin/supermixin10_test.dart
@@ -0,0 +1,26 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:expect/expect.dart';
+
+class SuperA {
+  method1(a) => 'A$a';
+}
+
+class SuperB extends SuperA {
+  method1(a) => 'B$a';
+}
+
+mixin Mixin on SuperA {
+  method1(a) => super.method1('M$a');
+  method2(a) => 'M$a';
+}
+
+class Class extends SuperB with Mixin {}
+
+main() {
+  var c = new Class();
+  Expect.equals("BMC", c.method1('C'));
+  Expect.equals("MC", c.method2('C'));
+}
diff --git a/tests/compiler/dart2js_extra/supermixin/supermixin1_test.dart b/tests/compiler/dart2js_extra/supermixin/supermixin1_test.dart
new file mode 100644
index 0000000..6f6d16a
--- /dev/null
+++ b/tests/compiler/dart2js_extra/supermixin/supermixin1_test.dart
@@ -0,0 +1,24 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:expect/expect.dart';
+
+class SuperA {
+  method(a) => 'A$a';
+}
+
+class SuperB extends SuperA {
+  method(a) => 'B$a';
+}
+
+mixin Mixin on SuperA {
+  method(a) => super.method('M$a');
+}
+
+class Class extends SuperB with Mixin {}
+
+main() {
+  var c = new Class();
+  Expect.equals("BMC", c.method('C'));
+}
diff --git a/tests/compiler/dart2js_extra/supermixin/supermixin2_test.dart b/tests/compiler/dart2js_extra/supermixin/supermixin2_test.dart
new file mode 100644
index 0000000..846fe88
--- /dev/null
+++ b/tests/compiler/dart2js_extra/supermixin/supermixin2_test.dart
@@ -0,0 +1,24 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:expect/expect.dart';
+
+class SuperA {
+  method(a) => 'A$a';
+}
+
+class SuperB extends SuperA {
+  method(a) => 'B$a';
+}
+
+mixin Mixin on SuperA {
+  method(a) => super.method('M$a');
+}
+
+class Class = SuperB with Mixin;
+
+main() {
+  var c = new Class();
+  Expect.equals("BMC", c.method('C'));
+}
diff --git a/tests/compiler/dart2js_extra/supermixin/supermixin3_test.dart b/tests/compiler/dart2js_extra/supermixin/supermixin3_test.dart
new file mode 100644
index 0000000..c5bfca0
--- /dev/null
+++ b/tests/compiler/dart2js_extra/supermixin/supermixin3_test.dart
@@ -0,0 +1,24 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:expect/expect.dart';
+
+class SuperA {
+  get getter => 'A';
+}
+
+class SuperB extends SuperA {
+  get getter => 'B';
+}
+
+mixin Mixin on SuperA {
+  get getter => super.getter;
+}
+
+class Class extends SuperB with Mixin {}
+
+main() {
+  var c = new Class();
+  Expect.equals("B", c.getter);
+}
diff --git a/tests/compiler/dart2js_extra/supermixin/supermixin4_test.dart b/tests/compiler/dart2js_extra/supermixin/supermixin4_test.dart
new file mode 100644
index 0000000..a450c76
--- /dev/null
+++ b/tests/compiler/dart2js_extra/supermixin/supermixin4_test.dart
@@ -0,0 +1,24 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:expect/expect.dart';
+
+class SuperA {
+  get getter => 'A';
+}
+
+class SuperB extends SuperA {
+  get getter => 'B';
+}
+
+mixin Mixin on SuperA {
+  get getter => super.getter;
+}
+
+class Class = SuperB with Mixin;
+
+main() {
+  var c = new Class();
+  Expect.equals("B", c.getter);
+}
diff --git a/tests/compiler/dart2js_extra/supermixin/supermixin5_test.dart b/tests/compiler/dart2js_extra/supermixin/supermixin5_test.dart
new file mode 100644
index 0000000..41ea90c
--- /dev/null
+++ b/tests/compiler/dart2js_extra/supermixin/supermixin5_test.dart
@@ -0,0 +1,27 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:expect/expect.dart';
+
+class SuperA {
+  int field = 0;
+
+  set setter(int a) => field = a;
+}
+
+class SuperB extends SuperA {
+  set setter(int a) => field = a + 1;
+}
+
+mixin Mixin on SuperA {
+  set setter(int a) => super.setter = a;
+}
+
+class Class extends SuperB with Mixin {}
+
+main() {
+  var c = new Class();
+  c.setter = 41;
+  Expect.equals(42, c.field);
+}
diff --git a/tests/compiler/dart2js_extra/supermixin/supermixin6_test.dart b/tests/compiler/dart2js_extra/supermixin/supermixin6_test.dart
new file mode 100644
index 0000000..86a998f
--- /dev/null
+++ b/tests/compiler/dart2js_extra/supermixin/supermixin6_test.dart
@@ -0,0 +1,27 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:expect/expect.dart';
+
+class SuperA {
+  int field = 0;
+
+  set setter(int a) => field = a;
+}
+
+class SuperB extends SuperA {
+  set setter(int a) => field = a + 1;
+}
+
+mixin Mixin on SuperA {
+  set setter(int a) => super.setter = a;
+}
+
+class Class = SuperB with Mixin;
+
+main() {
+  var c = new Class();
+  c.setter = 41;
+  Expect.equals(42, c.field);
+}
diff --git a/tests/compiler/dart2js_extra/supermixin/supermixin7_test.dart b/tests/compiler/dart2js_extra/supermixin/supermixin7_test.dart
new file mode 100644
index 0000000..80e0a17
--- /dev/null
+++ b/tests/compiler/dart2js_extra/supermixin/supermixin7_test.dart
@@ -0,0 +1,26 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:expect/expect.dart';
+
+class SuperA<T> {
+  method() => null;
+}
+
+class SuperB<T> extends SuperA<T> {
+  method() => T;
+}
+
+mixin Mixin<T> on SuperA<T> {
+  method() => super.method();
+}
+
+class Class<T> extends SuperB<T> with Mixin<T> {}
+
+main() {
+  var c1 = new Class<String>();
+  var c2 = new Class<int>();
+  Expect.equals(String, c1.method());
+  Expect.equals(int, c2.method());
+}
diff --git a/tests/compiler/dart2js_extra/supermixin/supermixin8_test.dart b/tests/compiler/dart2js_extra/supermixin/supermixin8_test.dart
new file mode 100644
index 0000000..42af785
--- /dev/null
+++ b/tests/compiler/dart2js_extra/supermixin/supermixin8_test.dart
@@ -0,0 +1,26 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:expect/expect.dart';
+
+class SuperA<T, S> {
+  method() => T;
+}
+
+class SuperB<T, S> extends SuperA<T, S> {
+  method() => S;
+}
+
+mixin Mixin<T, S> on SuperA<T, S> {
+  method() => super.method();
+}
+
+class Class<T, S> extends SuperB<T, S> with Mixin<T, S> {}
+
+main() {
+  var c1 = new Class<int, String>();
+  var c2 = new Class<String, int>();
+  Expect.equals(String, c1.method());
+  Expect.equals(int, c2.method());
+}
diff --git a/tests/compiler/dart2js_extra/supermixin/supermixin9_test.dart b/tests/compiler/dart2js_extra/supermixin/supermixin9_test.dart
new file mode 100644
index 0000000..41a688f
--- /dev/null
+++ b/tests/compiler/dart2js_extra/supermixin/supermixin9_test.dart
@@ -0,0 +1,24 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:expect/expect.dart';
+
+class SuperA<T> {
+  method() => T;
+}
+
+class SuperB extends SuperA<int> {
+  method() => String;
+}
+
+mixin Mixin<T> on SuperA<T> {
+  method() => super.method();
+}
+
+class Class extends SuperB with Mixin<int> {}
+
+main() {
+  var c = new Class();
+  Expect.equals(String, c.method());
+}
diff --git a/tests/corelib/corelib.status b/tests/corelib/corelib.status
index f41c498..a701a20 100644
--- a/tests/corelib/corelib.status
+++ b/tests/corelib/corelib.status
@@ -2,6 +2,7 @@
 # for details. All rights reserved. Use of this source code is governed by a
 # BSD-style license that can be found in the LICENSE file.
 
+core_runtime_types_test: RuntimeError # Does not expect bool to have operators.
 maps_test: Skip # Maps class no longer exists
 
 [ $compiler == dart2analyzer ]
diff --git a/tests/corelib_2/bool_operator_test.dart b/tests/corelib_2/bool_operator_test.dart
new file mode 100644
index 0000000..3d5e3de
--- /dev/null
+++ b/tests/corelib_2/bool_operator_test.dart
@@ -0,0 +1,46 @@
+// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+main() {
+  void test(bool b1, bool b2) {
+    var and1 = b1 && b2;
+    var and2 = b1 & b2;
+    var and3 = b1 ? b2 ? true : false : false;
+    var or1 = b1 || b2;
+    var or2 = b1 | b2;
+    var or3 = b1 ? true : b2 ? true : false;
+    var xor1 = b1 != b2;
+    var xor2 = b1 ^ b2;
+    var xor3 = b1 ? b2 ? false : true : b2 ? true : false;
+    var nb1 = !b1;
+    var nb2 = !b2;
+    Expect.equals(and3, and1);
+    Expect.equals(and3, and2);
+    Expect.equals(or3, or1);
+    Expect.equals(or3, or2);
+    Expect.equals(xor3, xor1);
+    Expect.equals(xor3, xor2);
+    Expect.notEquals(nb1, b1);
+    Expect.notEquals(nb2, b2);
+  }
+
+  test(true, false);
+  test(true, true);
+  test(false, true);
+  test(false, false);
+
+  Expect.isTrue(true || (throw "unreachable"));
+  Expect.throws(() => false || (throw "unreachable"));
+
+  Expect.isFalse(false && (throw "unreachable"));
+  Expect.throws(() => true && (throw "unreachable"));
+
+  Expect.throws(() => true | (throw "unreachable"));
+  Expect.throws(() => false | (throw "unreachable"));
+
+  Expect.throws(() => true & (throw "unreachable"));
+  Expect.throws(() => false & (throw "unreachable"));
+}
diff --git a/tests/corelib_2/core_runtime_types_test.dart b/tests/corelib_2/core_runtime_types_test.dart
index 69a741e..7176feb 100644
--- a/tests/corelib_2/core_runtime_types_test.dart
+++ b/tests/corelib_2/core_runtime_types_test.dart
@@ -46,13 +46,16 @@
     assertListEquals(a, b);
   }
 
-  static assertTypeError(void f()) {
-    Expect.throws(
+  static assertTypeError(void f(), [String message]) {
+    Expect.throws<Error>(
         f,
         (exception) =>
             (exception is TypeError) ||
+            (exception is CastError) ||
+            (exception is AssertionError) ||
             (exception is NoSuchMethodError) ||
-            (exception is ArgumentError));
+            (exception is ArgumentError),
+        message);
   }
 
   static testBooleanOperators() {
@@ -94,46 +97,49 @@
     for (var i = 0; i < objs.length; i++) {
       for (var j = i + 1; j < objs.length; j++) {
         testBinaryOperatorErrors(objs[i], objs[j]);
-        // Allow "String * int".
-        if (j > 2) testBinaryOperatorErrors(objs[j], objs[i]);
+        testBinaryOperatorErrors(objs[j], objs[i]);
       }
-      if (objs[i] != 1) {
-        testUnaryOperatorErrors(objs[i]);
-      }
+      testUnaryOperatorErrors(objs[i]);
     }
   }
 
   static testBinaryOperatorErrors(x, y) {
     assertTypeError(() {
-      x - y;
-    });
+      x + y;
+    }, "$x+$y");
     assertTypeError(() {
-      x * y;
-    });
+      x - y;
+    }, "$x-$y");
+    // String.* is the only non-same-type binary operator we have.
+    if (x is! String && y is! int) {
+      assertTypeError(() {
+        x * y;
+      }, "$x*$y");
+    }
     assertTypeError(() {
       x / y;
-    });
+    }, "$x/$y");
     assertTypeError(() {
       x | y;
-    });
+    }, "$x|$y");
     assertTypeError(() {
       x ^ y;
-    });
+    }, "$x^$y");
     assertTypeError(() {
       x & y;
-    });
+    }, "$x&$y");
     assertTypeError(() {
       x << y;
-    });
+    }, "$x<<$y");
     assertTypeError(() {
       x >> y;
-    });
+    }, "$x>>$y");
     assertTypeError(() {
       x ~/ y;
-    });
+    }, "$x~/$y");
     assertTypeError(() {
       x % y;
-    });
+    }, "$x%$y");
 
     testComparisonOperatorErrors(x, y);
   }
@@ -143,27 +149,34 @@
     assertEquals(x != y, true);
     assertTypeError(() {
       x < y;
-    });
+    }, "$x<$y");
     assertTypeError(() {
       x <= y;
-    });
+    }, "$x<=$y");
     assertTypeError(() {
       x > y;
-    });
+    }, "$x>$y");
     assertTypeError(() {
       x >= y;
-    });
+    }, "$x>=$y");
   }
 
   static testUnaryOperatorErrors(x) {
-    // TODO(jimhug): Add guard for 'is num' when 'is' is working
-    assertTypeError(() {
-      ~x;
-    });
-    assertTypeError(() {
-      -x;
-    });
-    // TODO(jimhug): Add check for !x as an error when x is not a bool
+    if (x is! int) {
+      assertTypeError(() {
+        ~x;
+      }, "~$x");
+    }
+    if (x is! num) {
+      assertTypeError(() {
+        -x;
+      }, "-$x");
+    }
+    if (x is! bool) {
+      assertTypeError(() {
+        !x;
+      }, "!$x");
+    }
   }
 
   static testRationalMethods() {
diff --git a/tests/corelib_2/corelib_2.status b/tests/corelib_2/corelib_2.status
index 9c87583..8467f2f 100644
--- a/tests/corelib_2/corelib_2.status
+++ b/tests/corelib_2/corelib_2.status
@@ -20,6 +20,7 @@
 bigint_test: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
 bit_twiddling_test/int64: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
 compare_to2_test: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
+core_runtime_types_test: RuntimeError # Issue 34147
 date_time11_test: RuntimeError, Pass # Fails when US is on winter time, issue 31285.
 date_time_test: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
 double_ceil_test/int64: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
@@ -288,6 +289,9 @@
 symbol_test/none: RuntimeError # Issues 11669 and 31936 - throwing const constructors.
 unicode_test: RuntimeError # Issue 18061: German double S.
 
+[ $compiler != fasta && !$strong ]
+core_runtime_types_test: SkipByDesign
+
 [ $compiler == none && $runtime == vm ]
 from_environment_const_type_undefined_test/09: MissingCompileTimeError
 from_environment_const_type_undefined_test/11: MissingCompileTimeError
diff --git a/tests/kernel/kernel.status b/tests/kernel/kernel.status
index 82cce18..4602e94 100644
--- a/tests/kernel/kernel.status
+++ b/tests/kernel/kernel.status
@@ -6,7 +6,6 @@
 unsorted/invocation_errors_test: Pass
 unsorted/nsm_dispatcher_test: Skip # The test uses Symbol without MirrorsUsed
 unsorted/simple_literal_test/01: Skip # The test expects error for large integer literal.
-unsorted/super_mixin_test: RuntimeError
 unsorted/try_finally_test: Crash
 
 [ !$fasta ]
@@ -18,6 +17,9 @@
 [ $compiler == dart2analyzer && $runtime == none ]
 unsorted/super_mixin_test: CompileTimeError
 
+[ $compiler == dart2js && !$fast_startup ]
+unsorted/super_mixin_test: RuntimeError
+
 [ $compiler == dart2js && $host_checked ]
 unsorted/super_mixin_test: Crash
 
diff --git a/tests/language_2/const_constructor3_test.dart b/tests/language_2/const_constructor3_test.dart
index e8aac19..e12c4b7 100644
--- a/tests/language_2/const_constructor3_test.dart
+++ b/tests/language_2/const_constructor3_test.dart
@@ -11,10 +11,11 @@
   const D(var d) : super(d);
 }
 
+const intValue = 0;
 const c = const C(0.0); //# 01: ok
-const d = const C(0); //# 02: compile-time error
+const d = const C(intValue); //# 02: compile-time error
 const e = const D(0.0); //# 03: ok
-const f = const D(0); //# 04: compile-time error
+const f = const D(intValue); //# 04: compile-time error
 
 main() {
   print(c); //# 01: continued
diff --git a/tests/language_2/const_init2_test.dart b/tests/language_2/const_init2_test.dart
index d45c5d5..fcc6f6f 100644
--- a/tests/language_2/const_init2_test.dart
+++ b/tests/language_2/const_init2_test.dart
@@ -2,8 +2,9 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+const intValue = 0;
 const double c = 0.0; //# 01: ok
-const double d = 0; //# 02: compile-time error
+const double d = intValue; //# 02: compile-time error
 
 main() {
   print(c); //# 01: continued
diff --git a/tests/language_2/covariant_subtyping_with_mixin_test.dart b/tests/language_2/covariant_subtyping_with_mixin_test.dart
new file mode 100644
index 0000000..8bff28e
--- /dev/null
+++ b/tests/language_2/covariant_subtyping_with_mixin_test.dart
@@ -0,0 +1,29 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:expect/expect.dart';
+
+class A {}
+
+class B extends A {}
+
+class Base<S> {}
+
+class Mixin<T> {
+  void f(T arg) {}
+}
+
+abstract class Interface {
+  void f(covariant A arg);
+}
+
+class C<S> extends Base<S> with Mixin<B> implements Interface {}
+
+main() {
+  Interface i = new C<String>();
+  i.f(new B());
+  Expect.throwsTypeError(() {
+    i.f(new A());
+  });
+}
diff --git a/tests/language_2/double_literals/double_literal_coercion_error_test.dart b/tests/language_2/double_literals/double_literal_coercion_error_test.dart
index 89d873f..ca112be 100644
--- a/tests/language_2/double_literals/double_literal_coercion_error_test.dart
+++ b/tests/language_2/double_literals/double_literal_coercion_error_test.dart
@@ -79,217 +79,221 @@
     18446744073709553664, // 2^64+2^11     //# 067: compile-time error
     179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858367, // maxValue - 1 //# 068 : compile-time error
     179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858369, // maxValue + 1 //# 069 : compile-time error
+    359538626972463141629054847463408713596141135051689993197834953606314521560057077521179117265533756343080917907028764928468642653778928365536935093407075033972099821153102564152490980180778657888151737016910267884609166473806445896331617118664246696549595652408289446337476354361838599762500808052368249716734, // maxValue * 2 //# 070P : compile-time error
 
     // Negative numbers too.
-    -9007199254740993, //     -(2^53+2^0)  //# 070: compile-time error
-    -18014398509481983, //    -(2^54-2^0)  //# 071: compile-time error
-    -18014398509481985, //    -(2^54+2^0)  //# 072: compile-time error
-    -18014398509481986, //    -(2^54+2^1)  //# 073: compile-time error
-    -4611686018427387903, //  -(2^62-2^0)  //# 074: compile-time error
-    -4611686018427387902, //  -(2^62-2^1)  //# 075: compile-time error
-    -4611686018427387900, //  -(2^62-2^2)  //# 076: compile-time error
-    -4611686018427387896, //  -(2^62-2^3)  //# 077: compile-time error
-    -4611686018427387888, //  -(2^62-2^4)  //# 078: compile-time error
-    -4611686018427387872, //  -(2^62-2^5)  //# 079: compile-time error
-    -4611686018427387840, //  -(2^62-2^6)  //# 080: compile-time error
-    -4611686018427387776, //  -(2^62-2^7)  //# 081: compile-time error
-    -4611686018427387648, //  -(2^62-2^8)  //# 082: compile-time error
-    -4611686018427387905, //  -(2^62+2^0)  //# 083: compile-time error
-    -4611686018427387906, //  -(2^62+2^1)  //# 084: compile-time error
-    -4611686018427387908, //  -(2^62+2^2)  //# 085: compile-time error
-    -4611686018427387912, //  -(2^62+2^3)  //# 086: compile-time error
-    -4611686018427387920, //  -(2^62+2^4)  //# 087: compile-time error
-    -4611686018427387936, //  -(2^62+2^5)  //# 088: compile-time error
-    -4611686018427387968, //  -(2^62+2^6)  //# 089: compile-time error
-    -4611686018427388032, //  -(2^62+2^7)  //# 090: compile-time error
-    -4611686018427388160, //  -(2^62+2^8)  //# 091: compile-time error
-    -4611686018427388416, //  -(2^62+2^9)  //# 092: compile-time error
-    -9223372036854775807, //  -(2^63-2^0)  //# 093: compile-time error
-    -9223372036854775806, //  -(2^63-2^1)  //# 094: compile-time error
-    -9223372036854775804, //  -(2^63-2^2)  //# 095: compile-time error
-    -9223372036854775800, //  -(2^63-2^3)  //# 096: compile-time error
-    -9223372036854775792, //  -(2^63-2^4)  //# 097: compile-time error
-    -9223372036854775776, //  -(2^63-2^5)  //# 098: compile-time error
-    -9223372036854775744, //  -(2^63-2^6)  //# 099: compile-time error
-    -9223372036854775680, //  -(2^63-2^7)  //# 100: compile-time error
-    -9223372036854775552, //  -(2^63-2^8)  //# 101: compile-time error
-    -9223372036854775296, //  -(2^63-2^9)  //# 102: compile-time error
-    -9223372036854775809, //  -(2^63+2^0)  //# 103: compile-time error
-    -9223372036854775810, //  -(2^63+2^1)  //# 104: compile-time error
-    -9223372036854775812, //  -(2^63+2^2)  //# 105: compile-time error
-    -9223372036854775816, //  -(2^63+2^3)  //# 106: compile-time error
-    -9223372036854775824, //  -(2^63+2^4)  //# 107: compile-time error
-    -9223372036854775840, //  -(2^63+2^5)  //# 108: compile-time error
-    -9223372036854775872, //  -(2^63+2^6)  //# 109: compile-time error
-    -9223372036854775936, //  -(2^63+2^7)  //# 110: compile-time error
-    -9223372036854776064, //  -(2^63+2^8)  //# 111: compile-time error
-    -9223372036854776320, //  -(2^63+2^9)  //# 112: compile-time error
-    -9223372036854776832, //  -(2^63+2^10) //# 113: compile-time error
-    -18446744073709551615, // -(2^64-2^0)  //# 114: compile-time error
-    -18446744073709551614, // -(2^64-2^1)  //# 115: compile-time error
-    -18446744073709551612, // -(2^64-2^2)  //# 116: compile-time error
-    -18446744073709551608, // -(2^64-2^3)  //# 117: compile-time error
-    -18446744073709551600, // -(2^64-2^4)  //# 118: compile-time error
-    -18446744073709551584, // -(2^64-2^5)  //# 119: compile-time error
-    -18446744073709551552, // -(2^64-2^6)  //# 120: compile-time error
-    -18446744073709551488, // -(2^64-2^7)  //# 121: compile-time error
-    -18446744073709551360, // -(2^64-2^8)  //# 122: compile-time error
-    -18446744073709551104, // -(2^64-2^9)  //# 123: compile-time error
-    -18446744073709550592, // -(2^64-2^10) //# 124: compile-time error
-    -18446744073709551617, // -(2^64+2^0)  //# 125: compile-time error
-    -18446744073709551618, // -(2^64+2^1)  //# 126: compile-time error
-    -18446744073709551620, // -(2^64+2^2)  //# 127: compile-time error
-    -18446744073709551624, // -(2^64+2^3)  //# 128: compile-time error
-    -18446744073709551632, // -(2^64+2^4)  //# 129: compile-time error
-    -18446744073709551648, // -(2^64+2^5)  //# 130: compile-time error
-    -18446744073709551680, // -(2^64+2^6)  //# 131: compile-time error
-    -18446744073709551744, // -(2^64+2^7)  //# 132: compile-time error
-    -18446744073709551872, // -(2^64+2^8)  //# 133: compile-time error
-    -18446744073709552128, // -(2^64+2^9)  //# 134: compile-time error
-    -18446744073709552640, // -(2^64+2^10) //# 135: compile-time error
-    -18446744073709553664, // -(2^64+2^11) //# 136: compile-time error
-    -179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858367, // -(maxValue - 1) //# 137 : compile-time error
-    -179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858369, // -(maxValue + 1) //# 138 : compile-time error
+    -9007199254740993, //     -(2^53+2^0)  //# 071: compile-time error
+    -18014398509481983, //    -(2^54-2^0)  //# 072: compile-time error
+    -18014398509481985, //    -(2^54+2^0)  //# 073: compile-time error
+    -18014398509481986, //    -(2^54+2^1)  //# 074: compile-time error
+    -4611686018427387903, //  -(2^62-2^0)  //# 075: compile-time error
+    -4611686018427387902, //  -(2^62-2^1)  //# 076: compile-time error
+    -4611686018427387900, //  -(2^62-2^2)  //# 077: compile-time error
+    -4611686018427387896, //  -(2^62-2^3)  //# 078: compile-time error
+    -4611686018427387888, //  -(2^62-2^4)  //# 079: compile-time error
+    -4611686018427387872, //  -(2^62-2^5)  //# 080: compile-time error
+    -4611686018427387840, //  -(2^62-2^6)  //# 081: compile-time error
+    -4611686018427387776, //  -(2^62-2^7)  //# 082: compile-time error
+    -4611686018427387648, //  -(2^62-2^8)  //# 083: compile-time error
+    -4611686018427387905, //  -(2^62+2^0)  //# 084: compile-time error
+    -4611686018427387906, //  -(2^62+2^1)  //# 085: compile-time error
+    -4611686018427387908, //  -(2^62+2^2)  //# 086: compile-time error
+    -4611686018427387912, //  -(2^62+2^3)  //# 087: compile-time error
+    -4611686018427387920, //  -(2^62+2^4)  //# 088: compile-time error
+    -4611686018427387936, //  -(2^62+2^5)  //# 089: compile-time error
+    -4611686018427387968, //  -(2^62+2^6)  //# 090: compile-time error
+    -4611686018427388032, //  -(2^62+2^7)  //# 091: compile-time error
+    -4611686018427388160, //  -(2^62+2^8)  //# 092: compile-time error
+    -4611686018427388416, //  -(2^62+2^9)  //# 093: compile-time error
+    -9223372036854775807, //  -(2^63-2^0)  //# 094: compile-time error
+    -9223372036854775806, //  -(2^63-2^1)  //# 095: compile-time error
+    -9223372036854775804, //  -(2^63-2^2)  //# 096: compile-time error
+    -9223372036854775800, //  -(2^63-2^3)  //# 097: compile-time error
+    -9223372036854775792, //  -(2^63-2^4)  //# 098: compile-time error
+    -9223372036854775776, //  -(2^63-2^5)  //# 099: compile-time error
+    -9223372036854775744, //  -(2^63-2^6)  //# 100: compile-time error
+    -9223372036854775680, //  -(2^63-2^7)  //# 101: compile-time error
+    -9223372036854775552, //  -(2^63-2^8)  //# 102: compile-time error
+    -9223372036854775296, //  -(2^63-2^9)  //# 103: compile-time error
+    -9223372036854775809, //  -(2^63+2^0)  //# 104: compile-time error
+    -9223372036854775810, //  -(2^63+2^1)  //# 105: compile-time error
+    -9223372036854775812, //  -(2^63+2^2)  //# 106: compile-time error
+    -9223372036854775816, //  -(2^63+2^3)  //# 107: compile-time error
+    -9223372036854775824, //  -(2^63+2^4)  //# 108: compile-time error
+    -9223372036854775840, //  -(2^63+2^5)  //# 109: compile-time error
+    -9223372036854775872, //  -(2^63+2^6)  //# 110: compile-time error
+    -9223372036854775936, //  -(2^63+2^7)  //# 111: compile-time error
+    -9223372036854776064, //  -(2^63+2^8)  //# 112: compile-time error
+    -9223372036854776320, //  -(2^63+2^9)  //# 113: compile-time error
+    -9223372036854776832, //  -(2^63+2^10) //# 114: compile-time error
+    -18446744073709551615, // -(2^64-2^0)  //# 115: compile-time error
+    -18446744073709551614, // -(2^64-2^1)  //# 116: compile-time error
+    -18446744073709551612, // -(2^64-2^2)  //# 117: compile-time error
+    -18446744073709551608, // -(2^64-2^3)  //# 118: compile-time error
+    -18446744073709551600, // -(2^64-2^4)  //# 119: compile-time error
+    -18446744073709551584, // -(2^64-2^5)  //# 120: compile-time error
+    -18446744073709551552, // -(2^64-2^6)  //# 121: compile-time error
+    -18446744073709551488, // -(2^64-2^7)  //# 122: compile-time error
+    -18446744073709551360, // -(2^64-2^8)  //# 123: compile-time error
+    -18446744073709551104, // -(2^64-2^9)  //# 124: compile-time error
+    -18446744073709550592, // -(2^64-2^10) //# 125: compile-time error
+    -18446744073709551617, // -(2^64+2^0)  //# 126: compile-time error
+    -18446744073709551618, // -(2^64+2^1)  //# 127: compile-time error
+    -18446744073709551620, // -(2^64+2^2)  //# 128: compile-time error
+    -18446744073709551624, // -(2^64+2^3)  //# 129: compile-time error
+    -18446744073709551632, // -(2^64+2^4)  //# 130: compile-time error
+    -18446744073709551648, // -(2^64+2^5)  //# 131: compile-time error
+    -18446744073709551680, // -(2^64+2^6)  //# 132: compile-time error
+    -18446744073709551744, // -(2^64+2^7)  //# 133: compile-time error
+    -18446744073709551872, // -(2^64+2^8)  //# 134: compile-time error
+    -18446744073709552128, // -(2^64+2^9)  //# 135: compile-time error
+    -18446744073709552640, // -(2^64+2^10) //# 136: compile-time error
+    -18446744073709553664, // -(2^64+2^11) //# 137: compile-time error
+    -179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858367, // -(maxValue - 1) //# 138 : compile-time error
+    -179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858369, // -(maxValue + 1) //# 139 : compile-time error
+    -359538626972463141629054847463408713596141135051689993197834953606314521560057077521179117265533756343080917907028764928468642653778928365536935093407075033972099821153102564152490980180778657888151737016910267884609166473806445896331617118664246696549595652408289446337476354361838599762500808052368249716734, // -(maxValue * 2) //# 140B : compile-time error
 
     // Same numbers as hexadecimal literals.
-    0x20000000000001, //    2^53+2^0      //# 139: compile-time error
-    0x3fffffffffffff, //    2^54-2^0      //# 140: compile-time error
-    0x40000000000001, //    2^54+2^0      //# 141: compile-time error
-    0x40000000000002, //    2^54+2^1      //# 142: compile-time error
-    0x3fffffffffffffff, //  2^62-2^0      //# 143: compile-time error
-    0x3ffffffffffffffe, //  2^62-2^1      //# 144: compile-time error
-    0x3ffffffffffffffc, //  2^62-2^2      //# 145: compile-time error
-    0x3ffffffffffffff8, //  2^62-2^3      //# 146: compile-time error
-    0x3ffffffffffffff0, //  2^62-2^4      //# 147: compile-time error
-    0x3fffffffffffffe0, //  2^62-2^5      //# 148: compile-time error
-    0x3fffffffffffffc0, //  2^62-2^6      //# 149: compile-time error
-    0x3fffffffffffff80, //  2^62-2^7      //# 150: compile-time error
-    0x3fffffffffffff00, //  2^62-2^8      //# 151: compile-time error
-    0x4000000000000001, //  2^62+2^0      //# 152: compile-time error
-    0x4000000000000002, //  2^62+2^1      //# 153: compile-time error
-    0x4000000000000004, //  2^62+2^2      //# 154: compile-time error
-    0x4000000000000008, //  2^62+2^3      //# 155: compile-time error
-    0x4000000000000010, //  2^62+2^4      //# 156: compile-time error
-    0x4000000000000020, //  2^62+2^5      //# 157: compile-time error
-    0x4000000000000040, //  2^62+2^6      //# 158: compile-time error
-    0x4000000000000080, //  2^62+2^7      //# 159: compile-time error
-    0x4000000000000100, //  2^62+2^8      //# 160: compile-time error
-    0x4000000000000200, //  2^62+2^9      //# 161: compile-time error
-    0x7fffffffffffffff, //  2^63-2^0      //# 162: compile-time error
-    0x7ffffffffffffffe, //  2^63-2^1      //# 163: compile-time error
-    0x7ffffffffffffffc, //  2^63-2^2      //# 164: compile-time error
-    0x7ffffffffffffff8, //  2^63-2^3      //# 165: compile-time error
-    0x7ffffffffffffff0, //  2^63-2^4      //# 166: compile-time error
-    0x7fffffffffffffe0, //  2^63-2^5      //# 167: compile-time error
-    0x7fffffffffffffc0, //  2^63-2^6      //# 168: compile-time error
-    0x7fffffffffffff80, //  2^63-2^7      //# 169: compile-time error
-    0x7fffffffffffff00, //  2^63-2^8      //# 170: compile-time error
-    0x7ffffffffffffe00, //  2^63-2^9      //# 171: compile-time error
-    0x8000000000000001, //  2^63+2^0      //# 172: compile-time error
-    0x8000000000000002, //  2^63+2^1      //# 173: compile-time error
-    0x8000000000000004, //  2^63+2^2      //# 174: compile-time error
-    0x8000000000000008, //  2^63+2^3      //# 175: compile-time error
-    0x8000000000000010, //  2^63+2^4      //# 176: compile-time error
-    0x8000000000000020, //  2^63+2^5      //# 177: compile-time error
-    0x8000000000000040, //  2^63+2^6      //# 178: compile-time error
-    0x8000000000000080, //  2^63+2^7      //# 179: compile-time error
-    0x8000000000000100, //  2^63+2^8      //# 180: compile-time error
-    0x8000000000000200, //  2^63+2^9      //# 181: compile-time error
-    0x8000000000000400, //  2^63+2^10     //# 182: compile-time error
-    0xffffffffffffffff, //  2^64-2^0      //# 183: compile-time error
-    0xfffffffffffffffe, //  2^64-2^1      //# 184: compile-time error
-    0xfffffffffffffffc, //  2^64-2^2      //# 185: compile-time error
-    0xfffffffffffffff8, //  2^64-2^3      //# 186: compile-time error
-    0xfffffffffffffff0, //  2^64-2^4      //# 187: compile-time error
-    0xffffffffffffffe0, //  2^64-2^5      //# 188: compile-time error
-    0xffffffffffffffc0, //  2^64-2^6      //# 189: compile-time error
-    0xffffffffffffff80, //  2^64-2^7      //# 190: compile-time error
-    0xffffffffffffff00, //  2^64-2^8      //# 191: compile-time error
-    0xfffffffffffffe00, //  2^64-2^9      //# 192: compile-time error
-    0xfffffffffffffc00, //  2^64-2^10     //# 193: compile-time error
-    0x10000000000000001, // 2^64+2^0      //# 194: compile-time error
-    0x10000000000000002, // 2^64+2^1      //# 195: compile-time error
-    0x10000000000000004, // 2^64+2^2      //# 196: compile-time error
-    0x10000000000000008, // 2^64+2^3      //# 197: compile-time error
-    0x10000000000000010, // 2^64+2^4      //# 198: compile-time error
-    0x10000000000000020, // 2^64+2^5      //# 199: compile-time error
-    0x10000000000000040, // 2^64+2^6      //# 200: compile-time error
-    0x10000000000000080, // 2^64+2^7      //# 201: compile-time error
-    0x10000000000000100, // 2^64+2^8      //# 202: compile-time error
-    0x10000000000000200, // 2^64+2^9      //# 203: compile-time error
-    0x10000000000000400, // 2^64+2^10     //# 204: compile-time error
-    0x10000000000000800, // 2^64+2^11     //# 205: compile-time error
-    0xfffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, // maxValue - 1 //# 206 : compile-time error
-    0xfffffffffffff800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001, // maxValue + 1 //# 207 : compile-time error
+    0x20000000000001, //    2^53+2^0      //# 141: compile-time error
+    0x3fffffffffffff, //    2^54-2^0      //# 142: compile-time error
+    0x40000000000001, //    2^54+2^0      //# 143: compile-time error
+    0x40000000000002, //    2^54+2^1      //# 144: compile-time error
+    0x3fffffffffffffff, //  2^62-2^0      //# 145: compile-time error
+    0x3ffffffffffffffe, //  2^62-2^1      //# 146: compile-time error
+    0x3ffffffffffffffc, //  2^62-2^2      //# 147: compile-time error
+    0x3ffffffffffffff8, //  2^62-2^3      //# 148: compile-time error
+    0x3ffffffffffffff0, //  2^62-2^4      //# 149: compile-time error
+    0x3fffffffffffffe0, //  2^62-2^5      //# 150: compile-time error
+    0x3fffffffffffffc0, //  2^62-2^6      //# 151: compile-time error
+    0x3fffffffffffff80, //  2^62-2^7      //# 152: compile-time error
+    0x3fffffffffffff00, //  2^62-2^8      //# 153: compile-time error
+    0x4000000000000001, //  2^62+2^0      //# 154: compile-time error
+    0x4000000000000002, //  2^62+2^1      //# 155: compile-time error
+    0x4000000000000004, //  2^62+2^2      //# 156: compile-time error
+    0x4000000000000008, //  2^62+2^3      //# 157: compile-time error
+    0x4000000000000010, //  2^62+2^4      //# 158: compile-time error
+    0x4000000000000020, //  2^62+2^5      //# 159: compile-time error
+    0x4000000000000040, //  2^62+2^6      //# 160: compile-time error
+    0x4000000000000080, //  2^62+2^7      //# 161: compile-time error
+    0x4000000000000100, //  2^62+2^8      //# 162: compile-time error
+    0x4000000000000200, //  2^62+2^9      //# 163: compile-time error
+    0x7fffffffffffffff, //  2^63-2^0      //# 164: compile-time error
+    0x7ffffffffffffffe, //  2^63-2^1      //# 165: compile-time error
+    0x7ffffffffffffffc, //  2^63-2^2      //# 166: compile-time error
+    0x7ffffffffffffff8, //  2^63-2^3      //# 167: compile-time error
+    0x7ffffffffffffff0, //  2^63-2^4      //# 168: compile-time error
+    0x7fffffffffffffe0, //  2^63-2^5      //# 169: compile-time error
+    0x7fffffffffffffc0, //  2^63-2^6      //# 170: compile-time error
+    0x7fffffffffffff80, //  2^63-2^7      //# 171: compile-time error
+    0x7fffffffffffff00, //  2^63-2^8      //# 172: compile-time error
+    0x7ffffffffffffe00, //  2^63-2^9      //# 173: compile-time error
+    0x8000000000000001, //  2^63+2^0      //# 174: compile-time error
+    0x8000000000000002, //  2^63+2^1      //# 175: compile-time error
+    0x8000000000000004, //  2^63+2^2      //# 176: compile-time error
+    0x8000000000000008, //  2^63+2^3      //# 177: compile-time error
+    0x8000000000000010, //  2^63+2^4      //# 178: compile-time error
+    0x8000000000000020, //  2^63+2^5      //# 179: compile-time error
+    0x8000000000000040, //  2^63+2^6      //# 180: compile-time error
+    0x8000000000000080, //  2^63+2^7      //# 181: compile-time error
+    0x8000000000000100, //  2^63+2^8      //# 182: compile-time error
+    0x8000000000000200, //  2^63+2^9      //# 183: compile-time error
+    0x8000000000000400, //  2^63+2^10     //# 184: compile-time error
+    0xffffffffffffffff, //  2^64-2^0      //# 185: compile-time error
+    0xfffffffffffffffe, //  2^64-2^1      //# 186: compile-time error
+    0xfffffffffffffffc, //  2^64-2^2      //# 187: compile-time error
+    0xfffffffffffffff8, //  2^64-2^3      //# 188: compile-time error
+    0xfffffffffffffff0, //  2^64-2^4      //# 189: compile-time error
+    0xffffffffffffffe0, //  2^64-2^5      //# 190: compile-time error
+    0xffffffffffffffc0, //  2^64-2^6      //# 191: compile-time error
+    0xffffffffffffff80, //  2^64-2^7      //# 192: compile-time error
+    0xffffffffffffff00, //  2^64-2^8      //# 193: compile-time error
+    0xfffffffffffffe00, //  2^64-2^9      //# 194: compile-time error
+    0xfffffffffffffc00, //  2^64-2^10     //# 195: compile-time error
+    0x10000000000000001, // 2^64+2^0      //# 196: compile-time error
+    0x10000000000000002, // 2^64+2^1      //# 197: compile-time error
+    0x10000000000000004, // 2^64+2^2      //# 198: compile-time error
+    0x10000000000000008, // 2^64+2^3      //# 199: compile-time error
+    0x10000000000000010, // 2^64+2^4      //# 200: compile-time error
+    0x10000000000000020, // 2^64+2^5      //# 201: compile-time error
+    0x10000000000000040, // 2^64+2^6      //# 202: compile-time error
+    0x10000000000000080, // 2^64+2^7      //# 203: compile-time error
+    0x10000000000000100, // 2^64+2^8      //# 204: compile-time error
+    0x10000000000000200, // 2^64+2^9      //# 205: compile-time error
+    0x10000000000000400, // 2^64+2^10     //# 206: compile-time error
+    0x10000000000000800, // 2^64+2^11     //# 207: compile-time error
+    0xfffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, // maxValue - 1 //# 208 : compile-time error
+    0xfffffffffffff800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001, // maxValue + 1 //# 209 : compile-time error
+    0x1fffffffffffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001, // maxValue * 2 //# 210V : compile-time error
 
-    -0x20000000000001, //    -(2^53+2^0)      //# 208: compile-time error
-    -0x3fffffffffffff, //    -(2^54-2^0)      //# 209: compile-time error
-    -0x40000000000001, //    -(2^54+2^0)      //# 210: compile-time error
-    -0x40000000000002, //    -(2^54+2^1)      //# 211: compile-time error
-    -0x3fffffffffffffff, //  -(2^62-2^0)      //# 212: compile-time error
-    -0x3ffffffffffffffe, //  -(2^62-2^1)      //# 213: compile-time error
-    -0x3ffffffffffffffc, //  -(2^62-2^2)      //# 214: compile-time error
-    -0x3ffffffffffffff8, //  -(2^62-2^3)      //# 215: compile-time error
-    -0x3ffffffffffffff0, //  -(2^62-2^4)      //# 216: compile-time error
-    -0x3fffffffffffffe0, //  -(2^62-2^5)      //# 217: compile-time error
-    -0x3fffffffffffffc0, //  -(2^62-2^6)      //# 218: compile-time error
-    -0x3fffffffffffff80, //  -(2^62-2^7)      //# 219: compile-time error
-    -0x3fffffffffffff00, //  -(2^62-2^8)      //# 220: compile-time error
-    -0x4000000000000001, //  -(2^62+2^0)      //# 221: compile-time error
-    -0x4000000000000002, //  -(2^62+2^1)      //# 222: compile-time error
-    -0x4000000000000004, //  -(2^62+2^2)      //# 223: compile-time error
-    -0x4000000000000008, //  -(2^62+2^3)      //# 224: compile-time error
-    -0x4000000000000010, //  -(2^62+2^4)      //# 225: compile-time error
-    -0x4000000000000020, //  -(2^62+2^5)      //# 226: compile-time error
-    -0x4000000000000040, //  -(2^62+2^6)      //# 227: compile-time error
-    -0x4000000000000080, //  -(2^62+2^7)      //# 228: compile-time error
-    -0x4000000000000100, //  -(2^62+2^8)      //# 229: compile-time error
-    -0x4000000000000200, //  -(2^62+2^9)      //# 230: compile-time error
-    -0x7fffffffffffffff, //  -(2^63-2^0)      //# 231: compile-time error
-    -0x7ffffffffffffffe, //  -(2^63-2^1)      //# 232: compile-time error
-    -0x7ffffffffffffffc, //  -(2^63-2^2)      //# 233: compile-time error
-    -0x7ffffffffffffff8, //  -(2^63-2^3)      //# 234: compile-time error
-    -0x7ffffffffffffff0, //  -(2^63-2^4)      //# 235: compile-time error
-    -0x7fffffffffffffe0, //  -(2^63-2^5)      //# 236: compile-time error
-    -0x7fffffffffffffc0, //  -(2^63-2^6)      //# 237: compile-time error
-    -0x7fffffffffffff80, //  -(2^63-2^7)      //# 238: compile-time error
-    -0x7fffffffffffff00, //  -(2^63-2^8)      //# 239: compile-time error
-    -0x7ffffffffffffe00, //  -(2^63-2^9)      //# 240: compile-time error
-    -0x8000000000000001, //  -(2^63+2^0)      //# 241: compile-time error
-    -0x8000000000000002, //  -(2^63+2^1)      //# 242: compile-time error
-    -0x8000000000000004, //  -(2^63+2^2)      //# 243: compile-time error
-    -0x8000000000000008, //  -(2^63+2^3)      //# 244: compile-time error
-    -0x8000000000000010, //  -(2^63+2^4)      //# 245: compile-time error
-    -0x8000000000000020, //  -(2^63+2^5)      //# 246: compile-time error
-    -0x8000000000000040, //  -(2^63+2^6)      //# 247: compile-time error
-    -0x8000000000000080, //  -(2^63+2^7)      //# 248: compile-time error
-    -0x8000000000000100, //  -(2^63+2^8)      //# 249: compile-time error
-    -0x8000000000000200, //  -(2^63+2^9)      //# 250: compile-time error
-    -0x8000000000000400, //  -(2^63+2^10)     //# 251: compile-time error
-    -0xffffffffffffffff, //  -(2^64-2^0)      //# 252: compile-time error
-    -0xfffffffffffffffe, //  -(2^64-2^1)      //# 253: compile-time error
-    -0xfffffffffffffffc, //  -(2^64-2^2)      //# 254: compile-time error
-    -0xfffffffffffffff8, //  -(2^64-2^3)      //# 255: compile-time error
-    -0xfffffffffffffff0, //  -(2^64-2^4)      //# 256: compile-time error
-    -0xffffffffffffffe0, //  -(2^64-2^5)      //# 257: compile-time error
-    -0xffffffffffffffc0, //  -(2^64-2^6)      //# 258: compile-time error
-    -0xffffffffffffff80, //  -(2^64-2^7)      //# 259: compile-time error
-    -0xffffffffffffff00, //  -(2^64-2^8)      //# 260: compile-time error
-    -0xfffffffffffffe00, //  -(2^64-2^9)      //# 261: compile-time error
-    -0xfffffffffffffc00, //  -(2^64-2^10)     //# 262: compile-time error
-    -0x10000000000000001, // -(2^64+2^0)      //# 263: compile-time error
-    -0x10000000000000002, // -(2^64+2^1)      //# 264: compile-time error
-    -0x10000000000000004, // -(2^64+2^2)      //# 265: compile-time error
-    -0x10000000000000008, // -(2^64+2^3)      //# 266: compile-time error
-    -0x10000000000000010, // -(2^64+2^4)      //# 267: compile-time error
-    -0x10000000000000020, // -(2^64+2^5)      //# 268: compile-time error
-    -0x10000000000000040, // -(2^64+2^6)      //# 269: compile-time error
-    -0x10000000000000080, // -(2^64+2^7)      //# 270: compile-time error
-    -0x10000000000000100, // -(2^64+2^8)      //# 271: compile-time error
-    -0x10000000000000200, // -(2^64+2^9)      //# 272: compile-time error
-    -0x10000000000000400, // -(2^64+2^10)     //# 273: compile-time error
-    -0x10000000000000800, // -(2^64+2^11)     //# 274: compile-time error
-    -0xfffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, // -(maxValue - 1) //# 275 : compile-time error
-    -0xfffffffffffff800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001, // -(maxValue + 1) //# 276 : compile-time error
+    -0x20000000000001, //    -(2^53+2^0)      //# 211: compile-time error
+    -0x3fffffffffffff, //    -(2^54-2^0)      //# 212: compile-time error
+    -0x40000000000001, //    -(2^54+2^0)      //# 213: compile-time error
+    -0x40000000000002, //    -(2^54+2^1)      //# 214: compile-time error
+    -0x3fffffffffffffff, //  -(2^62-2^0)      //# 215: compile-time error
+    -0x3ffffffffffffffe, //  -(2^62-2^1)      //# 216: compile-time error
+    -0x3ffffffffffffffc, //  -(2^62-2^2)      //# 217: compile-time error
+    -0x3ffffffffffffff8, //  -(2^62-2^3)      //# 218: compile-time error
+    -0x3ffffffffffffff0, //  -(2^62-2^4)      //# 219: compile-time error
+    -0x3fffffffffffffe0, //  -(2^62-2^5)      //# 220: compile-time error
+    -0x3fffffffffffffc0, //  -(2^62-2^6)      //# 221: compile-time error
+    -0x3fffffffffffff80, //  -(2^62-2^7)      //# 222: compile-time error
+    -0x3fffffffffffff00, //  -(2^62-2^8)      //# 223: compile-time error
+    -0x4000000000000001, //  -(2^62+2^0)      //# 224: compile-time error
+    -0x4000000000000002, //  -(2^62+2^1)      //# 225: compile-time error
+    -0x4000000000000004, //  -(2^62+2^2)      //# 226: compile-time error
+    -0x4000000000000008, //  -(2^62+2^3)      //# 227: compile-time error
+    -0x4000000000000010, //  -(2^62+2^4)      //# 228: compile-time error
+    -0x4000000000000020, //  -(2^62+2^5)      //# 229: compile-time error
+    -0x4000000000000040, //  -(2^62+2^6)      //# 230: compile-time error
+    -0x4000000000000080, //  -(2^62+2^7)      //# 231: compile-time error
+    -0x4000000000000100, //  -(2^62+2^8)      //# 232: compile-time error
+    -0x4000000000000200, //  -(2^62+2^9)      //# 233: compile-time error
+    -0x7fffffffffffffff, //  -(2^63-2^0)      //# 234: compile-time error
+    -0x7ffffffffffffffe, //  -(2^63-2^1)      //# 235: compile-time error
+    -0x7ffffffffffffffc, //  -(2^63-2^2)      //# 236: compile-time error
+    -0x7ffffffffffffff8, //  -(2^63-2^3)      //# 237: compile-time error
+    -0x7ffffffffffffff0, //  -(2^63-2^4)      //# 238: compile-time error
+    -0x7fffffffffffffe0, //  -(2^63-2^5)      //# 239: compile-time error
+    -0x7fffffffffffffc0, //  -(2^63-2^6)      //# 240: compile-time error
+    -0x7fffffffffffff80, //  -(2^63-2^7)      //# 241: compile-time error
+    -0x7fffffffffffff00, //  -(2^63-2^8)      //# 242: compile-time error
+    -0x7ffffffffffffe00, //  -(2^63-2^9)      //# 243: compile-time error
+    -0x8000000000000001, //  -(2^63+2^0)      //# 244: compile-time error
+    -0x8000000000000002, //  -(2^63+2^1)      //# 245: compile-time error
+    -0x8000000000000004, //  -(2^63+2^2)      //# 246: compile-time error
+    -0x8000000000000008, //  -(2^63+2^3)      //# 247: compile-time error
+    -0x8000000000000010, //  -(2^63+2^4)      //# 248: compile-time error
+    -0x8000000000000020, //  -(2^63+2^5)      //# 249: compile-time error
+    -0x8000000000000040, //  -(2^63+2^6)      //# 250: compile-time error
+    -0x8000000000000080, //  -(2^63+2^7)      //# 251: compile-time error
+    -0x8000000000000100, //  -(2^63+2^8)      //# 252: compile-time error
+    -0x8000000000000200, //  -(2^63+2^9)      //# 253: compile-time error
+    -0x8000000000000400, //  -(2^63+2^10)     //# 254: compile-time error
+    -0xffffffffffffffff, //  -(2^64-2^0)      //# 255: compile-time error
+    -0xfffffffffffffffe, //  -(2^64-2^1)      //# 256: compile-time error
+    -0xfffffffffffffffc, //  -(2^64-2^2)      //# 257: compile-time error
+    -0xfffffffffffffff8, //  -(2^64-2^3)      //# 258: compile-time error
+    -0xfffffffffffffff0, //  -(2^64-2^4)      //# 259: compile-time error
+    -0xffffffffffffffe0, //  -(2^64-2^5)      //# 260: compile-time error
+    -0xffffffffffffffc0, //  -(2^64-2^6)      //# 261: compile-time error
+    -0xffffffffffffff80, //  -(2^64-2^7)      //# 262: compile-time error
+    -0xffffffffffffff00, //  -(2^64-2^8)      //# 263: compile-time error
+    -0xfffffffffffffe00, //  -(2^64-2^9)      //# 264: compile-time error
+    -0xfffffffffffffc00, //  -(2^64-2^10)     //# 265: compile-time error
+    -0x10000000000000001, // -(2^64+2^0)      //# 266: compile-time error
+    -0x10000000000000002, // -(2^64+2^1)      //# 267: compile-time error
+    -0x10000000000000004, // -(2^64+2^2)      //# 268: compile-time error
+    -0x10000000000000008, // -(2^64+2^3)      //# 269: compile-time error
+    -0x10000000000000010, // -(2^64+2^4)      //# 270: compile-time error
+    -0x10000000000000020, // -(2^64+2^5)      //# 271: compile-time error
+    -0x10000000000000040, // -(2^64+2^6)      //# 272: compile-time error
+    -0x10000000000000080, // -(2^64+2^7)      //# 273: compile-time error
+    -0x10000000000000100, // -(2^64+2^8)      //# 274: compile-time error
+    -0x10000000000000200, // -(2^64+2^9)      //# 275: compile-time error
+    -0x10000000000000400, // -(2^64+2^10)     //# 276: compile-time error
+    -0x10000000000000800, // -(2^64+2^11)     //# 277: compile-time error
+    -0xfffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, // -(maxValue - 1) //# 278 : compile-time error
+    -0xfffffffffffff800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001, // -(maxValue + 1) //# 279 : compile-time error
+    -0x1fffffffffffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001, // -(maxValue * 2) //# 280 : compile-time error
   );
 }
diff --git a/tests/language_2/double_literals/double_literal_coercion_test.dart b/tests/language_2/double_literals/double_literal_coercion_test.dart
index 9c2cc91..3eaf06f 100644
--- a/tests/language_2/double_literals/double_literal_coercion_test.dart
+++ b/tests/language_2/double_literals/double_literal_coercion_test.dart
@@ -26,6 +26,8 @@
 main() {
   expectDouble(0.0, 0);
   expectDouble(1.0, 1);
+  expectDouble(0.0, 00);
+  expectDouble(1.0, 01);
   expectDouble(p2_8 - 1, 255);
   expectDouble(p2_8, 256);
   expectDouble(p2_8 + 1, 257);
@@ -55,6 +57,8 @@
 
   expectDouble(-0.0, -0);
   expectDouble(-1.0, -1);
+  expectDouble(-0.0, -00);
+  expectDouble(-1.0, -01);
   expectDouble(-(p2_8 - 1), -255);
   expectDouble(-(p2_8), -256);
   expectDouble(-(p2_8 + 1), -257);
@@ -84,6 +88,8 @@
 
   expectDouble(0.0, 0x0);
   expectDouble(1.0, 0x1);
+  expectDouble(0.0, 0x00);
+  expectDouble(1.0, 0x01);
   expectDouble(p2_8 - 1, 0xff);
   expectDouble(p2_8, 0x100);
   expectDouble(p2_8 + 1, 0x101);
@@ -113,6 +119,8 @@
 
   expectDouble(-0.0, -0x0);
   expectDouble(-1.0, -0x1);
+  expectDouble(-0.0, -0x00);
+  expectDouble(-1.0, -0x01);
   expectDouble(-(p2_8 - 1), -0xff);
   expectDouble(-(p2_8), -0x100);
   expectDouble(-(p2_8 + 1), -0x101);
diff --git a/tests/language_2/double_literals/implicit_double_context_test.dart b/tests/language_2/double_literals/implicit_double_context_test.dart
new file mode 100644
index 0000000..a2cdd02
--- /dev/null
+++ b/tests/language_2/double_literals/implicit_double_context_test.dart
@@ -0,0 +1,683 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "dart:async" show FutureOr;
+
+import "package:expect/expect.dart";
+
+// Check that integer literals in a double context are allowed
+// for various double context.
+
+main() {
+  // Variable initializer context.
+  double v1 = 0;
+  Expect.identical(0.0, v1);
+  double v2 = 1;
+  Expect.identical(1.0, v2);
+  double v3 = -0;
+  Expect.identical(-0.0, v3);
+  double v4 = -1;
+  Expect.identical(-1.0, v4);
+  double v5 = 9223372036854775808; // 2^63, not valid signed 64-bit integer.
+  Expect.identical(9223372036854775808.0, v5);
+  double v6 = 18446744073709551616; // 2^64.
+  Expect.identical(18446744073709551616.0, v6);
+  double v7 = 0x02; // Hex literal.
+  Expect.identical(2.0, v7);
+  double v8 = -0x02; // Hex literal.
+  Expect.identical(-2.0, v8);
+
+  // Const variable initializer context.
+  const double c1 = 0;
+  Expect.identical(0.0, c1);
+  const double c2 = 1;
+  Expect.identical(1.0, c2);
+  const double c3 = -0;
+  Expect.identical(-0.0, c3);
+  const double c4 = -1;
+  Expect.identical(-1.0, c4);
+  const double c5 = 9223372036854775808;
+  Expect.identical(9223372036854775808.0, c5);
+  const double c6 = 18446744073709551616;
+  Expect.identical(18446744073709551616.0, c6);
+  const double c7 = 0x02; // Hex literal.
+  Expect.identical(2.0, c7);
+  const double c8 = -0x02; // Hex literal.
+  Expect.identical(-2.0, c8);
+
+  // Assignment context, variable.
+  double value;
+  value = 0;
+  Expect.identical(0.0, value);
+  value = 1;
+  Expect.identical(1.0, value);
+  value = -0;
+  Expect.identical(-0.0, value);
+  value = -1;
+  Expect.identical(-1.0, value);
+  value = 9223372036854775808;
+  Expect.identical(9223372036854775808.0, value);
+  value = 18446744073709551616;
+  Expect.identical(18446744073709551616.0, value);
+  value = 0x02;
+  Expect.identical(2.0, value);
+  value = -0x02;
+  Expect.identical(-2.0, value);
+
+  // Assignment context, setter.
+  setter = 0;
+  Expect.identical(0.0, lastSetValue);
+  setter = 1;
+  Expect.identical(1.0, lastSetValue);
+  setter = -0;
+  Expect.identical(-0.0, lastSetValue);
+  setter = -1;
+  Expect.identical(-1.0, lastSetValue);
+  setter = 9223372036854775808;
+  Expect.identical(9223372036854775808.0, lastSetValue);
+  setter = 18446744073709551616;
+  Expect.identical(18446744073709551616.0, lastSetValue);
+  setter = 0x02;
+  Expect.identical(2.0, lastSetValue);
+  setter = -0x02;
+  Expect.identical(-2.0, lastSetValue);
+
+  // Argument context.
+  test(0.0, 0);
+  test(1.0, 1);
+  test(-0.0, -0);
+  test(-1.0, -1);
+  test(9223372036854775808.0, 9223372036854775808);
+  test(18446744073709551616.0, 18446744073709551616);
+  test(2.0, 0x02);
+  test(-2.0, -0x02);
+
+  // Argument context, operator setter.
+  List<double> box = [0.5];
+  box[0] = 0;
+  Expect.identical(0.0, box[0]);
+  box[0] = 1;
+  Expect.identical(1.0, box[0]);
+  box[0] = -0;
+  Expect.identical(-0.0, box[0]);
+  box[0] = -1;
+  Expect.identical(-1.0, box[0]);
+  box[0] = 9223372036854775808;
+  Expect.identical(9223372036854775808.0, box[0]);
+  box[0] = 18446744073709551616;
+  Expect.identical(18446744073709551616.0, box[0]);
+  box[0] = 0x02;
+  Expect.identical(2.0, box[0]);
+  box[0] = -0x02;
+  Expect.identical(-2.0, box[0]);
+
+  // Argument context, custom operators.
+  var oper = Oper();
+  Expect.identical(0.0, oper + 0);
+  Expect.identical(1.0, oper + 1);
+  Expect.identical(-0.0, oper + -0);
+  Expect.identical(-1.0, oper + -1);
+  Expect.identical(9223372036854775808.0, oper + 9223372036854775808);
+  Expect.identical(18446744073709551616.0, oper + 18446744073709551616);
+  Expect.identical(2.0, oper + 0x02);
+  Expect.identical(-2.0, oper + -0x02);
+
+  Expect.identical(0.0, oper >> 0);
+  Expect.identical(1.0, oper >> 1);
+  Expect.identical(-0.0, oper >> -0);
+  Expect.identical(-1.0, oper >> -1);
+  Expect.identical(9223372036854775808.0, oper >> 9223372036854775808);
+  Expect.identical(18446744073709551616.0, oper >> 18446744073709551616);
+  Expect.identical(2.0, oper >> 0x02);
+  Expect.identical(-2.0, oper >> -0x02);
+
+  Expect.identical(0.0, oper[0]);
+  Expect.identical(1.0, oper[1]);
+  Expect.identical(-0.0, oper[-0]);
+  Expect.identical(-1.0, oper[-1]);
+  Expect.identical(9223372036854775808.0, oper[9223372036854775808]);
+  Expect.identical(18446744073709551616.0, oper[18446744073709551616]);
+  Expect.identical(2.0, oper[0x02]);
+  Expect.identical(-2.0, oper[-0x02]);
+
+  // Explicit return context.
+  double fun1() => 0;
+  Expect.identical(0.0, fun1());
+  double fun2() => 1;
+  Expect.identical(1.0, fun2());
+  double fun3() => -0;
+  Expect.identical(-0.0, fun3());
+  double fun4() => -1;
+  Expect.identical(-1.0, fun4());
+  double fun5() => 9223372036854775808;
+  Expect.identical(9223372036854775808.0, fun5());
+  double fun6() => 18446744073709551616;
+  Expect.identical(18446744073709551616.0, fun6());
+  double fun7() => 0x02;
+  Expect.identical(2.0, fun7());
+  double fun4() => -0x02;
+  Expect.identical(-120, fun4());
+
+  // Inferred return context.
+  testFun(0.0, () => 0);
+  testFun(1.0, () => 1);
+  testFun(-0.0, () => -0);
+  testFun(-1.0, () => -1);
+  testFun(9223372036854775808.0, () => 9223372036854775808);
+  testFun(18446744073709551616.0, () => 18446744073709551616);
+  testFun(2.0, () => 0x02);
+  testFun(-2.0, () => -0x02);
+
+  // Function default value context.
+  Object deffun1([double v = 0]) => v;
+  Expect.identical(0.0, deffun1());
+  Object deffun2([double v = 1]) => v;
+  Expect.identical(1.0, deffun2());
+  Object deffun3([double v = -0]) => v;
+  Expect.identical(-0.0, deffun3());
+  Object deffun4([double v = -1]) => v;
+  Expect.identical(-1.0, deffun4());
+  Object deffun5([double v = 9223372036854775808]) => v;
+  Expect.identical(9223372036854775808.0, deffun5());
+  Object deffun6([double v = 18446744073709551616]) => v;
+  Expect.identical(18446744073709551616.0, deffun6());
+  Object deffun7([double v = 0x02]) => v;
+  Expect.identical(2.0, deffun7());
+  Object deffun8([double v = -0x02]) => v;
+  Expect.identical(-2.0, deffun8());
+
+  // Explicit collection literal context.
+  box = <double>[0];
+  Expect.identical(0.0, box[0]);
+  box = <double>[1];
+  Expect.identical(1.0, box[0]);
+  box = <double>[-0];
+  Expect.identical(-0.0, box[0]);
+  box = <double>[-1];
+  Expect.identical(-1.0, box[0]);
+  box = <double>[9223372036854775808];
+  Expect.identical(9223372036854775808.0, box[0]);
+  box = <double>[18446744073709551616];
+  Expect.identical(18446744073709551616.0, box[0]);
+  box = <double>[0x02];
+  Expect.identical(2.0, box[0]);
+  box = <double>[-0x02];
+  Expect.identical(-2.0, box[0]);
+
+  // Implicit collection literal context.
+  box = [0];
+  Expect.identical(0.0, box[0]);
+  box = [1];
+  Expect.identical(1.0, box[0]);
+  box = [-0];
+  Expect.identical(-0.0, box[0]);
+  box = [-1];
+  Expect.identical(-1.0, box[0]);
+  box = [9223372036854775808];
+  Expect.identical(9223372036854775808.0, box[0]);
+  box = [18446744073709551616];
+  Expect.identical(18446744073709551616.0, box[0]);
+  box = [0x02];
+  Expect.identical(2.0, box[0]);
+  box = [-0x02];
+  Expect.identical(-2.0, box[0]);
+
+  Map<double, double> map;
+  // Explicit map key context.
+  map = <double, Null>{0: null};
+  Expect.identical(0.0, map.keys.first);
+  map = <double, Null>{1: null};
+  Expect.identical(1.0, map.keys.first);
+  map = <double, Null>{-0: null};
+  Expect.identical(-0.0, map.keys.first);
+  map = <double, Null>{-1: null};
+  Expect.identical(-1.0, map.keys.first);
+  map = <double, Null>{9223372036854775808: null};
+  Expect.identical(9223372036854775808.0, map.keys.first);
+  map = <double, Null>{18446744073709551616: null};
+  Expect.identical(18446744073709551616.0, map.keys.first);
+  map = <double, Null>{0x02: null};
+  Expect.identical(2.0, map.keys.first);
+  map = <double, Null>{-0x02: null};
+  Expect.identical(-2.0, map.keys.first);
+
+  // Implicit map key context.
+  map = {0: null};
+  Expect.identical(0.0, map.keys.first);
+  map = {1: null};
+  Expect.identical(1.0, map.keys.first);
+  map = {-0: null};
+  Expect.identical(-0.0, map.keys.first);
+  map = {-1: null};
+  Expect.identical(-1.0, map.keys.first);
+  map = {9223372036854775808: null};
+  Expect.identical(9223372036854775808.0, map.keys.first);
+  map = {18446744073709551616: null};
+  Expect.identical(18446744073709551616.0, map.keys.first);
+  map = {0x02: null};
+  Expect.identical(2.0, map.keys.first);
+  map = {-0x02: null};
+  Expect.identical(-2.0, map.keys.first);
+
+  // Explicit map value context.
+  map = <Null, double>{null: 0};
+  Expect.identical(0.0, map.values.first);
+  map = <Null, double>{null: 1};
+  Expect.identical(1.0, map.values.first);
+  map = <Null, double>{null: -0};
+  Expect.identical(-0.0, map.values.first);
+  map = <Null, double>{null: -1};
+  Expect.identical(-1.0, map.values.first);
+  map = <Null, double>{null: 9223372036854775808};
+  Expect.identical(9223372036854775808.0, map.values.first);
+  map = <Null, double>{null: 18446744073709551616};
+  Expect.identical(18446744073709551616.0, map.values.first);
+  map = <Null, double>{null: 0x02};
+  Expect.identical(2.0, map.values.first);
+  map = <Null, double>{null: -0x02};
+  Expect.identical(-2.0, map.values.first);
+
+  // Implicit map value context.
+  map = {null: 0};
+  Expect.identical(0.0, map.values.first);
+  map = {null: 1};
+  Expect.identical(1.0, map.values.first);
+  map = {null: -0};
+  Expect.identical(-0.0, map.values.first);
+  map = {null: -1};
+  Expect.identical(-1.0, map.values.first);
+  map = {null: 9223372036854775808};
+  Expect.identical(9223372036854775808.0, map.values.first);
+  map = {null: 18446744073709551616};
+  Expect.identical(18446744073709551616.0, map.values.first);
+  map = {null: 0x02};
+  Expect.identical(2.0, map.values.first);
+  map = {null: -0x02};
+  Expect.identical(-2.0, map.values.first);
+
+  // Top-level contexts
+  Expect.identical(0.0, ts1);
+  Expect.identical(1.0, ts2);
+  Expect.identical(-0.0, ts3);
+  Expect.identical(-1.0, ts4);
+  Expect.identical(9223372036854775808.0, ts5);
+  Expect.identical(18446744073709551616.0, ts6);
+  Expect.identical(2.0, ts7);
+  Expect.identical(-2.0, ts8);
+
+  Expect.identical(0.0, tc1);
+  Expect.identical(1.0, tc2);
+  Expect.identical(-0.0, tc3);
+  Expect.identical(-1.0, tc4);
+  Expect.identical(9223372036854775808.0, tc5);
+  Expect.identical(18446744073709551616.0, tc6);
+  Expect.identical(2.0, tc7);
+  Expect.identical(-2.0, tc8);
+
+  Expect.identical(0.0, tg1);
+  Expect.identical(1.0, tg2);
+  Expect.identical(-0.0, tg3);
+  Expect.identical(-1.0, tg4);
+  Expect.identical(9223372036854775808.0, tg5);
+  Expect.identical(18446744073709551616.0, tg6);
+  Expect.identical(2.0, tg7);
+  Expect.identical(-2.0, tg8);
+
+  // Class contexts
+  var c = new C();
+  Expect.identical(0.0, c.v1);
+  Expect.identical(1.0, c.v2);
+  Expect.identical(-0.0, c.v3);
+  Expect.identical(-1.0, c.v4);
+  Expect.identical(9223372036854775808.0, c.v5);
+  Expect.identical(18446744073709551616.0, c.v6);
+  Expect.identical(2.0, c.v7);
+  Expect.identical(-2.0, c.v8);
+
+  Expect.identical(0.0, C.s1);
+  Expect.identical(1.0, C.s2);
+  Expect.identical(-0.0, C.s3);
+  Expect.identical(-1.0, C.s4);
+  Expect.identical(9223372036854775808.0, C.s5);
+  Expect.identical(18446744073709551616.0, C.s6);
+  Expect.identical(2.0, C.s7);
+  Expect.identical(-2.0, C.s8);
+
+  Expect.identical(0.0, C.c1);
+  Expect.identical(1.0, C.c2);
+  Expect.identical(-0.0, C.c3);
+  Expect.identical(-1.0, C.c4);
+  Expect.identical(9223372036854775808.0, C.c5);
+  Expect.identical(18446744073709551616.0, C.c6);
+  Expect.identical(2.0, C.c7);
+  Expect.identical(-2.0, C.c8);
+
+  Expect.identical(0.0, new C.cc1().d);
+  Expect.identical(1.0, new C.cc2().d);
+  Expect.identical(-0.0, new C.cc3().d);
+  Expect.identical(-1.0, new C.cc4().d);
+  Expect.identical(9223372036854775808.0, new C.cc5().d);
+  Expect.identical(18446744073709551616.0, new C.cc6().d);
+  Expect.identical(2.0, new C.cc7().d);
+  Expect.identical(-2.0, new C.cc8().d);
+
+  Expect.identical(0.0, const C.cc1().d);
+  Expect.identical(1.0, const C.cc2().d);
+  Expect.identical(-0.0, const C.cc3().d);
+  Expect.identical(-1.0, const C.cc4().d);
+  Expect.identical(9223372036854775808.0, const C.cc5().d);
+  Expect.identical(18446744073709551616.0, const C.cc6().d);
+  Expect.identical(2.0, const C.cc7().d);
+  Expect.identical(-2.0, const C.cc8().d);
+
+  Expect.identical(0.0, new C.ci1().d);
+  Expect.identical(1.0, new C.ci2().d);
+  Expect.identical(-0.0, new C.ci3().d);
+  Expect.identical(-1.0, new C.ci4().d);
+  Expect.identical(9223372036854775808.0, new C.ci5().d);
+  Expect.identical(18446744073709551616.0, new C.ci6().d);
+  Expect.identical(2.0, new C.ci7().d);
+  Expect.identical(-2.0, new C.ci8().d);
+
+  Expect.identical(0.0, const C.ci1().d);
+  Expect.identical(1.0, const C.ci2().d);
+  Expect.identical(-0.0, const C.ci3().d);
+  Expect.identical(-1.0, const C.ci4().d);
+  Expect.identical(9223372036854775808.0, const C.ci5().d);
+  Expect.identical(18446744073709551616.0, const C.ci6().d);
+  Expect.identical(2.0, const C.ci7().d);
+  Expect.identical(-2.0, const C.ci8().d);
+
+  // Nested context, `?:`.
+  v1 = false ? 42.0 : 0;
+  Expect.identical(0.0, v1);
+  v2 = false ? 42.0 : 1;
+  Expect.identical(1.0, v2);
+  v3 = false ? 42.0 : -0;
+  Expect.identical(-0.0, v3);
+  v4 = false ? 42.0 : -1;
+  Expect.identical(-1.0, v4);
+  v5 = false ? 42.0 : 9223372036854775808;
+  Expect.identical(9223372036854775808.0, v5);
+  v6 = false ? 42.0 : 18446744073709551616;
+  Expect.identical(18446744073709551616.0, v6);
+  v7 = false ? 42.0 : 0x02; // Hex literal.
+  Expect.identical(2.0, v7);
+  v8 = false ? 42.0 : -0x02; // Hex literal.
+  Expect.identical(-2.0, v8);
+
+  // Nested context, `??`.
+  double nl = double.tryParse("not a double"); // Returns null typed as double.
+  v1 = nl ?? 0;
+  Expect.identical(0.0, v1);
+  v2 = nl ?? 1;
+  Expect.identical(1.0, v2);
+  v3 = nl ?? -0;
+  Expect.identical(-0.0, v3);
+  v4 = nl ?? -1;
+  Expect.identical(-1.0, v4);
+  v5 = nl ?? 9223372036854775808;
+  Expect.identical(9223372036854775808.0, v5);
+  v6 = nl ?? 18446744073709551616;
+  Expect.identical(18446744073709551616.0, v6);
+  v7 = nl ?? 0x02; // Hex literal.
+  Expect.identical(2.0, v7);
+  v8 = nl ?? -0x02; // Hex literal.
+  Expect.identical(-2.0, v8);
+
+  // Nested context, `..`.
+  v1 = 0..toString();
+  Expect.identical(0.0, v1);
+  v2 = 1..toString();
+  Expect.identical(1.0, v2);
+  v3 = -0
+    ..toString();
+  Expect.identical(-0.0, v3);
+  v4 = -1
+    ..toString();
+  Expect.identical(-1.0, v4);
+  v5 = 9223372036854775808..toString();
+  Expect.identical(9223372036854775808.0, v5);
+  v6 = 18446744073709551616..toString();
+  Expect.identical(18446744073709551616.0, v6);
+  v7 = 0x02..toString(); // Hex literal.
+  Expect.identical(2.0, v7);
+  v8 = -0x02
+    ..toString(); // Hex literal.
+  Expect.identical(-2.0, v8);
+
+  // Nexted context, double assignment.
+  Object object;
+  object = value = 0;
+  Expect.identical(0.0, value);
+  object = value = 1;
+  Expect.identical(1.0, value);
+  object = value = -0;
+  Expect.identical(-0.0, value);
+  object = value = -1;
+  Expect.identical(-1.0, value);
+  object = value = 9223372036854775808;
+  Expect.identical(9223372036854775808.0, value);
+  object = value = 18446744073709551616;
+  Expect.identical(18446744073709551616.0, value);
+  object = value = 0x02;
+  Expect.identical(2.0, value);
+  object = value = -0x02;
+  Expect.identical(-2.0, value);
+
+  // Nested context, value of assignment.
+  Expect.identical(0.0, value = 0);
+  Expect.identical(1.0, value = 1);
+  Expect.identical(-0.0, value = -0);
+  Expect.identical(-1.0, value = -1);
+  Expect.identical(9223372036854775808.0, value = 9223372036854775808);
+  Expect.identical(18446744073709551616.0, value = 18446744073709551616);
+  Expect.identical(2.0, value = 0x02);
+  Expect.identical(-2.0, value = -0x02);
+
+  // Not promoted without a double context.
+  num x = -0;
+  Expect.identical(0, x);
+  Expect.isFalse(x.isNegative);
+
+  var list = [3.14, 2.17, -0];
+  Expect.notType<List<double>>(list);
+  Expect.identical(0, list[2]);
+  Expect.isFalse(list[2].isNegative);
+
+  // FutureOr<double> also forces double.
+  // "Type that int is not assignable to, but double is."
+  FutureOr<double> fo1 = 0;
+  Expect.identical(0.0, fo1);
+  FutureOr<double> fo2 = 1;
+  Expect.identical(1.0, fo2);
+  FutureOr<double> fo3 = -0;
+  Expect.identical(-0.0, fo3);
+  FutureOr<double> fo4 = -1;
+  Expect.identical(-1.0, fo4);
+  FutureOr<double> fo5 = 9223372036854775808;
+  Expect.identical(9223372036854775808.0, fo5);
+  FutureOr<double> fo6 = 18446744073709551616;
+  Expect.identical(18446744073709551616.0, fo6);
+  FutureOr<double> fo7 = 0x02; // Hex literal.
+  Expect.identical(2.0, fo7);
+  FutureOr<double> fo8 = -0x02; // Hex literal.
+  Expect.identical(-2.0, fo8);
+
+  // Some other FutureOr cases, without being exhaustive.
+  {
+    Object func([FutureOr<double> x = 9223372036854775808]) => x;
+    Expect.identical(9223372036854775808.0, func(9223372036854775808));
+    Expect.identical(9223372036854775808.0, func());
+    FutureOr<double> func2() => 9223372036854775808;
+    Expect.identical(9223372036854775808.0, func2());
+    testGeneric<FutureOr<double>>(9223372036854775808.0, 9223372036854775808);
+    List<FutureOr<double>> l = [9223372036854775808];
+    testGeneric<FutureOr<double>>(9223372036854775808.0, l[0]);
+    l.add(9223372036854775808);
+    testGeneric<FutureOr<double>>(9223372036854775808.0, l[1]);
+    l.add(0.0);
+    l[2] = 9223372036854775808;
+    testGeneric<FutureOr<double>>(9223372036854775808.0, l[2]);
+  }
+
+  // Type variables statically bound to double also force doubles:
+  testGeneric<double>(0.0, 0);
+  testGeneric<double>(1.0, 1);
+  testGeneric<double>(-0.0, -0);
+  testGeneric<double>(-1.0, -1);
+  testGeneric<double>(9223372036854775808.0, 9223372036854775808);
+  testGeneric<double>(18446744073709551616.0, 18446744073709551616);
+  testGeneric<double>(2.0, 0x02);
+  testGeneric<double>(-2.0, -0x02);
+
+  // Uses static type, not run-time type.
+  Super sub = Sub();
+  Expect.identical(0.0, sub.method(0));
+  Expect.identical(1.0, sub.method(1));
+  Expect.identical(-0.0, sub.method(-0));
+  Expect.identical(-1.0, sub.method(-1));
+  Expect.identical(9223372036854775808.0, sub.method(9223372036854775808));
+  Expect.identical(18446744073709551616.0, sub.method(18446744073709551616));
+  Expect.identical(2.0, sub.method(0x02));
+  Expect.identical(-2.0, sub.method(-0x02));
+
+  {
+    // Check that the correct value is used as receiver for the cascade.
+    var collector = StringBuffer();
+    double tricky = -42
+      ..toString().codeUnits.forEach(collector.addCharCode);
+    Expect.equals("${-42.0}", collector.toString());
+  }
+
+  bool isDigit(int charCode) => (charCode ^ 0x30) <= 9;
+  // Throws because double context does not affect "4", so the toString does
+  // not contain any non-digit (like ".", which it would if 4 was a double).
+  // The context type of "4.toString..." is not double, and the `-`
+  // is not having a literal as operand.
+  Expect.throws(() {
+    double tricky =
+        -4.toString().codeUnits.firstWhere((c) => !isDigit(c)).toDouble();
+  });
+  // The `?.` operation has the same precedence as `.`.
+  Expect.throws(() {
+    double tricky =
+        -4?.toString().codeUnits.firstWhere((c) => !isDigit(c)).toDouble();
+  });
+}
+
+void test(double expect, double value) {
+  Expect.identical(expect, value);
+}
+
+void testFun(double expect, double f()) {
+  Expect.identical(expect, f());
+}
+
+void testGeneric<T>(double expect, T value) {
+  Expect.identical(expect, value);
+}
+
+class Oper {
+  Object operator +(double value) => value;
+  Object operator >>(double value) => value;
+  Object operator [](double value) => value;
+}
+
+class C {
+  // Instance variable initializer
+  final double v1 = 0;
+  final double v2 = 1;
+  final double v3 = -0;
+  final double v4 = -1;
+  final double v5 = 9223372036854775808;
+  final double v6 = 18446744073709551616;
+  final double v7 = 0x02; // Hex literal.
+  final double v8 = -0x02; // Hex literal.
+
+  // Static class variable initializer
+  static double s1 = 0;
+  static double s2 = 1;
+  static double s3 = -0;
+  static double s4 = -1;
+  static double s5 = 9223372036854775808;
+  static double s6 = 18446744073709551616;
+  static double s7 = 0x02; // Hex literal.
+  static double s8 = -0x02; // Hex literal.
+
+  // Const class variable initializer context.
+  static const double c1 = 0;
+  static const double c2 = 1;
+  static const double c3 = -0;
+  static const double c4 = -1;
+  static const double c5 = 9223372036854775808;
+  static const double c6 = 18446744073709551616;
+  static const double c7 = 0x02; // Hex literal.
+  static const double c8 = -0x02; // Hex literal.
+
+  final double d;
+
+  // Default value context for a double initializing formal.
+  const C.cc1([this.d = 0]);
+  const C.cc2([this.d = 1]);
+  const C.cc3([this.d = -0]);
+  const C.cc4([this.d = -1]);
+  const C.cc5([this.d = 9223372036854775808]);
+  const C.cc6([this.d = 18446744073709551616]);
+  const C.cc7([this.d = 0x02]);
+  const C.cc8([this.d = -0x02]);
+
+  // Initializer list expressions context.
+  const C.ci1() : this.d = 0;
+  const C.ci2() : this.d = 1;
+  const C.ci3() : this.d = -0;
+  const C.ci4() : this.d = -1;
+  const C.ci5() : this.d = 9223372036854775808;
+  const C.ci6() : this.d = 18446744073709551616;
+  const C.ci7() : this.d = 0x02;
+  const C.ci8() : this.d = -0x02;
+}
+
+// Top-level lazy variable initializer
+double ts1 = 0;
+double ts2 = 1;
+double ts3 = -0;
+double ts4 = -1;
+double ts5 = 9223372036854775808;
+double ts6 = 18446744073709551616;
+double ts7 = 0x02; // Hex literal.
+double ts8 = -0x02; // Hex literal.
+
+// Top-level const variable initializer.
+const double tc1 = 0;
+const double tc2 = 1;
+const double tc3 = -0;
+const double tc4 = -1;
+const double tc5 = 9223372036854775808; // 2^63, invalid signed 64-bit integer.
+const double tc6 = 18446744073709551616;
+const double tc7 = 0x02; // Hex literal.
+const double tc8 = -0x02; // Hex literal.
+
+// Top-level getter return context.
+double get tg1 => 0;
+double get tg2 => 1;
+double get tg3 => -0;
+double get tg4 => -1;
+double get tg5 => 9223372036854775808;
+double get tg6 => 18446744073709551616;
+double get tg7 => 0x02; // Hex literal.
+double get tg8 => -0x02; // Hex literal.
+
+Object lastSetValue = null;
+void set setter(double v) {
+  lastSetValue = v;
+}
+
+abstract class Super {
+  Object method(double v);
+}
+
+class Sub implements Super {
+  Object method(Object o) => o;
+}
diff --git a/tests/language_2/inference_enum_list_test.dart b/tests/language_2/inference_enum_list_test.dart
new file mode 100644
index 0000000..dc7b7bd3
--- /dev/null
+++ b/tests/language_2/inference_enum_list_test.dart
@@ -0,0 +1,14 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+enum E1 { a, b }
+enum E2 { a, b }
+
+var v = [E1.a, E2.b];
+
+main() {
+  // Test that v is `List<Object>`, so any of these assignemnts are OK.
+  v[0] = 0;
+  v[1] = '1';
+}
diff --git a/tests/language_2/invalid_returns/async_valid_returns.dart b/tests/language_2/invalid_returns/async_valid_returns_test.dart
similarity index 96%
rename from tests/language_2/invalid_returns/async_valid_returns.dart
rename to tests/language_2/invalid_returns/async_valid_returns_test.dart
index f5ca755..649f2c9 100644
--- a/tests/language_2/invalid_returns/async_valid_returns.dart
+++ b/tests/language_2/invalid_returns/async_valid_returns_test.dart
@@ -20,7 +20,6 @@
 FutureOr<Null> fovn = null;
 FutureOr<int> fovi = null;
 
-
 /* Test the cases where expression bodied functions are more permissive
  * than block bodied functions (places where they behave the same
  * are tested below).
@@ -32,7 +31,6 @@
   with return type `T` as defined below.
 */
 
-  
 void async_int_to_void_e() async => vi;
 Future<void> async_int_to_Future_void__e() async => vi;
 FutureOr<void> async_int_to_FutureOr_void__e() async => vi;
@@ -343,42 +341,34 @@
   return fvi;
 }
 
-Future<void> async_int_to_Future_void__e() async => vi;
 Future<void> async_int_to_Future_void_() async {
   return vi;
 }
 
-Future<void> async_Object_to_Future_void__e() async => vo;
 Future<void> async_Object_to_Future_void_() async {
   return vo;
 }
 
-Future<void> async_FutureOr_int__to_Future_void__e() async => fovi;
 Future<void> async_FutureOr_int__to_Future_void_() async {
   return fovi;
 }
 
-Future<void> async_Future_int__to_Future_void__e() async => fvi;
 Future<void> async_Future_int__to_Future_void_() async {
   return fvi;
 }
 
-FutureOr<void> async_int_to_FutureOr_void__e() async => vi;
 FutureOr<void> async_int_to_FutureOr_void_() async {
   return vi;
 }
 
-FutureOr<void> async_Object_to_FutureOr_void__e() async => vo;
 FutureOr<void> async_Object_to_FutureOr_void_() async {
   return vo;
 }
 
-FutureOr<void> async_FutureOr_int__to_FutureOr_void__e() async => fovi;
 FutureOr<void> async_FutureOr_int__to_FutureOr_void_() async {
   return fovi;
 }
 
-FutureOr<void> async_Future_int__to_FutureOr_void__e() async => fvi;
 FutureOr<void> async_Future_int__to_FutureOr_void_() async {
   return fvi;
 }
diff --git a/tests/language_2/invalid_returns/sync_valid_returns.dart b/tests/language_2/invalid_returns/sync_valid_returns_test.dart
similarity index 99%
rename from tests/language_2/invalid_returns/sync_valid_returns.dart
rename to tests/language_2/invalid_returns/sync_valid_returns_test.dart
index 3ae76ff..ba3842d 100644
--- a/tests/language_2/invalid_returns/sync_valid_returns.dart
+++ b/tests/language_2/invalid_returns/sync_valid_returns_test.dart
@@ -37,7 +37,6 @@
 void sync_Future_Object__to_void_e() => fvo;
 void sync_FutureOr_Object__to_void_e() => fovo;
 
-
 /* Test the cases that apply only to block bodied  functions
  */
 
@@ -62,8 +61,6 @@
 /* Test the cases that apply to both expression bodied and block bodied
  * functions
  */
-  
-
 
 /*
 * `return exp;` where `exp` has static type `S` is a valid return if:
diff --git a/tests/language_2/issue34488_test.dart b/tests/language_2/issue34488_test.dart
new file mode 100644
index 0000000..4954abe
--- /dev/null
+++ b/tests/language_2/issue34488_test.dart
@@ -0,0 +1,32 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+abstract class Base {
+  void f(int i);
+  void g([int i]);
+  void h({int i});
+}
+
+abstract class Mixin implements Base {}
+
+class Derived extends Object with Mixin {
+  // Type `(int) -> void` should be inherited from `Base`
+  f(i) {}
+
+  // Type `([int]) -> void` should be inherited from `Base`
+  g([i]) {}
+
+  // Type `({h: int}) -> void` should be inherited from `Base`
+  h({i}) {}
+}
+
+main() {
+  var d = new Derived();
+  d.f('bad'); //# 01: compile-time error
+  d.g('bad'); //# 02: compile-time error
+  d.h(i: 'bad'); //# 03: compile-time error
+  Object x = d.f(1); //# 04: compile-time error
+  Object y = d.g(1); //# 05: compile-time error
+  Object z = d.h(i: 1); //# 06: compile-time error
+}
diff --git a/tests/language_2/language_2.status b/tests/language_2/language_2.status
index f4293613..84a6412 100644
--- a/tests/language_2/language_2.status
+++ b/tests/language_2/language_2.status
@@ -2,17 +2,19 @@
 # for details. All rights reserved. Use of this source code is governed by a
 # BSD-style license that can be found in the LICENSE file.
 
+[ $compiler == app_jit ]
+deferred_inheritance_constraints_test/redirecting_constructor: Crash
+
+[ $compiler != compare_analyzer_cfe ]
 bug34235_test/01: MissingCompileTimeError # Issue 34235
 mixin_constructor_forwarding/const_constructor_test/none: CompileTimeError # Issue 32223
 mixin_constructor_forwarding/const_constructor_with_field_test/none: CompileTimeError # Issue 32223
 mixin_constructor_forwarding/optional_named_parameters_test/none: CompileTimeError # Issue 31543
 mixin_constructor_forwarding/optional_positional_parameters_test/none: CompileTimeError # Issue 31543
 
-[ $compiler == app_jit ]
-deferred_inheritance_constraints_test/redirecting_constructor: Crash
-
 [ $compiler == dart2analyzer ]
-double_literals/*: Skip # https://github.com/dart-lang/sdk/issues/34360
+double_literals/implicit_double_context_test: CompileTimeError # Needs triage, see Issue #34444
+mixin_declaration/mixin_declaration_inference_valid_classes_test: CompileTimeError # https://github.com/dart-lang/sdk/issues/34164
 
 [ $compiler != dart2analyzer ]
 switch_case_warn_test: Skip # Analyzer only, see language_analyzer2.status
@@ -20,6 +22,7 @@
 [ $compiler == dart2js ]
 double_literals/*: Skip # https://github.com/dart-lang/sdk/issues/34356
 invalid_returns/*: Skip # https://github.com/dart-lang/sdk/issues/34011
+mixin_declaration/*: Skip # See https://github.com/dart-lang/language/issues/7
 void/*: Skip # https://github.com/dart-lang/sdk/issues/34011
 
 [ $compiler == fasta ]
@@ -28,6 +31,7 @@
 [ $compiler == spec_parser ]
 double_literals/*: Skip # https://github.com/dart-lang/sdk/issues/34355
 invalid_returns/*: Skip # https://github.com/dart-lang/sdk/issues/34015
+mixin_declaration/*: Skip # See https://github.com/dart-lang/language/issues/7
 void/*: Skip # https://github.com/dart-lang/sdk/issues/34015
 
 [ $mode == debug ]
@@ -47,12 +51,27 @@
 stacktrace_demangle_ctors_test: SkipByDesign # Names are not scrubbed.
 type_checks_in_factory_method_test: SkipByDesign # Requires checked mode.
 
+[ $fasta ]
+mixin_declaration/mixin_declaration_inference_invalid_05_test: MissingCompileTimeError, DartkCrash # https://github.com/dart-lang/sdk/issues/34165
+mixin_declaration/mixin_declaration_inference_invalid_07_test: MissingCompileTimeError # https://github.com/dart-lang/sdk/issues/34165
+mixin_declaration/mixin_declaration_inference_invalid_10_test: MissingCompileTimeError, DartkCrash # https://github.com/dart-lang/sdk/issues/34165
+partial_instantiation_static_bounds_check_test/01: MissingCompileTimeError # Issue 34327
+partial_instantiation_static_bounds_check_test/02: MissingCompileTimeError # Issue 34327
+partial_instantiation_static_bounds_check_test/03: MissingCompileTimeError # Issue 34327
+
 [ $compiler != app_jitk && $compiler != dartk && $compiler != dartkb && $compiler != dartkp && $mode == debug && $runtime == vm ]
 built_in_identifier_type_annotation_test/set: Crash # Not supported by legacy VM front-end.
 
-[ $compiler != dart2analyzer && $compiler != dart2js && $compiler != dartdevc && !$fasta && $strong ]
+[ $compiler != compare_analyzer_cfe && $compiler != dart2analyzer && $compiler != dart2js && $compiler != dartdevc && !$fasta && $strong ]
 type_promotion_functions_test: CompileTimeError # Issue 30895: This test requires a complete rewrite for 2.0.
 
+[ $compiler != compare_analyzer_cfe && $compiler != dart2js && !$fasta && $strong ]
+compile_time_constant_static5_test/11: CompileTimeError # Issue 30546
+compile_time_constant_static5_test/16: CompileTimeError # Issue 30546
+compile_time_constant_static5_test/21: CompileTimeError # Issue 30546
+compile_time_constant_static5_test/23: CompileTimeError # Issue 30546
+type_promotion_more_specific_test/04: CompileTimeError # Issue 30906.
+
 # Detection of compile-time errors that are related to constants can't be fully
 # done at the front end, because constants are evaluated at back ends.  So, some
 # errors aren't detected by fasta, but reported by back ends as compile-time
@@ -74,13 +93,6 @@
 [ $compiler != dart2js && $compiler != dartdevc && !$checked ]
 function_type/*: Skip # Needs checked mode.
 
-[ $compiler != dart2js && !$fasta && $strong ]
-compile_time_constant_static5_test/11: CompileTimeError # Issue 30546
-compile_time_constant_static5_test/16: CompileTimeError # Issue 30546
-compile_time_constant_static5_test/21: CompileTimeError # Issue 30546
-compile_time_constant_static5_test/23: CompileTimeError # Issue 30546
-type_promotion_more_specific_test/04: CompileTimeError # Issue 30906.
-
 [ $compiler != dart2js && !$fasta && !$strong ]
 implicit_creation/implicit_new_constructor_generic_test: Fail # No support for implicit creation.
 implicit_creation/implicit_new_constructor_test: Fail # No support for implicit creation.
diff --git a/tests/language_2/language_2_analyzer.status b/tests/language_2/language_2_analyzer.status
index 01ea12e..97bbdb3 100644
--- a/tests/language_2/language_2_analyzer.status
+++ b/tests/language_2/language_2_analyzer.status
@@ -7,7 +7,6 @@
 [ $compiler == dart2analyzer ]
 abstract_override_adds_optional_args_concrete_subclass_test: MissingCompileTimeError # Issue #30568
 abstract_override_adds_optional_args_concrete_test: MissingCompileTimeError # Issue #30568
-abstract_override_adds_optional_args_supercall_test: MissingCompileTimeError # Issue #30568
 accessor_conflict_export2_test: CompileTimeError # Issue 25626
 accessor_conflict_export_test: CompileTimeError # Issue 25626
 accessor_conflict_import2_test: CompileTimeError # Issue 25626
@@ -15,40 +14,39 @@
 accessor_conflict_import_prefixed_test: CompileTimeError # Issue 25626
 accessor_conflict_import_test: CompileTimeError # Issue 25626
 additional_interface_adds_optional_args_test: CompileTimeError # Issue #30568
-built_in_identifier_prefix_test: CompileTimeError
-cascaded_forwarding_stubs_test: CompileTimeError
-config_import_corelib_test: CompileTimeError
-config_import_corelib_test: StaticWarning, OK
-conflicting_generic_interfaces_hierarchy_loop_infinite_test: Skip # Crashes or times out
-const_cast2_test/01: CompileTimeError
-const_cast2_test/none: CompileTimeError
-constructor_reference_test/27: MissingCompileTimeError # Issue 34270
-default_implementation2_test: CompileTimeError # Issue 30855
-dynamic_prefix_core_test/01: MissingCompileTimeError
-emit_const_fields_test: CompileTimeError
-enum_syntax_test/05: Fail # Issue 21649
-enum_syntax_test/06: Fail # Issue 21649
-forwarding_stub_tearoff_test: CompileTimeError
+cascaded_forwarding_stubs_test: CompileTimeError # Issue 34329
+config_import_corelib_test: CompileTimeError, StaticWarning, OK # failing-by-design: Will never pass, see Issue #34332
+conflicting_generic_interfaces_hierarchy_loop_infinite_test: Skip # Issue #34333 (loops forever)
+const_cast2_test/01: CompileTimeError # failing-by-design: Not a const expression, see Issue #34334
+const_cast2_test/none: CompileTimeError # failing-by-design: Not a const expression, see Issue #34334
+const_constructor3_test/04: MissingCompileTimeError # Side-effect of working around issue 33441 for int-to-double
+constructor_reference_test/27: MissingCompileTimeError # Issue 34403
+covariant_subtyping_with_mixin_test: CompileTimeError # Issue 34329
+default_implementation2_test: CompileTimeError # Issue #34338, however, needs triage (#34337) and blocked (#34336)
+dynamic_prefix_core_test/01: MissingCompileTimeError # failing-by-design: #34339
+emit_const_fields_test: CompileTimeError # failing-by-design: #34340
+enum_syntax_test/05: Fail # Issue 34341
+enum_syntax_test/06: Fail # Issue 34341
+forwarding_stub_tearoff_test: CompileTimeError # Issue 34329
 generic_local_functions_test: CompileTimeError # Issue 28515
 generic_methods_generic_function_parameter_test: CompileTimeError # Issue 28515
 generic_methods_generic_function_result_test/none: CompileTimeError # Issue #30207
-generic_no_such_method_dispatcher_simple_test: Skip # This test is just for kernel.
-generic_no_such_method_dispatcher_test: CompileTimeError
-generic_tearoff_test: CompileTimeError
+generic_no_such_method_dispatcher_simple_test: Skip # failing-by-design: This test is just for kernel
+generic_no_such_method_dispatcher_test: CompileTimeError # failing-by-design: This test needs to be updated for Dart 2, see Issue #34366
+generic_tearoff_test: CompileTimeError # failing-by-design: Analysis of generic function typed parameters is not yet supported
 getter_setter_in_lib_test: Fail # Issue 23286
-getters_setters2_test/01: CompileTimeError
-getters_setters_type_test/01: CompileTimeError
-hidden_import_test/01: MissingStaticWarning # Issue #34302
-hidden_import_test/02: MissingStaticWarning # Issue #34302
-implements_futureor_test/01: MissingCompileTimeError
-implicit_creation/implicit_const_context_constructor_generic_named_test: CompileTimeError
-implicit_creation/implicit_const_context_constructor_generic_test: CompileTimeError
-implicit_creation/implicit_const_context_prefix_constructor_generic_named_test: CompileTimeError
-implicit_creation/implicit_const_context_prefix_constructor_generic_test: CompileTimeError
-index_assign_operator_infer_return_type_test: CompileTimeError
-initializing_formal_final_test: MissingCompileTimeError
-interceptor6_test: CompileTimeError
-interface_test/00: MissingCompileTimeError
+getters_setters2_test/01: CompileTimeError # failing-by-design: Test needs refactoring, see Issue #34365
+getters_setters_type_test/01: CompileTimeError # failing-by-design: Test needs refactoring, see Issue #34365
+hidden_import_test/01: MissingStaticWarning # failing-by-design: invalid test, see Issue #34302
+hidden_import_test/02: MissingStaticWarning # failing-by-design: invalid test, see Issue #34302
+implements_futureor_test/01: MissingCompileTimeError # Issue #33745
+implicit_creation/implicit_const_context_constructor_generic_named_test: CompileTimeError # Issue #34367
+implicit_creation/implicit_const_context_constructor_generic_test: CompileTimeError # Issue #34367
+implicit_creation/implicit_const_context_prefix_constructor_generic_named_test: CompileTimeError # Issue #34367
+implicit_creation/implicit_const_context_prefix_constructor_generic_test: CompileTimeError # Issue #34367
+index_assign_operator_infer_return_type_test: CompileTimeError # failing-by-design: outdated against the spec, see Issue #34368
+initializing_formal_final_test: MissingCompileTimeError # Issue #34369
+interface_test/00: MissingCompileTimeError # Issue #34370
 invalid_returns/async_invalid_return_00_test/none: CompileTimeError # issue #34319
 invalid_returns/async_invalid_return_01_test/none: CompileTimeError # issue #34319
 invalid_returns/async_invalid_return_02_test/none: CompileTimeError # issue #34319
@@ -61,28 +59,28 @@
 invalid_returns/sync_invalid_return_04_test/none: CompileTimeError # issue #34319
 invalid_returns/sync_invalid_return_05_test/none: CompileTimeError # issue #34319
 issue13673_test: StaticWarning # Issue 31925
-issue31596_implement_covariant_test: CompileTimeError
-issue31596_override_test/01: CompileTimeError
-issue31596_override_test/02: CompileTimeError
-issue31596_override_test/03: CompileTimeError
-issue31596_override_test/04: CompileTimeError
-issue31596_override_test/none: CompileTimeError
-issue31596_super_test/01: CompileTimeError
-issue31596_super_test/03: CompileTimeError
-issue31596_super_test/05: CompileTimeError
-issue31596_super_test/none: CompileTimeError
-issue31596_tearoff_test: CompileTimeError
-issue31596_test: CompileTimeError
-malformed2_test: Pass, MissingCompileTimeError # Issue 31056.
-method_override7_test/03: Fail # Issue 11497
-mixin_forwarding_constructor4_test/01: CompileTimeError # See issue 15101
-mixin_forwarding_constructor4_test/02: CompileTimeError # See issue 15101
-mixin_forwarding_constructor4_test/03: CompileTimeError # See issue 15101
+issue31596_implement_covariant_test: CompileTimeError # Issue #31596
+issue31596_override_test/01: CompileTimeError # Issue #31596
+issue31596_override_test/02: CompileTimeError # Issue #31596
+issue31596_override_test/03: CompileTimeError # Issue #31596
+issue31596_override_test/04: CompileTimeError # Issue #31596
+issue31596_override_test/none: CompileTimeError # Issue #31596
+issue31596_super_test/01: CompileTimeError # Issue #31596
+issue31596_super_test/03: CompileTimeError # Issue #31596
+issue31596_super_test/05: CompileTimeError # Issue #31596
+issue31596_super_test/none: CompileTimeError # Issue #31596
+issue31596_tearoff_test: CompileTimeError # Issue #31596
+issue31596_test: CompileTimeError # Issue #31596
+malformed2_test: Pass, MissingCompileTimeError # Flaky: issue 31056.
+mixin_declaration/mixin_declaration_invalid_superinvocation_test/10: CompileTimeError # Issue 30552
+mixin_forwarding_constructor4_test/01: CompileTimeError # See issue #34375
+mixin_forwarding_constructor4_test/02: CompileTimeError # See issue #34375
+mixin_forwarding_constructor4_test/03: CompileTimeError # See issue #34375
 mixin_method_override_test/01: MissingCompileTimeError
 mixin_super_2_test/01: MissingCompileTimeError
 mixin_super_2_test/03: MissingCompileTimeError
-mixin_super_constructor_named_test/01: CompileTimeError # See issue 15101
-mixin_super_constructor_positionals_test/01: CompileTimeError # See issue 15101
+mixin_super_constructor_named_test/01: CompileTimeError # See issue #34375
+mixin_super_constructor_positionals_test/01: CompileTimeError # See issue #34375
 mixin_supertype_subclass2_test/02: MissingStaticWarning # Issue 25614
 mixin_supertype_subclass2_test/05: MissingStaticWarning # Issue 25614
 mixin_supertype_subclass3_test/02: MissingStaticWarning # Issue 25614
@@ -92,15 +90,12 @@
 mixin_supertype_subclass4_test/03: MissingStaticWarning # Issue 25614
 mixin_supertype_subclass4_test/04: MissingStaticWarning # Issue 25614
 mixin_supertype_subclass4_test/05: MissingStaticWarning # Issue 25614
-mixin_supertype_subclass_test/02: MissingCompileTimeError
-mixin_supertype_subclass_test/02: MissingStaticWarning # Issue 25614
-mixin_supertype_subclass_test/05: MissingCompileTimeError
-mixin_supertype_subclass_test/05: MissingStaticWarning # Issue 25614
-mock_writable_final_private_field_test: CompileTimeError # Issue 30848
+mixin_supertype_subclass_test/02: MissingCompileTimeError, MissingStaticWarning # failing-by-design, see Issue #34376
+mixin_supertype_subclass_test/05: MissingCompileTimeError, MissingStaticWarning # failing-by-design, see Issue #34376
+mock_writable_final_private_field_test: CompileTimeError # failing-by-design, see Issue #34377
 multiple_interface_inheritance_test: CompileTimeError # Issue 30552
-nested_generic_closure_test: CompileTimeError
-no_main_test/01: Fail # Issue 20030
-no_main_test/01: MissingStaticWarning # Issue 28823
+nested_generic_closure_test: CompileTimeError # Issue #28515
+no_main_test/01: Fail # failing-by-design, the analyzer has no restriction that a library include a main function.
 no_such_constructor2_test: StaticWarning
 override_inheritance_field_test/42: CompileTimeError
 parser_quirks_test: CompileTimeError
@@ -119,24 +114,9 @@
 regress_30339_test: CompileTimeError
 regress_32660_test/01: MissingCompileTimeError # Issue #32660.
 regress_32660_test/04: CompileTimeError
-regress_33235_03_test/01: MissingCompileTimeError
-regress_33235_07_test/03: MissingCompileTimeError
-regress_33235_10_test/01: MissingCompileTimeError
-regress_33235_10_test/02: MissingCompileTimeError
-regress_33235_10_test/03: MissingCompileTimeError
-regress_33235_11_test/01: MissingCompileTimeError
-regress_33235_12_test/03: MissingCompileTimeError
-regress_33235_13_test/03: MissingCompileTimeError
-regress_33235_16_test/02: MissingCompileTimeError
-regress_33235_16_test/03: MissingCompileTimeError
-regress_33235_19_test: CompileTimeError
-regress_33235_20_test: CompileTimeError
+regress_33479_test/01: Crash # Issue #33479
 setter3_test/01: CompileTimeError # Invalid test, see https://github.com/dart-lang/sdk/issues/33837
 setter3_test/02: CompileTimeError # Invalid test, see https://github.com/dart-lang/sdk/issues/33837
-setter_override2_test/02: MissingCompileTimeError # Issue 14736
-static_setter_conflicts_test/02: MissingCompileTimeError
-static_setter_conflicts_test/11: MissingCompileTimeError
-static_setter_conflicts_test/12: MissingCompileTimeError
 string_split_test: CompileTimeError
 string_supertype_checked_test: CompileTimeError
 super_bound_closure_test/none: CompileTimeError
diff --git a/tests/language_2/language_2_dart2js.status b/tests/language_2/language_2_dart2js.status
index 25b6963..241f8f57 100644
--- a/tests/language_2/language_2_dart2js.status
+++ b/tests/language_2/language_2_dart2js.status
@@ -463,8 +463,6 @@
 redirecting_factory_malbounded_test/01: MissingCompileTimeError
 regress_13462_1_test: RuntimeError
 regress_18535_test: RuntimeError
-sync_generator2_test/41: Crash # 'file:*/pkg/compiler/lib/src/kernel/element_map_impl.dart': Failed assertion: line 939 pos 18: 'asyncMarker == AsyncMarker.SYNC': is not true.
-sync_generator2_test/52: Crash # 'file:*/pkg/compiler/lib/src/kernel/element_map_impl.dart': Failed assertion: line 939 pos 18: 'asyncMarker == AsyncMarker.SYNC': is not true.
 type_literal_prefix_call_test/00: MissingCompileTimeError
 type_promotion_logical_and_test/01: MissingCompileTimeError
 type_variable_bounds_test/02: Crash # NoSuchMethodError: The method 'accept' was called on null.
diff --git a/tests/language_2/language_2_dartdevc.status b/tests/language_2/language_2_dartdevc.status
index d31e225..29b9a9c 100644
--- a/tests/language_2/language_2_dartdevc.status
+++ b/tests/language_2/language_2_dartdevc.status
@@ -6,7 +6,6 @@
 [ $compiler == dartdevc ]
 abstract_override_adds_optional_args_concrete_subclass_test: MissingCompileTimeError # Issue #30568
 abstract_override_adds_optional_args_concrete_test: MissingCompileTimeError # Issue #30568
-abstract_override_adds_optional_args_supercall_test: MissingCompileTimeError # Issue #30568
 accessor_conflict_export2_test: CompileTimeError # Issue 25626
 accessor_conflict_export_test: CompileTimeError # Issue 25626
 accessor_conflict_import2_test: CompileTimeError # Issue 25626
@@ -33,11 +32,13 @@
 conflicting_generic_interfaces_simple_test: MissingCompileTimeError
 const_cast2_test/01: CompileTimeError
 const_cast2_test/none: CompileTimeError
+const_constructor3_test/04: MissingCompileTimeError # Side-effect of working around issue 33441 for int-to-double
 const_constructor_mixin3_test/01: MissingCompileTimeError # Issue 33644
 const_constructor_mixin_test/01: MissingCompileTimeError # Issue 33644
-constructor_reference_test/27: MissingCompileTimeError
+constructor_reference_test/27: MissingCompileTimeError # Issue https://github.com/dart-lang/sdk/issues/34403
 covariance_field_test/03: RuntimeError
 covariant_override/tear_off_type_test: RuntimeError # Issue 28395
+covariant_subtyping_with_mixin_test: CompileTimeError # Issue 34329
 default_implementation2_test: CompileTimeError # Issue 30855
 deferred_load_library_wrong_args_test/01: MissingRuntimeError, RuntimeError # Issue 29920
 double_identical_test: RuntimeError # Negative and positive zero are distinct, but not in ddc
@@ -103,7 +104,16 @@
 issue32353_test: RuntimeError
 label_test: RuntimeError
 left_shift_test: RuntimeError # Ints and doubles are unified.
-method_override7_test/03: MissingCompileTimeError
+mixin_declaration/mixin_declaration_inference_invalid_03_test: MissingCompileTimeError   # https://github.com/dart-lang/sdk/issues/34167
+mixin_declaration/mixin_declaration_inference_invalid_04_test: MissingCompileTimeError   # https://github.com/dart-lang/sdk/issues/34167
+mixin_declaration/mixin_declaration_inference_invalid_05_test: MissingCompileTimeError   # https://github.com/dart-lang/sdk/issues/34167
+mixin_declaration/mixin_declaration_inference_invalid_06_test: MissingCompileTimeError   # https://github.com/dart-lang/sdk/issues/34167
+mixin_declaration/mixin_declaration_inference_invalid_07_test: MissingCompileTimeError   # https://github.com/dart-lang/sdk/issues/34167
+mixin_declaration/mixin_declaration_inference_invalid_08_test: MissingCompileTimeError   # https://github.com/dart-lang/sdk/issues/34167
+mixin_declaration/mixin_declaration_inference_invalid_09_test: MissingCompileTimeError   # https://github.com/dart-lang/sdk/issues/34167
+mixin_declaration/mixin_declaration_inference_invalid_10_test: MissingCompileTimeError   # https://github.com/dart-lang/sdk/issues/34167
+mixin_declaration/mixin_declaration_inference_valid_classes_test: CompileTimeError   # https://github.com/dart-lang/sdk/issues/34164
+mixin_declaration/mixin_declaration_invalid_superinvocation_test/10: CompileTimeError    # Analyzer chooses wrong(?) super method.
 mixin_forwarding_constructor4_test/01: CompileTimeError # See issue 15101
 mixin_forwarding_constructor4_test/02: CompileTimeError # See issue 15101
 mixin_forwarding_constructor4_test/03: CompileTimeError # See issue 15101
@@ -146,25 +156,10 @@
 regress_30339_test: CompileTimeError # As expected. Should we make this a multi test?
 regress_32660_test/01: MissingCompileTimeError # Issue #32660.
 regress_32660_test/04: CompileTimeError
-regress_33235_03_test/01: MissingCompileTimeError
-regress_33235_07_test/03: MissingCompileTimeError
-regress_33235_10_test/01: MissingCompileTimeError
-regress_33235_10_test/02: MissingCompileTimeError
-regress_33235_10_test/03: MissingCompileTimeError
-regress_33235_11_test/01: MissingCompileTimeError
-regress_33235_12_test/03: MissingCompileTimeError
-regress_33235_13_test/03: MissingCompileTimeError
-regress_33235_16_test/02: MissingCompileTimeError
-regress_33235_16_test/03: MissingCompileTimeError
-regress_33235_19_test: CompileTimeError
-regress_33235_20_test: CompileTimeError
+regress_33479_test/01: Crash # Issue #33479
 setter3_test/01: CompileTimeError # Invalid test, see https://github.com/dart-lang/sdk/issues/33837
 setter3_test/02: CompileTimeError # Invalid test, see https://github.com/dart-lang/sdk/issues/33837
-setter_override2_test/02: MissingCompileTimeError # Issue 14736
 stacktrace_test: RuntimeError # Issue 29920
-static_setter_conflicts_test/02: MissingCompileTimeError
-static_setter_conflicts_test/11: MissingCompileTimeError
-static_setter_conflicts_test/12: MissingCompileTimeError
 string_split_test: CompileTimeError
 string_supertype_checked_test: CompileTimeError
 super_bound_closure_test/none: CompileTimeError
@@ -305,6 +300,7 @@
 map_literal3_test/01: MissingCompileTimeError
 map_literal3_test/02: MissingCompileTimeError
 map_literal3_test/03: MissingCompileTimeError
+mixin_declaration/*: Skip # need flag on Kernel Class nodes.
 mixin_illegal_super_use_test/01: MissingCompileTimeError
 mixin_illegal_super_use_test/04: MissingCompileTimeError
 mixin_illegal_super_use_test/07: MissingCompileTimeError
@@ -458,8 +454,8 @@
 generic_is_check_test: RuntimeError # Issue 29920; Expect.isTrue(false) fails.
 generic_tearoff_test: CompileTimeError
 guess_cid_test: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
-identical_closure2_test: RuntimeError # Issue 29920; Expect.isFalse(true) fails.
 identical_closure2_test: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
+identical_closure2_test: RuntimeError # Issue 29920; Expect.isFalse(true) fails.
 infinite_switch_label_test: RuntimeError # Issue 29920; NoSuchMethodError: method not found: '<Unexpected Null Value>'
 infinity_test: RuntimeError # Issue 29920; Expect.isFalse(true) fails.
 instance_creation_in_function_annotation_test: RuntimeError # Issue 29920; UnimplementedError: JsClosureMirror.function unimplemented
@@ -493,7 +489,6 @@
 number_identity_test: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
 numbers_test: RuntimeError # Issue 29920; Expect.equals(expected: <false>, actual: <true>) fails.
 parser_quirks_test: CompileTimeError
-partial_instantiation_eager_bounds_check_test: RuntimeError # Issue 34296
 regress_16640_test: RuntimeError # Issue 29920; Uncaught Error: type arguments should not be null: E => {
 regress_22443_test: RuntimeError # Uncaught Expect.isTrue(false) fails.
 stack_overflow_stacktrace_test: RuntimeError # Issue 29920; RangeError: Maximum call stack size exceeded
diff --git a/tests/language_2/language_2_kernel.status b/tests/language_2/language_2_kernel.status
index 818a556..41bd846 100644
--- a/tests/language_2/language_2_kernel.status
+++ b/tests/language_2/language_2_kernel.status
@@ -85,6 +85,17 @@
 local_function3_test/none: RuntimeError
 local_function_test/none: RuntimeError
 main_test/03: RuntimeError
+mixin_declaration/mixin_declaration_invalid_application_supertype_test/03: MissingCompileTimeError
+mixin_declaration/mixin_declaration_invalid_application_supertype_test/04: MissingCompileTimeError
+mixin_declaration/mixin_declaration_invalid_application_supertype_test/05: MissingCompileTimeError
+mixin_declaration/mixin_declaration_invalid_override_test/none: CompileTimeError
+mixin_declaration/mixin_declaration_invalid_superinvocation_test/10: CompileTimeError
+mixin_declaration/mixin_declaration_invalid_superinvocation_test/none: CompileTimeError
+mixin_declaration/mixin_declaration_invalid_syntax_test/none: CompileTimeError
+mixin_declaration/mixin_declaration_invalid_usage_test/03: MissingCompileTimeError
+mixin_declaration/mixin_declaration_superinvocation_application_test/none: CompileTimeError
+mixin_declaration/mixin_declaration_supertype_compatible_test/none: CompileTimeError
+mixin_declaration/mixin_declaration_syntax_test: CompileTimeError
 mixin_illegal_super_use_test/01: MissingCompileTimeError
 mixin_illegal_super_use_test/04: MissingCompileTimeError
 mixin_illegal_super_use_test/07: MissingCompileTimeError
@@ -136,9 +147,9 @@
 string_supertype_checked_test: CompileTimeError
 super_bound_closure_test/none: CompileTimeError
 super_test: RuntimeError
-type_alias_equality_test/02: RuntimeError
-type_alias_equality_test/03: RuntimeError
-type_alias_equality_test/04: RuntimeError
+type_alias_equality_test/02: RuntimeError # Issue 32783
+type_alias_equality_test/03: RuntimeError # Issue 32783
+type_alias_equality_test/04: RuntimeError # Issue 32783
 type_error_test: RuntimeError
 type_literal_test: RuntimeError
 type_promotion_functions_test/02: CompileTimeError
@@ -198,6 +209,17 @@
 implicit_creation/implicit_const_not_default_values_test/e5: MissingCompileTimeError
 implicit_creation/implicit_const_not_default_values_test/e7: MissingCompileTimeError
 implicit_creation/implicit_const_not_default_values_test/e8: MissingCompileTimeError
+mixin_declaration/mixin_declaration_invalid_application_supertype_test/03: MissingCompileTimeError
+mixin_declaration/mixin_declaration_invalid_application_supertype_test/04: MissingCompileTimeError
+mixin_declaration/mixin_declaration_invalid_application_supertype_test/05: MissingCompileTimeError
+mixin_declaration/mixin_declaration_invalid_override_test/none: CompileTimeError
+mixin_declaration/mixin_declaration_invalid_superinvocation_test/10: CompileTimeError
+mixin_declaration/mixin_declaration_invalid_superinvocation_test/none: CompileTimeError
+mixin_declaration/mixin_declaration_invalid_syntax_test/none: CompileTimeError
+mixin_declaration/mixin_declaration_invalid_usage_test/03: MissingCompileTimeError
+mixin_declaration/mixin_declaration_superinvocation_application_test/none: CompileTimeError
+mixin_declaration/mixin_declaration_supertype_compatible_test/none: CompileTimeError
+mixin_declaration/mixin_declaration_syntax_test: CompileTimeError
 vm/regress_33469_test/01: MissingCompileTimeError
 vm/regress_33469_test/02: MissingCompileTimeError
 vm/regress_33469_test/03: MissingCompileTimeError
@@ -212,7 +234,7 @@
 const_constructor_mixin_test: CompileTimeError # Issue 33644.
 const_types_test/34: MissingCompileTimeError # Issue 31590
 const_types_test/39: MissingCompileTimeError # Issue 31590
-constructor_reference_test/27: MissingCompileTimeError # Issue 32972 (parsed as method call)
+constructor_reference_test/27: MissingCompileTimeError # Issue 34403
 default_factory2_test/01: MissingCompileTimeError # Issue 31590
 default_factory_test/01: MissingCompileTimeError # Issue 31590
 deferred_inheritance_constraints_test/extends: MissingCompileTimeError # Fasta/KernelVM bug: Deferred loading kernel issue 30273.
@@ -227,6 +249,12 @@
 generic_methods_recursive_bound_test/02: MissingCompileTimeError # Issue 33308
 issue31596_super_test/02: MissingCompileTimeError # Issue 31596
 issue31596_super_test/04: MissingCompileTimeError # Issue 31596
+issue34488_test/01: MissingCompileTimeError # Issue 34488
+issue34488_test/02: MissingCompileTimeError # Issue 34488
+issue34488_test/03: MissingCompileTimeError # Issue 34488
+issue34488_test/04: MissingCompileTimeError # Issue 34488
+issue34488_test/05: MissingCompileTimeError # Issue 34488
+issue34488_test/06: MissingCompileTimeError # Issue 34488
 malbounded_instantiation_test/01: MissingCompileTimeError # Issue 33308
 malbounded_instantiation_test/02: MissingCompileTimeError # Issue 33308
 malbounded_instantiation_test/03: MissingCompileTimeError # Issue 33308
@@ -243,6 +271,7 @@
 malbounded_type_test_test/00: MissingCompileTimeError # Issue 33308
 malbounded_type_test_test/01: MissingCompileTimeError # Issue 33308
 malbounded_type_test_test/02: MissingCompileTimeError # Issue 33308
+mixin_declaration/mixin_declaration_inference_valid_classes_test: CompileTimeError, DartkCrash, Crash # https://github.com/dart-lang/sdk/issues/34165
 mixin_invalid_bound2_test/02: MissingCompileTimeError # Issue 33308
 mixin_invalid_bound2_test/03: MissingCompileTimeError # Issue 33308
 mixin_invalid_bound2_test/04: MissingCompileTimeError # Issue 33308
@@ -402,7 +431,7 @@
 const_dynamic_type_literal_test/02: Pass
 map_literal3_test/01: Pass
 map_literal3_test/02: Pass
-type_alias_equality_test/02: RuntimeError # Issue 31359
+type_alias_equality_test/02: RuntimeError # Issue 32783
 vm/bool_check_stack_traces_test/01: RuntimeError # No support for line numbers in stacktraces
 vm/bool_check_stack_traces_test/none: RuntimeError # No support for line numbers in stacktraces
 vm/causal_async_exception_stack2_test: RuntimeError # No support for line numbers in stacktraces
@@ -430,9 +459,9 @@
 vm/type_vm_test/36: MissingRuntimeError
 
 [ $compiler == dartkp && $runtime == dart_precompiled ]
-type_alias_equality_test/02: RuntimeError # Issue 31359
-type_alias_equality_test/03: RuntimeError # Issue 31359
-type_alias_equality_test/04: RuntimeError # Issue 31359
+type_alias_equality_test/02: RuntimeError # Issue 32783
+type_alias_equality_test/03: RuntimeError # Issue 32783
+type_alias_equality_test/04: RuntimeError # Issue 32783
 vm/bool_check_stack_traces_test/01: RuntimeError # Issue 33584
 vm/bool_check_stack_traces_test/02: RuntimeError # Issue 33584
 
@@ -2089,9 +2118,10 @@
 *: SkipByDesign # language_2 is only supported in strong mode.
 
 [ ($compiler == app_jitk || $compiler == dartk || $compiler == dartkp) && ($runtime == dart_precompiled || $runtime == vm) ]
-type_alias_equality_test/02: RuntimeError # Issue 31359
-type_alias_equality_test/03: RuntimeError # Issue 31359
-type_alias_equality_test/04: RuntimeError # Issue 31359
+covariant_subtyping_with_mixin_test: RuntimeError # Issue 34321
+type_alias_equality_test/02: RuntimeError # Issue 32783
+type_alias_equality_test/03: RuntimeError # Issue 32783
+type_alias_equality_test/04: RuntimeError # Issue 32783
 
 [ ($compiler == dartk || $compiler == dartkb) && ($hot_reload || $hot_reload_rollback) ]
 async_star_test/01: Skip # Timeout
@@ -2104,3 +2134,14 @@
 [ $compiler == dartk || $compiler == dartkb || $compiler == dartkp ]
 generic_function_bounds_test: RuntimeError # Issue 32076
 generic_test/01: MissingCompileTimeError
+mixin_declaration/mixin_declaration_invalid_application_supertype_test/03: MissingCompileTimeError
+mixin_declaration/mixin_declaration_invalid_application_supertype_test/04: MissingCompileTimeError
+mixin_declaration/mixin_declaration_invalid_application_supertype_test/05: MissingCompileTimeError
+mixin_declaration/mixin_declaration_invalid_override_test/none: CompileTimeError
+mixin_declaration/mixin_declaration_invalid_superinvocation_test/10: CompileTimeError
+mixin_declaration/mixin_declaration_invalid_superinvocation_test/none: CompileTimeError
+mixin_declaration/mixin_declaration_invalid_syntax_test/none: CompileTimeError
+mixin_declaration/mixin_declaration_invalid_usage_test/03: MissingCompileTimeError
+mixin_declaration/mixin_declaration_superinvocation_application_test/none: CompileTimeError
+mixin_declaration/mixin_declaration_supertype_compatible_test/none: CompileTimeError
+mixin_declaration/mixin_declaration_syntax_test: CompileTimeError
diff --git a/tests/language_2/language_2_precompiled.status b/tests/language_2/language_2_precompiled.status
index cf38485..c813c7b 100644
--- a/tests/language_2/language_2_precompiled.status
+++ b/tests/language_2/language_2_precompiled.status
@@ -10,6 +10,9 @@
 [ $arch == ia32 && $runtime == dart_precompiled ]
 vm/regress_24517_test: Pass, Fail # Issue 24517.
 
+[ $compiler != dart2analyzer && $runtime == dart_precompiled ]
+mixin_mixin2_test: Skip
+
 [ $runtime == dart_precompiled && $minified ]
 cyclic_type_test/*: Skip
 enum_duplicate_test/*: Skip # Uses Enum.toString()
@@ -21,7 +24,6 @@
 full_stacktrace2_test: Skip
 full_stacktrace3_test: Skip
 mixin_generic_test: Skip
-mixin_mixin2_test: Skip
 mixin_mixin3_test: Skip
 mixin_mixin5_test: Skip
 mixin_mixin6_test: Skip
diff --git a/tests/language_2/mixin_declaration/mixin_declaration_inference_invalid_00_test.dart b/tests/language_2/mixin_declaration/mixin_declaration_inference_invalid_00_test.dart
new file mode 100644
index 0000000..5d99d2f
--- /dev/null
+++ b/tests/language_2/mixin_declaration/mixin_declaration_inference_invalid_00_test.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for 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 I<X> {}
+
+mixin M0<T> on I<T> {}
+
+///////////////////////////////////////////////////////
+// Inference happens from superclasses to subclasses
+///////////////////////////////////////////////////////
+
+// Error since class hierarchy is inconsistent
+class A00 extends I with M0<int> {} /*@compile-error=unspecified*/
+
+void main() {}
\ No newline at end of file
diff --git a/tests/language_2/mixin_declaration/mixin_declaration_inference_invalid_01_test.dart b/tests/language_2/mixin_declaration/mixin_declaration_inference_invalid_01_test.dart
new file mode 100644
index 0000000..749d813
--- /dev/null
+++ b/tests/language_2/mixin_declaration/mixin_declaration_inference_invalid_01_test.dart
@@ -0,0 +1,18 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for 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 I<X> {}
+
+mixin M0<T> on I<T> {}
+
+mixin M1<T> on I<T> {}
+
+///////////////////////////////////////////////////////
+// Inference happens from superclasses to subclasses
+///////////////////////////////////////////////////////
+
+// Error since class hierarchy is inconsistent
+class A00 extends I with M0, M1<int> {} /*@compile-error=unspecified*/
+
+void main() {}
\ No newline at end of file
diff --git a/tests/language_2/mixin_declaration/mixin_declaration_inference_invalid_02_test.dart b/tests/language_2/mixin_declaration/mixin_declaration_inference_invalid_02_test.dart
new file mode 100644
index 0000000..01ae1ae
--- /dev/null
+++ b/tests/language_2/mixin_declaration/mixin_declaration_inference_invalid_02_test.dart
@@ -0,0 +1,18 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for 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 I<X> {}
+
+mixin M0<T> implements I<T> {}
+
+mixin M1<T> on I<T> {}
+
+///////////////////////////////////////////////////////
+// Inference happens from superclasses to subclasses
+///////////////////////////////////////////////////////
+
+// Error since class hierarchy is inconsistent
+class A00 with M0, M1<int> {} /*@compile-error=unspecified*/
+
+void main() {}
\ No newline at end of file
diff --git a/tests/language_2/mixin_declaration/mixin_declaration_inference_invalid_03_test.dart b/tests/language_2/mixin_declaration/mixin_declaration_inference_invalid_03_test.dart
new file mode 100644
index 0000000..5741700
--- /dev/null
+++ b/tests/language_2/mixin_declaration/mixin_declaration_inference_invalid_03_test.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for 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 I<X> {}
+
+mixin M0<T> implements I<T> {}
+
+//////////////////////////////////////////////////////
+// Inference happens from superclasses to subclasses
+///////////////////////////////////////////////////////
+
+// Error since class hierarchy is inconsistent
+class A00 extends Object with M0 implements I<int> {} /*@compile-error=unspecified*/
+
+void main() {}
\ No newline at end of file
diff --git a/tests/language_2/mixin_declaration/mixin_declaration_inference_invalid_04_test.dart b/tests/language_2/mixin_declaration/mixin_declaration_inference_invalid_04_test.dart
new file mode 100644
index 0000000..50d017b
--- /dev/null
+++ b/tests/language_2/mixin_declaration/mixin_declaration_inference_invalid_04_test.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for 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 I<X> {}
+
+mixin M0<T> implements I<T> {}
+
+//////////////////////////////////////////////////////
+// Inference does not use implements constraints on mixin
+///////////////////////////////////////////////////////
+
+// Error since class hierarchy is inconsistent
+class A00 with M0 implements I<int> {} /*@compile-error=unspecified*/
+
+void main() {}
\ No newline at end of file
diff --git a/tests/language_2/mixin_declaration/mixin_declaration_inference_invalid_05_test.dart b/tests/language_2/mixin_declaration/mixin_declaration_inference_invalid_05_test.dart
new file mode 100644
index 0000000..38e681e
--- /dev/null
+++ b/tests/language_2/mixin_declaration/mixin_declaration_inference_invalid_05_test.dart
@@ -0,0 +1,18 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for 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 I<X> {}
+
+mixin M0<T> implements I<T> {}
+
+mixin M1<T> implements I<T> {}
+
+//////////////////////////////////////////////////////
+// Inference does not use implements constraints on mixin
+///////////////////////////////////////////////////////
+
+// Error since class hierarchy is inconsistent
+class A00 extends I<int> with M0<int>, M1 {} /*@compile-error=unspecified*/
+
+void main() {}
\ No newline at end of file
diff --git a/tests/language_2/mixin_declaration/mixin_declaration_inference_invalid_06_test.dart b/tests/language_2/mixin_declaration/mixin_declaration_inference_invalid_06_test.dart
new file mode 100644
index 0000000..14c2416
--- /dev/null
+++ b/tests/language_2/mixin_declaration/mixin_declaration_inference_invalid_06_test.dart
@@ -0,0 +1,23 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for 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 I<X> {}
+class J<X> {}
+
+mixin M0<S, T> implements I<S>, J<T> {}
+
+mixin M1<S, T> implements I<S>, J<T> {}
+
+//////////////////////////////////////////////////////
+// Inference does not use implements constraints on mixin
+///////////////////////////////////////////////////////
+
+class A00 extends I<int> with M0 {}
+
+class A01 extends J<int> with M1 {}
+
+// Error since class hierarchy is inconsistent
+class A02 extends A00 implements A01 {} /*@compile-error=unspecified*/
+
+void main() {}
\ No newline at end of file
diff --git a/tests/language_2/mixin_declaration/mixin_declaration_inference_invalid_07_test.dart b/tests/language_2/mixin_declaration/mixin_declaration_inference_invalid_07_test.dart
new file mode 100644
index 0000000..9b16c66
--- /dev/null
+++ b/tests/language_2/mixin_declaration/mixin_declaration_inference_invalid_07_test.dart
@@ -0,0 +1,19 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for 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 I<X> {}
+
+mixin M0<X, Y extends Comparable<Y>> on I<X> {}
+
+class M1 implements I<int> {}
+
+//////////////////////////////////////////////////////
+// Inference does not produce super-bounded types
+///////////////////////////////////////////////////////
+
+// M0 is inferred as M0<int, Comparable<dynamic>>
+// Error since super-bounded type not allowed
+class A extends M1 with M0 {} /*@compile-error=unspecified*/
+
+void main() {}
\ No newline at end of file
diff --git a/tests/language_2/mixin_declaration/mixin_declaration_inference_invalid_08_test.dart b/tests/language_2/mixin_declaration/mixin_declaration_inference_invalid_08_test.dart
new file mode 100644
index 0000000..23da50d3
--- /dev/null
+++ b/tests/language_2/mixin_declaration/mixin_declaration_inference_invalid_08_test.dart
@@ -0,0 +1,21 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for 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 I<X, Y> {}
+
+mixin M0<T> implements I<T, int> {}
+
+mixin M1<T> implements I<String, T> {}
+
+//////////////////////////////////////////////////////
+// Inference is not bi-directional
+///////////////////////////////////////////////////////
+
+
+// M0<String>, M1<int> is a solution, but we shouldn't find it
+// M0 inferred as M0<dynamic>
+// M1 inferred as M1<dynamic>
+class A with M0, M1 {} /*@compile-error=unspecified*/
+
+void main() {}
\ No newline at end of file
diff --git a/tests/language_2/mixin_declaration/mixin_declaration_inference_invalid_09_test.dart b/tests/language_2/mixin_declaration/mixin_declaration_inference_invalid_09_test.dart
new file mode 100644
index 0000000..0ebdf97
--- /dev/null
+++ b/tests/language_2/mixin_declaration/mixin_declaration_inference_invalid_09_test.dart
@@ -0,0 +1,23 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for 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 I<X, Y> {}
+
+mixin M0<T> implements I<T, List<T>> {}
+
+mixin M1<T> implements I<List<T>, T> {}
+
+//////////////////////////////////////////////////////
+// Inference does not produce infinite types
+///////////////////////////////////////////////////////
+
+// No solution, even with unification, since solution
+// requires that I<List<U0>, U0> == I<U1, List<U1>>
+// for some U0, U1, and hence that:
+// U0 = List<U1>
+// U1 = List<U0>
+// which has no finite solution
+class A with M0, M1 {} /*@compile-error=unspecified*/
+
+void main() {}
\ No newline at end of file
diff --git a/tests/language_2/mixin_declaration/mixin_declaration_inference_invalid_10_test.dart b/tests/language_2/mixin_declaration/mixin_declaration_inference_invalid_10_test.dart
new file mode 100644
index 0000000..00563ef
--- /dev/null
+++ b/tests/language_2/mixin_declaration/mixin_declaration_inference_invalid_10_test.dart
@@ -0,0 +1,15 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for 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 I<T> {}
+class J<T> {}
+mixin M0<T> implements I<T>, J<T> {}
+
+//////////////////////////////////////////////////////
+// Over-constrained results are caught
+///////////////////////////////////////////////////////
+
+class A with I<int>, J<double>, M0 {} /*@compile-error=unspecified*/
+
+void main() {}
\ No newline at end of file
diff --git a/tests/language_2/mixin_declaration/mixin_declaration_inference_valid_classes_test.dart b/tests/language_2/mixin_declaration/mixin_declaration_inference_valid_classes_test.dart
new file mode 100644
index 0000000..e7eeb50
--- /dev/null
+++ b/tests/language_2/mixin_declaration/mixin_declaration_inference_valid_classes_test.dart
@@ -0,0 +1,396 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+class I<X> {}
+
+class C0<T> extends I<T> {}
+class C1<T> implements I<T> {}
+
+mixin M0<T> on I<T> {
+}
+
+mixin M1<T> on I<T> {
+  T Function(T) get value => null;
+}
+
+mixin M2<T> implements I<T> {}
+
+mixin M3<T> on I<T> {}
+
+class J<X> {}
+class C2 extends C1<int> implements J<double> {}
+class C3 extends J<double> {}
+
+mixin M4<S, T> on I<S>, J<T> {
+  S Function(S) get value0 => null;
+  T Function(T) get value1 => null;
+}
+
+///////////////////////////////////////////////////////
+// Inference of a single mixin from a super class works
+///////////////////////////////////////////////////////
+
+// M1 is inferred as M1<int>
+class A00 extends I<int> with M1 {
+  void check() {
+    // Verify that M1.T is exactly int
+    int Function(int) f = this.value;
+  }
+}
+
+// M1 is inferred as M1<int>
+class A01 extends C0<int> with M1 {
+  void check() {
+    // Verify that M1.T is exactly int
+    int Function(int) f = this.value;
+  }
+}
+
+// M1 is inferred as M1<int>
+class A02 extends C1<int> with M1 {
+  void check() {
+    // Verify that M1.T is exactly int
+    int Function(int) f = this.value;
+  }
+}
+
+///////////////////////////////////////////////////////
+// Inference of a single mixin from another mixin works
+///////////////////////////////////////////////////////
+
+// M1 is inferred as M1<int>
+class B00 extends Object with I<int>, M1 {
+  void check() {
+    // Verify that M1.T is exactly int
+    int Function(int) f = this.value;
+  }
+}
+
+// M1 is inferred as M1<int>
+class B01 extends Object with C1<int>, M1 {
+  void check() {
+    // Verify that M1.T is exactly int
+    int Function(int) f = this.value;
+  }
+}
+
+// M1 is inferred as M1<int>
+class B02 extends I<int> with M0<int>, M1 {
+  void check() {
+    // Verify that M1.T is exactly int
+    int Function(int) f = this.value;
+  }
+}
+
+// M1 is inferred as M1<int>
+class B03 extends Object with M2<int>, M1 {
+  void check() {
+    // Verify that M1.T is exactly int
+    int Function(int) f = this.value;
+  }
+}
+
+///////////////////////////////////////////////////////
+// Inference of a single mixin from another mixin works
+// with the shorthand syntax
+///////////////////////////////////////////////////////
+
+// M1 is inferred as M1<int>
+class C00 with I<int>, M1 {
+  void check() {
+    // Verify that M1.T is exactly int
+    int Function(int) f = this.value;
+  }
+}
+
+// M1 is inferred as M1<int>
+class C01 with C1<int>, M1 {
+  void check() {
+    // Verify that M1.T is exactly int
+    int Function(int) f = this.value;
+  }
+}
+
+// M1 is inferred as M1<int>
+class C02 with I<int>, M0<int>, M1 {
+  void check() {
+    // Verify that M1.T is exactly int
+    int Function(int) f = this.value;
+  }
+}
+
+// M1 is inferred as M1<int>
+class C03 with M2<int>, M1 {
+  void check() {
+    // Verify that M1.T is exactly int
+    int Function(int) f = this.value;
+  }
+}
+
+///////////////////////////////////////////////////////
+// Inference of two mixins from a super class works
+///////////////////////////////////////////////////////
+
+// M1 is inferred as M1<int>
+class A10 extends I<int> with M3, M1 {
+  void check() {
+    // Verify that M1.T is exactly int
+    int Function(int) f = this.value;
+  }
+}
+
+// M1 is inferred as M1<int>
+class A11 extends C0<int> with M3, M1 {
+  void check() {
+    // Verify that M1.T is exactly int
+    int Function(int) f = this.value;
+  }
+}
+
+// M1 is inferred as M1<int>
+class A12 extends C1<int> with M3, M1 {
+  void check() {
+    // Verify that M1.T is exactly int
+    int Function(int) f = this.value;
+  }
+}
+
+///////////////////////////////////////////////////////
+// Inference of two mixins from another mixin works
+///////////////////////////////////////////////////////
+
+// M1 is inferred as M1<int>
+class B10 extends Object with I<int>, M3, M1 {
+  void check() {
+    // Verify that M1.T is exactly int
+    int Function(int) f = this.value;
+  }
+}
+
+// M1 is inferred as M1<int>
+class B11 extends Object with C1<int>, M3, M1 {
+  void check() {
+    // Verify that M1.T is exactly int
+    int Function(int) f = this.value;
+  }
+}
+
+// M1 is inferred as M1<int>
+class B12 extends I<int> with M0<int>, M3, M1 {
+  void check() {
+    // Verify that M1.T is exactly int
+    int Function(int) f = this.value;
+  }
+}
+
+// M1 is inferred as M1<int>
+class B13 extends Object with M2<int>, M3, M1 {
+  void check() {
+    // Verify that M1.T is exactly int
+    int Function(int) f = this.value;
+  }
+}
+
+///////////////////////////////////////////////////////
+// Inference of a single mixin from another mixin works
+// with the shorthand syntax
+///////////////////////////////////////////////////////
+
+// M1 is inferred as M1<int>
+class C10 with I<int>, M3, M1 {
+  void check() {
+    // Verify that M1.T is exactly int
+    int Function(int) f = this.value;
+  }
+}
+
+// M1 is inferred as M1<int>
+class C11 with C1<int>, M3, M1 {
+  void check() {
+    // Verify that M1.T is exactly int
+    int Function(int) f = this.value;
+  }
+}
+
+// M1 is inferred as M1<int>
+class C12 with I<int>, M0<int>, M3, M1 {
+  void check() {
+    // Verify that M1.T is exactly int
+    int Function(int) f = this.value;
+  }
+}
+
+// M1 is inferred as M1<int>
+class C13 with M2<int>, M3, M1 {
+  void check() {
+    // Verify that M1.T is exactly int
+    int Function(int) f = this.value;
+  }
+}
+
+
+///////////////////////////////////////////////////////
+// Inference from multiple constraints works
+///////////////////////////////////////////////////////
+
+
+// M4 is inferred as M4<int, double>
+class A20 extends C2 with M4 {
+  void check() {
+    // Verify that M4.S is exactly int
+    int Function(int) f0 = this.value0;
+    // Verify that M4.T is exactly double
+    double Function(double) f1 = this.value1;
+  }
+}
+
+// M4 is inferred as M4<int, double>
+class A21 extends C3 with M2<int>, M4 {
+  void check() {
+    // Verify that M4.S is exactly int
+    int Function(int) f0 = this.value0;
+    // Verify that M4.T is exactly double
+    double Function(double) f1 = this.value0;
+  }
+}
+
+// M4 is inferred as M4<int, double>
+class A22 extends C2 with M1, M4 {
+  void check() {
+    // Verify that M1.T is exactly int
+    int Function(int) f = this.value;
+    // Verify that M4.S is exactly int
+    int Function(int) f0 = this.value0;
+    // Verify that M4.T is exactly double
+    double Function(double) f1 = this.value1;
+  }
+}
+
+mixin _M5<T> on I<T> implements J<T> {}
+
+// Inference here puts J<int> in the superclass hierarchy
+class _A23 extends C0<int> with _M5 {}
+
+// Inference here should get J<int> for M4.T
+// if inference for _M5 is done first (correctly)
+// and otherwise J<dynamic>
+class A23 extends _A23 with M4 {
+  void check() {
+    // Verify that M4.S is exactly int
+    int Function(int) f0 = this.value0;
+    // Verify that M4.T is exactly int
+    int Function(int) f1 = this.value1;
+  }
+}
+
+///////////////////////////////////////////////////////
+// Unconstrained parameters go to bounds
+///////////////////////////////////////////////////////
+
+mixin M5<S, T extends String> on I<S> {
+  S Function(S) get value0 => null;
+  T Function(T) get value1 => null;
+}
+
+mixin M6<S, T extends S> on I<S> {
+  S Function(S) get value0 => null;
+  T Function(T) get value1 => null;
+}
+
+// M5 is inferred as M5<int, String>
+class A30 extends C0<int> with M5 {
+  void check() {
+    // Verify that M5.S is exactly int
+    int Function(int) f0 = this.value0;
+    // Verify that M5.T is exactly String
+    String Function(String) f1 = this.value1;
+  }
+}
+
+// M6 is inferred as M6<int, int>
+class A31 extends C0<int> with M6 {
+  void check() {
+    // Verify that M6.S is exactly int
+    int Function(int) f0 = this.value0;
+    // Verify that M6.T is exactly int
+    int Function(int) f1 = this.value1;
+  }
+}
+
+///////////////////////////////////////////////////////
+// Non-trivial constraints should work
+///////////////////////////////////////////////////////
+
+mixin M7<T> on I<List<T>> {
+  T Function(T) get value0 => null;
+}
+
+mixin M8<T> on I<Iterable<T>> {
+  T Function(T) get value0 => null;
+}
+
+class A40<T> extends I<List<T>> {}
+
+class A41<T> extends A40<Map<T, T>> {}
+
+// M7 is inferred as M7<Map<int, int>>
+class A42 extends A41<int> with M7 {
+  void check() {
+    // Verify that M7.T is exactly Map<int, int>
+    Map<int, int> Function(Map<int, int>) f1 = this.value0;
+  }
+}
+
+// M8 is inferred as M8<Map<int, int>>
+class A43 extends A41<int> with M8 {
+  void check() {
+    // Verify that M8.T is exactly Map<int, int>
+    Map<int, int> Function(Map<int, int>) f1 = this.value0;
+  }
+}
+
+
+void main() {
+  Expect.type<M1<int>>(new A00()..check());
+  Expect.type<M1<int>>(new A01()..check());
+  Expect.type<M1<int>>(new A02()..check());
+
+  Expect.type<M1<int>>(new B00()..check());
+  Expect.type<M1<int>>(new B01()..check());
+  Expect.type<M1<int>>(new B02()..check());
+  Expect.type<M1<int>>(new B03()..check());
+
+  Expect.type<M1<int>>(new C00()..check());
+  Expect.type<M1<int>>(new C01()..check());
+  Expect.type<M1<int>>(new C02()..check());
+  Expect.type<M1<int>>(new C03()..check());
+
+  Expect.type<M1<int>>(new A10()..check());
+  Expect.type<M1<int>>(new A11()..check());
+  Expect.type<M1<int>>(new A12()..check());
+
+  Expect.type<M1<int>>(new B10()..check());
+  Expect.type<M1<int>>(new B11()..check());
+  Expect.type<M1<int>>(new B12()..check());
+  Expect.type<M1<int>>(new B13()..check());
+
+  Expect.type<M1<int>>(new C10()..check());
+  Expect.type<M1<int>>(new C11()..check());
+  Expect.type<M1<int>>(new C12()..check());
+  Expect.type<M1<int>>(new C13()..check());
+
+  Expect.type<M4<int, double>>(new A20()..check());
+  Expect.type<M4<int, double>>(new A21()..check());
+  Expect.type<M4<int, double>>(new A22()..check());
+  Expect.type<M1<int>>(new A22()..check());
+  Expect.type<M4<int, int>>(new A23()..check());
+
+  Expect.type<M5<int, String>>(new A30()..check());
+  Expect.type<M6<int, int>>(new A31()..check());
+
+  Expect.type<M7<Map<int, int>>>(new A42()..check());
+  Expect.type<M8<Map<int, int>>>(new A43()..check());
+}
\ No newline at end of file
diff --git a/tests/language_2/mixin_declaration/mixin_declaration_invalid_application_supertype_test.dart b/tests/language_2/mixin_declaration/mixin_declaration_invalid_application_supertype_test.dart
new file mode 100644
index 0000000..584003c
--- /dev/null
+++ b/tests/language_2/mixin_declaration/mixin_declaration_invalid_application_supertype_test.dart
@@ -0,0 +1,33 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for 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";
+
+// Test various invalid mixin applications where the supertype doesn't
+// implement the super-interfaces.
+
+abstract class UnaryNum {
+  num foo(num x) => x;
+}
+
+abstract class UnaryInt {
+  num foo(int x) => x;
+}
+
+mixin M1 on UnaryNum {}
+
+class _ = Object with M1; //# 01: compile-time error
+class _ = Null with M1; //# 02: compile-time error
+class _ = UnaryInt with M1;  //# 03: compile-time error
+
+mixin M2 on UnaryNum, UnaryInt {}
+
+class _ = UnaryInt with M2;  //# 04: compile-time error
+class _ = UnaryNum with M2;  //# 05: compile-time error
+
+main() {
+  // M1 and M2 are valid types.
+  Expect.notType<M1>(null);
+  Expect.notType<M2>(null);
+}
diff --git a/tests/language_2/mixin_declaration/mixin_declaration_invalid_override_test.dart b/tests/language_2/mixin_declaration/mixin_declaration_invalid_override_test.dart
new file mode 100644
index 0000000..be0ace3
--- /dev/null
+++ b/tests/language_2/mixin_declaration/mixin_declaration_invalid_override_test.dart
@@ -0,0 +1,66 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for 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";
+
+// Test various invalid super-constraints for mixin declarations.
+
+abstract class UnaryNum {
+  num foo(num x);
+}
+
+// Overides must still be valid, wrt. signatures and types.
+
+mixin M3 on UnaryNum {
+  // M3.foo is a valid override of UnaryNum.foo
+  num foo(num x) => super.foo(x) * 2;
+}
+
+// Invalid signature override (overriding optional parameter with required).
+class C3 implements UnaryNum {
+  // C3.foo is a valid override of UnaryNum.foo
+  num foo([num x]) => x ?? 17;
+}
+// M3.foo is not a valid override for C3.foo.
+class A3 extends C3 //
+    with M3 //# 06: compile-time error
+{}
+
+// Invalid type override (overriding `int` return with `num` return).
+class C4 implements UnaryNum {
+  // C4.foo is a valid override of UnaryNum.foo
+  int foo(num x) => x.toInt();
+}
+// M3.foo is not a valid override for C4.foo.
+class A4 extends C4 //
+    with M3 //# 07: compile-time error
+{}
+
+// It's not required to have an implementation of members which are not super-
+// invoked, if the application class is abstract.
+abstract class C5 {
+  num foo(num x);
+  num bar(num x);
+}
+mixin M5 on C5 {
+  num baz(num x) => super.foo(x);
+}
+abstract class C5Foo implements C5 {
+  num foo(num x) => x;
+}
+abstract class C5Bar implements C5 {
+  num bar(num x) => x;
+}
+
+// Valid abstract class, super-invocation of foo hits implementation,
+// even if bar is still abstract.
+abstract class A5Foo = C5Foo with M5;
+// Invalid since super-invocaton of foo does not hit concrete implementation.
+abstract class _ = C5Bar with M5;  //# 08: compile-time error
+
+class A5FooConcrete = A5Foo with C5Bar;
+
+main() {
+  Expect.equals(42, A5FooConcrete().baz(42));
+}
\ No newline at end of file
diff --git a/tests/language_2/mixin_declaration/mixin_declaration_invalid_superinvocation_test.dart b/tests/language_2/mixin_declaration/mixin_declaration_invalid_superinvocation_test.dart
new file mode 100644
index 0000000..500ec14
--- /dev/null
+++ b/tests/language_2/mixin_declaration/mixin_declaration_invalid_superinvocation_test.dart
@@ -0,0 +1,61 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test various invalid super-invocations for mixin declarations.
+
+abstract class UnaryInt {
+  num foo(int x);
+}
+
+abstract class UnaryNum {
+  num foo(num x);
+}
+
+abstract class UnaryOptionalNum {
+  num foo([num x]);
+}
+
+// Mixins may contain super-invocations.
+// The super-invocation must be valid against the combined super-interfaces
+// (i.e., valid against the most specific of them for that method).
+
+mixin M1 on UnaryNum {
+  void bar() {
+    super.foo(); //# 01: compile-time error
+    super.foo(1, 2); //# 02: compile-time error
+    super.foo("not num"); //# 03: compile-time error
+    super.bar; //# 04: compile-time error
+    super + 2; //# 05: compile-time error
+  }
+}
+
+mixin M2 on UnaryNum, UnaryInt {
+  void bar() {
+    super.foo(4.2); // Allows most specific type.
+    super.foo(1, 2); //# 06: compile-time error
+    super.foo("not num"); //# 07: compile-time error
+  }
+}
+
+mixin M3 on UnaryNum, UnaryOptionalNum {
+  void bar() {
+    super.foo(4.2);
+    super.foo();     //# 10: ok
+    super.foo(1, 2); //# 08: compile-time error
+    super.foo("not num"); //# 09: compile-time error
+  }
+}
+
+class C1 implements UnaryNum, UnaryInt, UnaryOptionalNum {
+  num foo([num x]) => x ?? 37.0;
+}
+
+class A1 = C1 with M1;
+class A2 = C1 with M2;
+class A3 = C1 with M3;
+main() {
+  A1().bar();
+  A2().bar();
+  A3().bar();
+}
diff --git a/tests/language_2/mixin_declaration/mixin_declaration_invalid_syntax_test.dart b/tests/language_2/mixin_declaration/mixin_declaration_invalid_syntax_test.dart
new file mode 100644
index 0000000..0ff26d6
--- /dev/null
+++ b/tests/language_2/mixin_declaration/mixin_declaration_invalid_syntax_test.dart
@@ -0,0 +1,64 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for 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";
+
+// Test various invalid syntax combinations.
+
+// You cannot prefix "mixin" with anything.
+abstract //# 01: compile-time error
+static //# 02: compile-time error
+const //# 03: compile-time error
+mixin M0 {}
+
+// Cannot use "extends".
+mixin M1 //
+  extends A //# 04: compile-time error
+{}
+
+// On-clause must be before implements clause.
+mixin M2
+  implements B //# 05: compile-time error
+  on A
+{}
+
+// Cannot use "on" on class declarations.
+class C0 //
+  on A //# 06: compile-time error
+{}
+
+// Type parameters must not be empty.
+mixin M3 //
+  <> //# 07: compile-time error
+{}
+
+// Super-class restrictions and implements must be well-formed.
+mixin M4 on List
+  <UndeclaredType> //# 08: compile-time error
+{}
+mixin M5 implements List
+  <UndeclaredType> //# 09: compile-time error
+{}
+
+mixin M6 {
+  // Mixins cannot have constructors (or members with same name as mixin).
+  factory M6() {} //# 10: compile-time error
+  M6() {} //# 11: compile-time error
+  M6.foo(); //# 12: compile-time error
+  get M6 => 42; //# 13: compile-time error
+}
+
+// Cannot declare local mixins.
+class C {
+  static mixin M {}; //# 14: compile-time error
+  mixin M {} //# 15: compile-time error
+}
+
+// Just to have some types.
+class A {}
+class B {}
+
+main() {
+  new C();
+}
\ No newline at end of file
diff --git a/tests/language_2/mixin_declaration/mixin_declaration_invalid_type_test.dart b/tests/language_2/mixin_declaration/mixin_declaration_invalid_type_test.dart
new file mode 100644
index 0000000..0fad558
--- /dev/null
+++ b/tests/language_2/mixin_declaration/mixin_declaration_invalid_type_test.dart
@@ -0,0 +1,49 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for 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";
+
+// Test various invalid type-declaration combinations.
+
+// Types must be class types.
+mixin M on void {} //# 01: compile-time error
+mixin M on double {} //# 02: compile-time error
+mixin M on FutureOr<int> {} //# 03: compile-time error
+mixin M on FunType {} //# 04: compile-time error
+
+mixin M implements void {} //# 05: compile-time error
+mixin M implements double {} //# 06: compile-time error
+mixin M implements FutureOr<int> {} //# 07: compile-time error
+mixin M implements FunType {} //# 08: compile-time error
+
+// Types must be extensible.
+mixin M on bool {} //# 09: compile-time error
+mixin M on num {} //# 10: compile-time error
+mixin M on int {} //# 11: compile-time error
+mixin M on double {} //# 12: compile-time error
+mixin M on Null {} //# 13: compile-time error
+mixin M on String {} //# 14: compile-time error
+mixin M implements bool {} //# 15: compile-time error
+mixin M implements num {} //# 16: compile-time error
+mixin M implements int {} //# 17: compile-time error
+mixin M implements double {} //# 18: compile-time error
+mixin M implements Null {} //# 19: compile-time error
+mixin M implements String {} //# 20: compile-time error
+
+// Mixin type cannot depend on itself
+mixin M on M {} //# 21: compile-time error
+mixin M implements M {} //# 22: compile-time error
+
+// Types must exist and be valid
+mixin M on Undeclared {} //# 23: compile-time error
+mixin M on A<int> {} //# 24: compile-time error
+mixin M implements Undeclared {} //# 25: compile-time error
+mixin M implements A<int> {} //# 26: compile-time error
+
+main() {}
+
+// Just to have some types.
+class A {}
+class B {}
+typedef FuntType = int Function(int);
diff --git a/tests/language_2/mixin_declaration/mixin_declaration_invalid_usage_test.dart b/tests/language_2/mixin_declaration/mixin_declaration_invalid_usage_test.dart
new file mode 100644
index 0000000..83e50b4d
--- /dev/null
+++ b/tests/language_2/mixin_declaration/mixin_declaration_invalid_usage_test.dart
@@ -0,0 +1,19 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+mixin Mixin // cannot `extend` anything.
+  extends M //# 01: compile-time error
+  extends Object //# 02: compile-time error
+{}
+
+// You cannot extend a mixin.
+class Class // cannot extend a mixin
+  extends Mixin //# 03: compile-time error
+{}
+
+void main() {
+  // Cannot instantiate a mixin.
+  new Mixin();  //# 04: compile-time error
+  new Class();
+}
\ No newline at end of file
diff --git a/tests/language_2/mixin_declaration/mixin_declaration_nsm_test.dart b/tests/language_2/mixin_declaration/mixin_declaration_nsm_test.dart
new file mode 100644
index 0000000..ccfde7b
--- /dev/null
+++ b/tests/language_2/mixin_declaration/mixin_declaration_nsm_test.dart
@@ -0,0 +1,39 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for 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";
+
+abstract class Bar {
+  String bar();
+}
+
+abstract class Foo {
+  String foo();
+}
+
+mixin M implements Bar {
+  dynamic noSuchMethod(i) => "M:${i.memberName == #foo ? "foo" : "bar"}";
+}
+
+abstract class C {
+  dynamic noSuchMethod(i) => "C:${i.memberName == #foo ? "foo" : "bar"}";
+}
+
+abstract class D {
+  String foo() => "D:foo";
+  String bar() => "D:bar";
+}
+
+class A1 extends Foo with M {}
+class A2 extends C with M implements Foo {}
+class A3 extends D with M implements Foo {}
+
+main() {
+  Expect.equals("M:foo", A1().foo());
+  Expect.equals("M:bar", A1().bar());
+  Expect.equals("M:foo", A2().foo());
+  Expect.equals("M:bar", A2().bar());
+  Expect.equals("D:foo", A3().foo());
+  Expect.equals("D:bar", A3().bar());
+}
\ No newline at end of file
diff --git a/tests/language_2/mixin_declaration/mixin_declaration_on_keyword_test.dart b/tests/language_2/mixin_declaration/mixin_declaration_on_keyword_test.dart
new file mode 100644
index 0000000..f4cc1f1
--- /dev/null
+++ b/tests/language_2/mixin_declaration/mixin_declaration_on_keyword_test.dart
@@ -0,0 +1,27 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for 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";
+
+// The `on` word is not a reserved word or built-in identifier.
+// It's a purely contextual keyword.
+// A type can have the name `on`, and even a mixin.
+
+class A {}
+
+mixin on on A {}
+
+mixin M on on {}
+
+mixin M2 implements on {}
+
+class B = A with on;
+class C = B with M;
+class D = Object with M2;
+
+main() {
+  Expect.type<on>(B());
+  Expect.type<on>(C());
+  Expect.type<on>(D());
+}
\ No newline at end of file
diff --git a/tests/language_2/mixin_declaration/mixin_declaration_static_scope_test.dart b/tests/language_2/mixin_declaration/mixin_declaration_static_scope_test.dart
new file mode 100644
index 0000000..79450cd
--- /dev/null
+++ b/tests/language_2/mixin_declaration/mixin_declaration_static_scope_test.dart
@@ -0,0 +1,36 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for 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";
+
+// A mixin declaration introduces a static scope.
+// Instance members keep seeing this scope when mixed in.
+
+abstract class UnaryNum {
+  num foo(num x);
+}
+
+mixin M1 on UnaryNum {
+  static int counter = 0;
+  static int next() => ++counter;
+  int count() => foo(next());
+}
+
+class C1 implements UnaryNum {
+  static int counter = 87;
+  static int next() => 42;
+  num foo(num x) => x * 10;
+}
+
+class A1 = C1 with M1;
+
+main() {
+  Expect.equals(0, M1.counter);
+  Expect.equals(1, M1.next());
+  Expect.equals(2, M1.next());
+  var a = A1();
+  Expect.equals(30, a.count());
+  Expect.equals(40, a.count());
+  Expect.equals(5, M1.next());
+}
diff --git a/tests/language_2/mixin_declaration/mixin_declaration_subtype_test.dart b/tests/language_2/mixin_declaration/mixin_declaration_subtype_test.dart
new file mode 100644
index 0000000..172bb23
--- /dev/null
+++ b/tests/language_2/mixin_declaration/mixin_declaration_subtype_test.dart
@@ -0,0 +1,51 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for 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";
+
+// A mixin declaration introduces a type.
+
+// A mixin with multiple super-types and implemented types.
+class A {}
+class B {}
+class I {}
+class J {}
+
+mixin M on A, B implements I, J {}
+
+class C implements A, B {}
+
+class D = C with M;
+
+// Same, with generics.
+class GA<T> {}
+class GB<T> {}
+class GI<T> {}
+class GJ<T> {}
+
+mixin GM<T> on GA<T>, GB<List<T>> implements GI<Iterable<T>>, GJ<Set<T>> {}
+
+class GC<T> implements GA<T>, GB<List<T>> {}
+
+class GD<T> = GC<T> with GM<T>;
+
+main() {
+  Expect.subtype<M, A>();
+  Expect.subtype<M, B>();
+  Expect.subtype<M, I>();
+  Expect.subtype<M, J>();
+  Expect.subtype<D, M>();
+  Expect.subtype<D, C>();
+  Expect.notSubtype<M, C>();
+  Expect.notSubtype<C, M>();
+
+  Expect.subtype<GM<int>, GA<int>>();
+  Expect.subtype<GM<int>, GB<List<int>>>();
+  Expect.subtype<GM<int>, GI<Iterable<int>>>();
+  Expect.subtype<GM<int>, GJ<Set<int>>>();
+  Expect.subtype<GD<int>, GM<int>>();
+  Expect.subtype<GD<int>, GC<int>>();
+  Expect.notSubtype<GM<int>, GC<int>>();
+  Expect.notSubtype<GC<int>, GM<int>>();
+}
\ No newline at end of file
diff --git a/tests/language_2/mixin_declaration/mixin_declaration_superinvocation_application_test.dart b/tests/language_2/mixin_declaration/mixin_declaration_superinvocation_application_test.dart
new file mode 100644
index 0000000..1a07759
--- /dev/null
+++ b/tests/language_2/mixin_declaration/mixin_declaration_superinvocation_application_test.dart
@@ -0,0 +1,62 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test various invalid mixin applications due to insufficient super-invoked
+// methods.
+
+abstract class UnaryNum {
+  num foo(num x);
+}
+
+abstract class UnaryOptionalNum {
+  num foo([num x]);
+}
+
+// When a mixin is applied, the super-invoked methods must have
+// a concrete implementation in the superclass which satisfies
+// the signature in the super-interfaces.
+
+mixin M1 on UnaryNum {
+  num bar() {
+    return super.foo(42.0);
+  }
+}
+
+// The super-invoked method must be non-abstract.
+class A1 extends UnaryNum //
+    with M1 //# 04: compile-time error
+{
+  // M1.bar does super.foo and UnaryNum has no implementation.
+  num foo(num x) => x;
+}
+
+// The super-invoked method must satisfy the most specific signature
+// among super-interfaces of the mixin.
+class C1 {
+  num foo(num x) => x;
+}
+
+abstract class C2 extends C1 implements UnaryOptionalNum {
+  num foo([num x]);
+}
+
+mixin M2 on UnaryOptionalNum {
+  num bar() {
+    // Allowed, super.foo has signature num Function([num]).
+    return super.foo(42.0);
+  }
+}
+
+class A2 extends C2 //
+    with M2 //# 05: compile-time error
+{
+  // M2.bar does a super.foo, so C2.foo must satisfy the super-interface of M2.
+  // It doesn't, even if the super-call would succeed against C1.foo.
+  num foo([num x]) => x ?? 0;
+}
+
+main() {
+  A1().bar(); //# 04: continued
+  A2().bar(); //# 05: continued
+}
\ No newline at end of file
diff --git a/tests/language_2/mixin_declaration/mixin_declaration_supertype_compatible_test.dart b/tests/language_2/mixin_declaration/mixin_declaration_supertype_compatible_test.dart
new file mode 100644
index 0000000..5307979
--- /dev/null
+++ b/tests/language_2/mixin_declaration/mixin_declaration_supertype_compatible_test.dart
@@ -0,0 +1,73 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for 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";
+
+// Test various invalid super-constraints for mixin declarations.
+
+abstract class BinaryNumInt {
+  num foo(num x, int y);
+}
+
+abstract class BinaryIntNum {
+  num foo(int x, num y);
+}
+
+abstract class GetterNumNum {
+  num Function(num) get foo;
+}
+
+abstract class GetterIntInt {
+  int Function(int) get foo;
+}
+
+abstract class UnaryInt {
+  num foo(int x);
+}
+
+abstract class UnaryNum {
+  num foo(num x);
+}
+
+abstract class UnaryString {
+  num foo(String x);
+}
+
+// The super-interfaces must be *compatible*.
+// Any member declared by more than one super-interface must have at
+// least one most-specific signature among the super-interfaces.
+
+// Incompatible member kinds, one is a getter, the other a method.
+mixin _ on UnaryNum, GetterNumNum {} //# 01: compile-time error
+
+// Incompatible signature structure, unary vs binary.
+mixin _ on UnaryNum, BinaryNumInt {} //# 02: compile-time error
+
+// Incompatible method parameter type, neither is more specific.
+mixin _ on UnaryNum, UnaryString {} //# 03: compile-time error
+
+// Compatible types for each parameter, but still no most specific signature.
+mixin _ on BinaryNumInt, BinaryIntNum {} //# 04: compile-time error
+
+// Incompatible return type for getter.
+mixin _ on GetterNumNum, GetterIntInt {} //# 05: compile-time error
+
+
+// Mixin is valid when one signature is more specific.
+mixin M1 on UnaryNum, UnaryInt {
+  // May call the method in a super-invocation, at the most specific type.
+  num bar() {
+    return super.foo(42.0);
+  }
+}
+
+class C1 implements UnaryNum, UnaryInt {
+  num foo(num x) => x;
+}
+
+class A1 = C1 with M1;
+
+main() {
+  Expect.equals(42.0, A1().bar());
+}
\ No newline at end of file
diff --git a/tests/language_2/mixin_declaration/mixin_declaration_syntax_test.dart b/tests/language_2/mixin_declaration/mixin_declaration_syntax_test.dart
new file mode 100644
index 0000000..6159af9
--- /dev/null
+++ b/tests/language_2/mixin_declaration/mixin_declaration_syntax_test.dart
@@ -0,0 +1,405 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for 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";
+
+// Test various combinations of valid mixin declarations.
+
+// Class unrelated to everything else here, just Object with a toString.
+class O {
+  String toString() => "O";
+}
+
+abstract class A {
+  String toString() => "A";
+  String methodA() => "A:${this}.A";
+}
+
+class B implements A {
+  String toString() => "B";
+  String methodA() => "B:${this}.A";
+  String methodB() => "B:${this}.B";
+}
+
+class C extends A {
+  String toString() => "C";
+  String methodA() => "C:${this}.A->${super.methodA()}";
+  String methodC() => "C:${this}.C";
+}
+
+class AIJ implements A, I, J {
+  String toString() => "AIJ";
+  String methodA() => "AIJ:${this}.A";
+  String methodI() => "AIJ:${this}.I";
+  String methodJ() => "AIJ:${this}.J";
+}
+
+class BC extends C implements B {
+  String toString() => "BC";
+  String methodA() => "BC:${this}.A->${super.methodA()}";
+  String methodB() => "BC:${this}.B";
+  String methodC() => "BC:${this}.C->${super.methodC()}";
+}
+
+// Interfaces.
+abstract class I {
+  String methodI();
+}
+abstract class J {
+  String methodJ();
+}
+
+// Simple mixin with no super-invocations, no super restrictions
+// and no interfaces implemented.
+mixin M {
+  String toString() => "?&M";
+  String methodM() => "M:${this}.M";
+}
+
+
+// Mixin which uses the implicit "on Object" to do a super-invocation.
+mixin MO {
+  String toString() => "${super.toString()}&MO";
+  String methodMO() => "MO:${this}.MO";
+}
+
+
+// Mixin with "implements" clause.
+mixin MOiIJ implements I, J {
+  String toString() => "${super.toString()}&MOiIJ";
+  String methodMOiIJ() => "MOiIJ:${this}.MOiIJ";
+  String methodI() => "MOiIJ:${this}.I";
+  String methodJ() => "MOiIJ:${this}.J";
+}
+
+
+// Mixin with single non-Object super-constraint.
+mixin MA on A {
+  String toString() => "${super.toString()}&MA";
+  String methodMA() => "MA:${this}.MA";
+  String methodA() => "MA:${this}.A->${super.methodA()}";
+}
+
+
+// Mixin with super-restriction implementing other interfaces.
+mixin MAiBC on A implements B, C {
+  String toString() => "${super.toString()}&MAiBC";
+  String methodMAiBC() => "MAiBC:${this}.MAiBC";
+  String methodA() => "MAiBC:${this}.A->${super.methodA()}";
+  String methodB() => "MAiBC:${this}.B";
+  String methodC() => "MAiBC:${this}.C";
+}
+
+// Mixin with "implements" clause.
+mixin MBiIJ on B implements I, J {
+  String toString() => "${super.toString()}&MBiIJ";
+  String methodMOiIJ() => "MBiIJ:${this}.MBiIJ";
+  String methodI() => "MBiIJ:${this}.I";
+  String methodJ() => "MBiIJ:${this}.J";
+}
+
+
+// Mixin on more than one class.
+mixin MBC on B, C {
+  String toString() => "${super.toString()}&MBC";
+  String methodMBC() => "MBC:${this}.MBC";
+  String methodA() => "MBC:${this}.A->${super.methodA()}";
+  String methodB() => "MBC:${this}.B->${super.methodB()}";
+  String methodC() => "MBC:${this}.C->${super.methodC()}";
+}
+
+
+// One with everything.
+mixin MBCiIJ on B, C implements I, J {
+  String toString() => "${super.toString()}&MBCiIJ";
+  String methodMBCiIJ() => "MBCiIJ:${this}.MBCiIJ";
+  String methodA() => "MBCiIJ:${this}.A->${super.methodA()}";
+  String methodB() => "MBCiIJ:${this}.B->${super.methodB()}";
+  String methodC() => "MBCiIJ:${this}.C->${super.methodC()}";
+  String methodI() => "MBCiIJ:${this}.I";
+  String methodJ() => "MBCiIJ:${this}.J";
+}
+
+
+// Abstract mixin, doesn't implement its interface.
+mixin MiIJ implements I, J {
+  String toString() => "${super.toString()}&MiIJ";
+}
+
+
+// Applications of the mixins.
+
+class COaM = O with M;
+
+class COaM_2 extends O with M {}
+
+class CBaM = B with M;
+
+class CBaM_2 extends B with M {}
+
+class COaMO = O with MO;
+
+class COaMO_2 extends O with MO {}
+
+class CBaMO = B with MO;
+
+class CBaMO_2 extends B with MO {}
+
+class COaMOiIJ = O with MOiIJ;
+
+class COaMOiIJ_2 extends O with MOiIJ {}
+
+class CBaMBiIJ = B with MBiIJ;
+
+class CBaMBiIJ_2 extends B with MBiIJ {}
+
+class CAaMA = A with MA;
+
+class CAaMA_2 extends A with MA {}
+
+class CBaMA = B with MA;
+
+class CBaMA_2 extends B with MA {}
+
+class CAaMAiBC = A with MAiBC;
+
+class CAaMAiBC_2 extends A with MAiBC {}
+
+class CBaMAiBC = B with MAiBC;
+
+class CBaMAiBC_2 extends B with MAiBC {}
+
+class CBCaMBC = BC with MBC;
+
+class CBCaMBC_2 extends BC with MBC {}
+
+class CAaMAiBCaMBC = CAaMAiBC with MBC;
+
+class CAaMAiBCaMBC_2 extends CAaMAiBC with MBC {}
+
+class CBCaMBCiIJ = BC with MBCiIJ;
+
+class CBCaMBCiIJ_2 extends BC with MBCiIJ {}
+
+class CAaMAiBCaMBCiIJ = CAaMAiBC with MBCiIJ;
+
+class CAaMAiBCaMBCiIJ_2 extends CAaMAiBC with MBCiIJ {}
+
+// Abstract mixin application does not implement I and J.
+abstract class OaMiIJ = O with MiIJ;
+
+// Concrete subclass of abstract mixin appliction
+class COaMiIJ extends OaMiIJ {
+  String toString() => "${super.toString()}:$COaMiIJ";
+  String methodI() => "COaMiIJ:${this}.I";
+  String methodJ() => "COaMiIJ:${this}.J";
+}
+
+// Abstract class with mixin application and does not implement I and J.
+abstract class OaMiIJ_2 extends O with MiIJ {}
+
+// Concrete subclass of abstract mixin appliction
+class COaMiIJ_2 extends OaMiIJ_2 {
+  String toString() => "${super.toString()}:$COaMiIJ";
+  String methodI() => "COaMiIJ:${this}.I";
+  String methodJ() => "COaMiIJ:${this}.J";
+}
+
+// Test of `class C with M` syntax.
+class CwithM with M {}
+class CeOwithM extends Object with M {}
+
+// Test that the mixin applications behave as expected.
+void main() {
+  {
+    for (dynamic o in [COaM(), COaM_2()]) {
+      Expect.type<O>(o);
+      Expect.type<M>(o);
+      Expect.equals("?&M", "$o");
+      Expect.equals("M:$o.M", o.methodM());
+    }
+  }
+
+  {
+    for (var o in [CBaM(), CBaM_2()]) {
+      Expect.type<B>(o);
+      Expect.type<M>(o);
+      Expect.equals("?&M", "$o");
+      Expect.equals("B:$o.B", o.methodB());
+      Expect.equals("M:$o.M", (o as M).methodM());
+    }
+  }
+
+  {
+    for (dynamic o in [COaMO(), COaMO_2()]) {
+      Expect.type<O>(o);
+      Expect.type<MO>(o);
+      Expect.equals("O&MO", "$o");
+      Expect.equals("MO:$o.MO", o.methodMO());
+    }
+  }
+
+  {
+    for (var o in [CBaMO(), CBaMO_2()]) {
+      Expect.type<B>(o);
+      Expect.type<MO>(o);
+      Expect.equals("B&MO", "$o");
+      Expect.equals("MO:$o.MO", (o as MO).methodMO());
+      Expect.equals("B:$o.B", o.methodB());
+    }
+  }
+
+  {
+    for (dynamic o in [COaMOiIJ(), COaMOiIJ_2()]) {
+      Expect.type<O>(o);
+      Expect.type<I>(o);
+      Expect.type<J>(o);
+      Expect.type<MOiIJ>(o);
+      Expect.equals("O&MOiIJ", "$o");
+      Expect.equals("MOiIJ:$o.MOiIJ", o.methodMOiIJ());
+      Expect.equals("MOiIJ:$o.I", o.methodI());
+      Expect.equals("MOiIJ:$o.J", o.methodJ());
+    }
+  }
+
+  {
+    for (dynamic o in [CBaMBiIJ(), CBaMBiIJ_2()]) {
+      Expect.type<B>(o);
+      Expect.type<I>(o);
+      Expect.type<J>(o);
+      Expect.type<MBiIJ>(o);
+      Expect.equals("B&MBiIJ", "$o");
+      Expect.equals("MBiIJ:$o.MBiIJ", o.methodMOiIJ());
+      Expect.equals("B:$o.B", o.methodB());
+      Expect.equals("MBiIJ:$o.I", o.methodI());
+      Expect.equals("MBiIJ:$o.J", o.methodJ());
+    }
+  }
+
+  {
+    for (dynamic o in [CAaMA(), CAaMA_2()]) {
+      Expect.type<A>(o);
+      Expect.type<MA>(o);
+      Expect.equals("A&MA", "$o");
+      Expect.equals("MA:$o.MA", o.methodMA());
+      Expect.equals("MA:$o.A->A:$o.A", o.methodA());
+    }
+  }
+
+  {
+    for (var o in [CBaMA(), CBaMA_2()]) {
+      Expect.type<B>(o);
+      Expect.type<MA>(o);
+      Expect.equals("B&MA", "$o");
+      Expect.equals("MA:$o.MA", (o as MA).methodMA());
+      Expect.equals("MA:$o.A->B:$o.A", (o as MA).methodA());
+      Expect.equals("B:$o.B", o.methodB());
+    }
+  }
+
+  {
+    for (dynamic o in [CAaMAiBC(), CAaMAiBC_2()]) {
+      Expect.type<A>(o);
+      Expect.type<B>(o);
+      Expect.type<C>(o);
+      Expect.type<MAiBC>(o);
+      Expect.equals("A&MAiBC", "$o");
+      Expect.equals("MAiBC:$o.MAiBC", o.methodMAiBC());
+      Expect.equals("MAiBC:$o.A->A:$o.A", o.methodA());
+      Expect.equals("MAiBC:$o.B", o.methodB());
+      Expect.equals("MAiBC:$o.C", o.methodC());
+    }
+  }
+
+  {
+    for (dynamic o in [CBaMAiBC(), CBaMAiBC_2()]) {
+      Expect.type<A>(o);
+      Expect.type<B>(o);
+      Expect.type<C>(o);
+      Expect.type<MAiBC>(o);
+      Expect.equals("B&MAiBC", "$o");
+      Expect.equals("MAiBC:$o.MAiBC", o.methodMAiBC());
+      Expect.equals("MAiBC:$o.A->B:$o.A", o.methodA());
+      Expect.equals("MAiBC:$o.B", o.methodB());
+      Expect.equals("MAiBC:$o.C", o.methodC());
+    }
+  }
+
+  {
+    for (dynamic o in [CBCaMBC(), CBCaMBC_2()]) {
+      Expect.type<BC>(o);
+      Expect.type<MBC>(o);
+      Expect.equals("BC&MBC", "$o");
+      Expect.equals("MBC:$o.MBC", o.methodMBC());
+      Expect.equals("MBC:$o.A->BC:$o.A->C:$o.A->$A:$o.A", o.methodA());
+      Expect.equals("MBC:$o.B->BC:$o.B", o.methodB());
+      Expect.equals("MBC:$o.C->BC:$o.C->C:$o.C", o.methodC());
+    }
+  }
+
+  {
+    // Mixin on top of mixin application.
+    for (dynamic o in [CAaMAiBCaMBC(), CAaMAiBCaMBC_2()]) {
+      Expect.type<CAaMAiBC>(o);
+      Expect.type<MBC>(o);
+      Expect.equals("A&MAiBC&MBC", "$o");
+      Expect.equals("MBC:$o.MBC", (o as MBC).methodMBC());
+      Expect.equals("MAiBC:$o.MAiBC", o.methodMAiBC());
+      Expect.equals("MBC:$o.A->MAiBC:$o.A->$A:$o.A", o.methodA());
+      Expect.equals("MBC:$o.B->MAiBC:$o.B", o.methodB());
+      Expect.equals("MBC:$o.C->MAiBC:$o.C", o.methodC());
+    }
+  }
+
+  {
+    for (dynamic o in [CBCaMBCiIJ(), CBCaMBCiIJ_2()]) {
+      Expect.type<BC>(o);
+      Expect.type<MBCiIJ>(o);
+      Expect.type<I>(o);
+      Expect.type<J>(o);
+      Expect.equals("BC&MBCiIJ", "$o");
+      Expect.equals("MBCiIJ:$o.MBCiIJ", o.methodMBCiIJ());
+      Expect.equals("MBCiIJ:$o.A->BC:$o.A->C:$o.A->$A:$o.A", o.methodA());
+      Expect.equals("MBCiIJ:$o.B->BC:$o.B", o.methodB());
+      Expect.equals("MBCiIJ:$o.C->BC:$o.C->C:$o.C", o.methodC());
+      Expect.equals("MBCiIJ:$o.I", o.methodI());
+      Expect.equals("MBCiIJ:$o.J", o.methodJ());
+    }
+  }
+
+  {
+    // Mixin on top of mixin application.
+    for (dynamic o in [CAaMAiBCaMBCiIJ(), CAaMAiBCaMBCiIJ_2()]) {
+      Expect.type<CAaMAiBC>(o);
+      Expect.type<MBCiIJ>(o);
+      Expect.type<I>(o);
+      Expect.type<J>(o);
+      Expect.equals("A&MAiBC&MBCiIJ", "$o");
+      Expect.equals("MBCiIJ:$o.MBCiIJ", o.methodMBCiIJ());
+      Expect.equals("MAiBC:$o.MAiBC", (o as CAaMAiBC).methodMAiBC());
+      Expect.equals("MBCiIJ:$o.A->MAiBC:$o.A->$A:$o.A", o.methodA());
+      Expect.equals("MBCiIJ:$o.B->MAiBC:$o.B", o.methodB());
+      Expect.equals("MBCiIJ:$o.C->MAiBC:$o.C", o.methodC());
+      Expect.equals("MBCiIJ:$o.I", o.methodI());
+      Expect.equals("MBCiIJ:$o.J", o.methodJ());
+    }
+  }
+
+  {
+    // Abstract mixin application, concrete subclass.
+    for (dynamic o in [COaMiIJ(), COaMiIJ_2()]) {
+      Expect.type<O>(o);
+      Expect.type<MiIJ>(o);
+      Expect.isTrue(o is OaMiIJ || o is OaMiIJ_2,
+          "`$o` should subtype OaMiIJ or OaMiIJ_2");
+      Expect.type<I>(o);
+      Expect.type<J>(o);
+      Expect.equals("O&MiIJ:COaMiIJ", "$o");
+      Expect.equals("COaMiIJ:$o.I", o.methodI());
+      Expect.equals("COaMiIJ:$o.J", o.methodJ());
+    }
+  }
+
+  Expect.equals(CeOwithM().toString(), CwithM().toString());
+}
diff --git a/tests/language_2/partial_instantiation_static_bounds_check_test.dart b/tests/language_2/partial_instantiation_static_bounds_check_test.dart
new file mode 100644
index 0000000..2bfa732
--- /dev/null
+++ b/tests/language_2/partial_instantiation_static_bounds_check_test.dart
@@ -0,0 +1,28 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+topFn<T extends num>(T x) {
+  print(T);
+}
+
+class C<T> {
+  instanceFn<S extends T>(S x) {
+    print(S);
+  }
+}
+
+class D<T> extends C<T> {
+  void foo() {
+    void Function(int) k = instanceFn; //# 03: compile-time error
+  }
+}
+
+void main() {
+  localFn<T extends num>(T x) {
+    print(T);
+  }
+
+  void Function(String) k0 = localFn; //# 01: compile-time error
+  void Function(String) k1 = topFn; //# 02: compile-time error
+}
diff --git a/tests/language_2/regress_33479_test.dart b/tests/language_2/regress_33479_test.dart
new file mode 100644
index 0000000..80515ff3
--- /dev/null
+++ b/tests/language_2/regress_33479_test.dart
@@ -0,0 +1,9 @@
+class Hest<TypeX extends Fisk> {}
+
+typedef Fisk = void Function // don't merge lines
+    <TypeY extends Hest> //# 01: compile-time error
+        ();
+
+main() {
+  Hest hest = new Hest();
+}
diff --git a/tests/language_2/regress_34482_test.dart b/tests/language_2/regress_34482_test.dart
new file mode 100644
index 0000000..2390497
--- /dev/null
+++ b/tests/language_2/regress_34482_test.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for 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';
+
+main() {
+  Future f = new Future(() => 12345);
+  Future<FutureOr> f1 = f;
+
+  FutureOr fo = f;
+  f1 = fo;
+}
diff --git a/tests/language_2/vm/regress_34396_helper.dart b/tests/language_2/vm/regress_34396_helper.dart
new file mode 100644
index 0000000..5e61334
--- /dev/null
+++ b/tests/language_2/vm/regress_34396_helper.dart
@@ -0,0 +1,8 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for 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 regress_34396_helper;
+
+get privateSymbol => #_privateSymbol;
+get privateSymbolSame => #_privateSymbol;
diff --git a/tests/language_2/vm/regress_34396_test.dart b/tests/language_2/vm/regress_34396_test.dart
new file mode 100644
index 0000000..ead2b0b
--- /dev/null
+++ b/tests/language_2/vm/regress_34396_test.dart
@@ -0,0 +1,17 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for 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 'regress_34396_helper.dart' as helper;
+
+main() {
+  Expect.isFalse(#_privateSymbol == helper.privateSymbol);
+  Expect.isFalse(#_privateSymbol == helper.privateSymbolSame);
+  Expect.isFalse(identical(#_privateSymbol, helper.privateSymbol));
+  Expect.isFalse(identical(#_privateSymbol, helper.privateSymbolSame));
+
+  Expect.isTrue(helper.privateSymbol == helper.privateSymbolSame);
+  Expect.isTrue(identical(helper.privateSymbol, helper.privateSymbolSame));
+}
diff --git a/tests/lib_2/async/stream_take_test.dart b/tests/lib_2/async/stream_take_test.dart
index b681e88..853cc77 100644
--- a/tests/lib_2/async/stream_take_test.dart
+++ b/tests/lib_2/async/stream_take_test.dart
@@ -61,6 +61,9 @@
   Expect.listEquals([], await makeStream(5).take(0).toList());
 
   Expect.listEquals([], await makeStream(0).take(0).toList());
+
+  // Regression for https://github.com/dart-lang/sdk/issues/30305
+  Expect.equals('result', await makeStream(5).take(0).drain('result'));
 }
 
 Future expectThrowsAsync(Future computation, String name) {
diff --git a/tests/lib_2/async/stream_transformer_from_bind_test.dart b/tests/lib_2/async/stream_transformer_from_bind_test.dart
new file mode 100644
index 0000000..fcc63a1
--- /dev/null
+++ b/tests/lib_2/async/stream_transformer_from_bind_test.dart
@@ -0,0 +1,25 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for 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:async_helper/async_helper.dart";
+import 'package:expect/expect.dart';
+
+import 'event_helper.dart';
+
+void main() {
+  asyncStart();
+  var transformer =
+      new StreamTransformer<int, String>.fromBind((s) => s.map((v) => '$v'));
+  var controller = new StreamController<int>(sync: true);
+  Events expected = new Events.fromIterable(['1', '2']);
+  Events input = new Events.fromIterable([1, 2]);
+  Events actual = new Events.capture(controller.stream.transform(transformer));
+  actual.onDone(() {
+    Expect.listEquals(expected.events, actual.events);
+    asyncEnd();
+  });
+  input.replay(controller);
+}
diff --git a/tests/lib_2/html/js_mock_test.dart b/tests/lib_2/html/js_mock_test.dart
index 94e62a7..310abc9 100644
--- a/tests/lib_2/html/js_mock_test.dart
+++ b/tests/lib_2/html/js_mock_test.dart
@@ -41,12 +41,11 @@
     expect(f, isNull);
 
     var doc = document;
+    expect(doc is Document, isTrue);
     // Fails in dart2js
-    // expect(doc is Document, isTrue);
-    expect(doc is! Element, isTrue);
+    //expect(doc is! Element, isTrue);
 
-    // Fails in dart2js
-    // expect(doc is Node, isTrue);
+    expect(doc is Node, isTrue);
 
     expect(doc is! MockDocument, isTrue);
     expect(doc is! MockElement, isTrue);
diff --git a/tests/lib_2/lib_2_dart2js.status b/tests/lib_2/lib_2_dart2js.status
index e2eb9a6..035de4d 100644
--- a/tests/lib_2/lib_2_dart2js.status
+++ b/tests/lib_2/lib_2_dart2js.status
@@ -258,7 +258,6 @@
 html/js_jsify_test: RuntimeError
 html/js_jsobject_test: RuntimeError
 html/js_methods_test: RuntimeError
-html/js_mock_test: RuntimeError
 html/js_transferrables_test: RuntimeError
 html/js_typed_interop_bind_this_test: RuntimeError
 html/js_typed_interop_callable_object_test: RuntimeError
diff --git a/tests/standalone_2/standalone_2_kernel.status b/tests/standalone_2/standalone_2_kernel.status
index 347a812..3019ae9 100644
--- a/tests/standalone_2/standalone_2_kernel.status
+++ b/tests/standalone_2/standalone_2_kernel.status
@@ -37,9 +37,6 @@
 [ $compiler == dartkb ]
 no_lazy_dispatchers_test: SkipByDesign # KBC interpreter doesn't support --no_lazy_dispatchers
 
-[ $compiler == fasta ]
-io/arguments_test: CompileTimeError
-
 [ $fasta ]
 deferred_transitive_import_error_test: CompileTimeError
 package/package1_test: CompileTimeError
diff --git a/tools/VERSION b/tools/VERSION
index 69aa10a..4bb7fc5 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 1
 PATCH 0
-PRERELEASE 4
+PRERELEASE 5
 PRERELEASE_PATCH 0
diff --git a/tools/bots/add_fields.dart b/tools/bots/add_fields.dart
new file mode 100644
index 0000000..56b313a
--- /dev/null
+++ b/tools/bots/add_fields.dart
@@ -0,0 +1,16 @@
+import 'dart:io';
+import 'dart:convert';
+
+/// This script reads the JSON object from the file at args[0] and
+/// adds data to it from the environment.  Args[1] should be the timestamp
+/// (as epoch seconds) of the current Git commit being tested.
+/// Args[2] should be the hash of the current Git commit under test.
+void main(List<String> args) {
+  Map<String, dynamic> map = jsonDecode(File(args[0]).readAsStringSync());
+  final env = Platform.environment;
+  map['commit_time'] = args[1];
+  map['commit_hash'] = args[2];
+  map['builder_name'] = env['SWARMING_BOT_ID'];
+  map['bot_name'] = env['BUILDBOT_BUILDERNAME'];
+  File(args[0]).writeAsStringSync(jsonEncode(map));
+}
diff --git a/tools/bots/test_matrix.json b/tools/bots/test_matrix.json
index 08fc477..088da9b 100644
--- a/tools/bots/test_matrix.json
+++ b/tools/bots/test_matrix.json
@@ -364,7 +364,7 @@
         "use-blobs": true
     }},
     "dartkp-linux-(product|release)-x64": { },
-    "dartkp-obsufcate-linux-release-x64": {
+    "dartkp-obfuscate-linux-release-x64": {
       "options": {
         "builder-tag": "obfuscated",
         "vm-options": ["--obfuscate"]
@@ -407,7 +407,14 @@
         "preview-dart-2": false
       }},
     "app_jitk-linux-(debug|product|release)-x64": { },
-    "dartkb-linux-(debug|release)-x64": { },
+    "dartkb-interpret-linux-(debug|release)-x64": {
+      "options": {
+        "vm-options": ["--enable_interpreter"]
+      }},
+    "dartkb-compile-linux-(debug|release)-x64": {
+      "options": {
+        "vm-options": ["--use_bytecode_compiler"]
+      }},
     "(dartdevc|dartdevk)-checked-(linux|mac|win)-release-chrome": {
       "options": {
         "checked": true,
@@ -516,16 +523,22 @@
           "name": "build dart",
           "script": "tools/build.py",
           "arguments": [
-            "--bytecode",
             "runtime"
           ]
         },
         {
-          "name": "vm tests",
+          "name": "vm interpreter tests",
           "arguments": [
-            "-ndartkb-linux-${mode}-x64",
+            "-ndartkb-interpret-linux-${mode}-x64",
             "--compiler=dartkb",
-            "vm",
+            "language_2"
+          ]
+        },
+        {
+          "name": "vm bytecode compiler tests",
+          "arguments": [
+            "-ndartkb-compile-linux-${mode}-x64",
+            "--compiler=dartkb",
             "language_2"
           ]
         }
@@ -669,7 +682,8 @@
         {
           "name": "vm tests",
           "arguments": [
-            "-ndartkp-${system}-${mode}-${arch}"
+            "-ndartkp-${system}-${mode}-${arch}",
+            "-v"
           ],
           "fileset": "vm-kernel",
           "shards": 10
@@ -695,7 +709,8 @@
         {
           "name": "vm tests",
           "arguments": [
-            "-ndartkp-obfuscate-${system}-${mode}-${arch}"
+            "-ndartkp-obfuscate-${system}-${mode}-${arch}",
+            "-v"
           ],
           "fileset": "vm-kernel",
           "shards": 10
@@ -1751,11 +1766,6 @@
           "arguments": ["--fatal-warnings", "pkg/dart_internal"]
         },
         {
-          "name": "analyze pkg/dart_messages",
-          "script": "out/ReleaseX64/dart-sdk/bin/dartanalyzer",
-          "arguments": ["--fatal-warnings", "pkg/dart_messages"]
-        },
-        {
           "name": "analyze pkg/dev_compiler",
           "script": "out/ReleaseX64/dart-sdk/bin/dartanalyzer",
           "arguments": ["--fatal-warnings", "pkg/dev_compiler"]
diff --git a/tools/bots/try_benchmarks.sh b/tools/bots/try_benchmarks.sh
index 4dba863..141b852 100755
--- a/tools/bots/try_benchmarks.sh
+++ b/tools/bots/try_benchmarks.sh
@@ -221,6 +221,7 @@
     out/ReleaseIA32/dart pkg/front_end/tool/fasta_perf.dart kernel_gen_e2e hello.dart
     out/ReleaseIA32/dart pkg/front_end/tool/fasta_perf.dart scan hello.dart
     out/ReleaseIA32/dart --print_metrics pkg/analyzer_cli/bin/analyzer.dart --dart-sdk=sdk hello.dart
+    out/ReleaseIA32/run_vm_tests InitialRSS
     cd ..
     rm -rf tmp
   elif [ "$command" = linux-x64-build ]; then
@@ -403,6 +404,7 @@
     out/ReleaseX64/dart --background-compilation=false pkg/front_end/tool/incremental_perf.dart.appjit --target=vm --sdk-summary=out/ReleaseX64/vm_platform_strong.dill --sdk-library-specification=sdk/lib/libraries.json pkg/front_end/benchmarks/ikg/hello.dart pkg/front_end/benchmarks/ikg/hello.edits.json
     out/ReleaseX64/dart --background-compilation=false pkg/front_end/tool/incremental_perf.dart.appjit --target=vm --implementation=minimal --sdk-summary=out/ReleaseX64/vm_platform_strong.dill --sdk-library-specification=sdk/lib/libraries.json pkg/front_end/benchmarks/ikg/hello.dart pkg/front_end/benchmarks/ikg/hello.edits.json
     out/ReleaseX64/dart --packages=.packages pkg/kernel/test/binary_bench.dart --golem AstFromBinaryLazy out/ReleaseX64/vm_platform_strong.dill
+    out/ReleaseX64/run_vm_tests InitialRSS
     cd ..
     rm -rf tmp
   else
diff --git a/tools/build.py b/tools/build.py
index abb1e1d..efeff21 100755
--- a/tools/build.py
+++ b/tools/build.py
@@ -32,7 +32,7 @@
               'simarm64,arm64,simdbc,armsimdbc]',
       default=utils.GuessArchitecture())
   result.add_option("-b", "--bytecode",
-      help='Build with the kernel bytecode interpreter',
+      help='Build with the kernel bytecode interpreter. DEPRECATED.',
       default=False,
       action='store_true')
   result.add_option("-j",
@@ -228,9 +228,9 @@
 
 
 # Returns a tuple (build_config, command to run, whether goma is used)
-def BuildOneConfig(options, targets, target_os, mode, arch, kbc):
-  build_config = utils.GetBuildConf(mode, arch, target_os, kbc=kbc)
-  out_dir = utils.GetBuildRoot(HOST_OS, mode, arch, target_os, kbc=kbc)
+def BuildOneConfig(options, targets, target_os, mode, arch):
+  build_config = utils.GetBuildConf(mode, arch, target_os)
+  out_dir = utils.GetBuildRoot(HOST_OS, mode, arch, target_os)
   using_goma = False
   # TODO(zra): Remove auto-run of gn, replace with prompt for user to run
   # gn.py manually.
@@ -295,8 +295,7 @@
   for target_os in options.os:
     for mode in options.mode:
       for arch in options.arch:
-        configs.append(BuildOneConfig(options, targets, target_os, mode, arch,
-                                      options.bytecode))
+        configs.append(BuildOneConfig(options, targets, target_os, mode, arch))
 
   # Build regular configs.
   goma_builds = []
diff --git a/tools/gn.py b/tools/gn.py
index 005ecc0..9c24ee3 100755
--- a/tools/gn.py
+++ b/tools/gn.py
@@ -64,8 +64,8 @@
   return args.split()
 
 
-def GetOutDir(mode, arch, target_os, kbc):
-  return utils.GetBuildRoot(HOST_OS, mode, arch, target_os, kbc=kbc)
+def GetOutDir(mode, arch, target_os):
+  return utils.GetBuildRoot(HOST_OS, mode, arch, target_os)
 
 
 def ToCommandLine(gn_args):
@@ -174,9 +174,6 @@
   gn_args['target_cpu'] = TargetCpuForArch(arch, target_os)
   gn_args['dart_target_arch'] = DartTargetCpuForArch(arch)
 
-  if args.bytecode:
-    gn_args['dart_use_interpreter'] = True
-
   if arch != HostCpuForArch(arch):
     # Training an app-jit snapshot under a simulator is slow. Use script
     # snapshots instead.
@@ -189,6 +186,8 @@
   if gn_args['target_os'] in ['linux', 'win']:
     gn_args['dart_use_fallback_root_certificates'] = True
 
+  gn_args['dart_platform_bytecode'] = args.bytecode
+
   gn_args['dart_zlib_path'] = "//runtime/bin/zlib"
 
   # Use tcmalloc only when targeting Linux and when not using ASAN.
@@ -345,10 +344,6 @@
       metavar='[all,ia32,x64,simarm,arm,simarmv6,armv6,simarmv5te,armv5te,'
               'simarm64,arm64,simdbc,armsimdbc]',
       default='x64')
-  common_group.add_argument('--bytecode', '-b',
-      help='Configure with the kernel bytecode interpreter',
-      default=False,
-      action="store_true")
   common_group.add_argument('--mode', '-m',
       type=str,
       help='Build variants (comma-separated).',
@@ -377,6 +372,10 @@
       help='Disable ASAN',
       dest='asan',
       action='store_false')
+  other_group.add_argument('--bytecode', '-b',
+      help='Include bytecode in the VMs platform dill',
+      default=False,
+      action="store_true")
   other_group.add_argument('--clang',
       help='Use Clang',
       default=True,
@@ -488,7 +487,7 @@
   for target_os in args.os:
     for mode in args.mode:
       for arch in args.arch:
-        out_dir = GetOutDir(mode, arch, target_os, args.bytecode)
+        out_dir = GetOutDir(mode, arch, target_os)
         # TODO(infra): Re-enable --check. Many targets fail to use
         # public_deps to re-expose header files to their dependents.
         # See dartbug.com/32364
diff --git a/tools/patches/flutter-engine/760a9690c22ec3f3d163173737f9949f97e6e02a.patch b/tools/patches/flutter-engine/760a9690c22ec3f3d163173737f9949f97e6e02a.patch
new file mode 100644
index 0000000..baa7cc7
--- /dev/null
+++ b/tools/patches/flutter-engine/760a9690c22ec3f3d163173737f9949f97e6e02a.patch
@@ -0,0 +1,16 @@
+diff --git a/frontend_server/lib/server.dart b/frontend_server/lib/server.dart
+index 804c5699e..572087e9d 100644
+--- a/frontend_server/lib/server.dart
++++ b/frontend_server/lib/server.dart
+@@ -39,6 +39,11 @@ class _FlutterFrontendCompiler implements frontend.CompilerInterface{
+     _compiler.acceptLastDelta();
+   }
+ 
++  @override
++  Future<Null> rejectLastDelta() async {
++    return _compiler.rejectLastDelta();
++  }
++
+   @override
+   void invalidate(Uri uri) {
+     _compiler.invalidate(uri);
diff --git a/tools/patches/flutter-engine/apply.sh b/tools/patches/flutter-engine/apply.sh
index 984576a..e2ac1df 100755
--- a/tools/patches/flutter-engine/apply.sh
+++ b/tools/patches/flutter-engine/apply.sh
@@ -26,8 +26,17 @@
 fi
 pinned_dart_sdk=$(grep -E "'dart_revision':.*" src/flutter/DEPS |
                   sed -E "s/.*'([^']*)',/\1/")
+need_runhooks=false
+patch=src/third_party/dart/tools/patches/flutter-engine/${pinned_dart_sdk}.flutter.patch
+if [ -e "$patch" ]; then
+  (cd flutter && git apply ../$patch)
+  need_runhooks=true
+fi
 patch=src/third_party/dart/tools/patches/flutter-engine/${pinned_dart_sdk}.patch
 if [ -e "$patch" ]; then
   (cd src/flutter && git apply ../../$patch)
+  need_runhooks=true
+fi
+if [ $need_runhooks = true ]; then
   gclient runhooks
 fi
diff --git a/tools/testing/dart/command.dart b/tools/testing/dart/command.dart
index 7bb1ae4..eaf62c6 100644
--- a/tools/testing/dart/command.dart
+++ b/tools/testing/dart/command.dart
@@ -51,6 +51,12 @@
     return new AnalysisCommand._(executable, arguments, environmentOverrides);
   }
 
+  static Command compareAnalyzerCfe(String executable, List<String> arguments,
+      Map<String, String> environmentOverrides) {
+    return new CompareAnalyzerCfeCommand._(
+        executable, arguments, environmentOverrides);
+  }
+
   static Command specParse(String executable, List<String> arguments,
       Map<String, String> environmentOverrides) {
     return new SpecParseCommand._(executable, arguments, environmentOverrides);
@@ -429,6 +435,13 @@
       : super._('dart2analyzer', executable, arguments, environmentOverrides);
 }
 
+class CompareAnalyzerCfeCommand extends ProcessCommand {
+  CompareAnalyzerCfeCommand._(String executable, List<String> arguments,
+      Map<String, String> environmentOverrides)
+      : super._('compare_analyzer_cfe', executable, arguments,
+            environmentOverrides);
+}
+
 class SpecParseCommand extends ProcessCommand {
   SpecParseCommand._(String executable, List<String> arguments,
       Map<String, String> environmentOverrides)
diff --git a/tools/testing/dart/command_output.dart b/tools/testing/dart/command_output.dart
index 4f7521c..d26a4dd 100644
--- a/tools/testing/dart/command_output.dart
+++ b/tools/testing/dart/command_output.dart
@@ -566,6 +566,49 @@
   }
 }
 
+class CompareAnalyzerCfeCommandOutput extends CommandOutput {
+  CompareAnalyzerCfeCommandOutput(
+      Command command,
+      int exitCode,
+      bool timedOut,
+      List<int> stdout,
+      List<int> stderr,
+      Duration time,
+      bool compilationSkipped)
+      : super(command, exitCode, timedOut, stdout, stderr, time,
+            compilationSkipped, 0);
+
+  Expectation result(TestCase testCase) {
+    // Handle crashes and timeouts first
+    if (hasCrashed) return Expectation.crash;
+    if (hasTimedOut) return Expectation.timeout;
+    if (hasNonUtf8) return Expectation.nonUtf8Error;
+
+    if (exitCode != 0) return Expectation.fail;
+    for (var line in decodeUtf8(this.stdout).split('\n')) {
+      if (line.indexOf('No differences found') != -1) return Expectation.pass;
+      if (line.indexOf('Differences found') != -1) return Expectation.fail;
+    }
+    return Expectation.fail;
+  }
+
+  /// Cloned code from member result(), with changes.
+  /// Delete existing result() function and rename, when status files are gone.
+  Expectation realResult(TestCase testCase) {
+    // Handle crashes and timeouts first
+    if (hasCrashed) return Expectation.crash;
+    if (hasTimedOut) return Expectation.timeout;
+    if (hasNonUtf8) return Expectation.nonUtf8Error;
+
+    if (exitCode != 0) return Expectation.fail;
+    for (var line in decodeUtf8(this.stdout).split('\n')) {
+      if (line.indexOf('No differences found') != -1) return Expectation.pass;
+      if (line.indexOf('Differences found') != -1) return Expectation.fail;
+    }
+    return Expectation.fail;
+  }
+}
+
 class SpecParseCommandOutput extends CommandOutput {
   SpecParseCommandOutput(
       Command command,
@@ -984,6 +1027,9 @@
   if (command is AnalysisCommand) {
     return new AnalysisCommandOutput(
         command, exitCode, timedOut, stdout, stderr, time, compilationSkipped);
+  } else if (command is CompareAnalyzerCfeCommand) {
+    return new CompareAnalyzerCfeCommandOutput(
+        command, exitCode, timedOut, stdout, stderr, time, compilationSkipped);
   } else if (command is SpecParseCommand) {
     return new SpecParseCommandOutput(
         command, exitCode, timedOut, stdout, stderr, time, compilationSkipped);
diff --git a/tools/testing/dart/compiler_configuration.dart b/tools/testing/dart/compiler_configuration.dart
index f1762e6..8f039d7 100644
--- a/tools/testing/dart/compiler_configuration.dart
+++ b/tools/testing/dart/compiler_configuration.dart
@@ -51,6 +51,9 @@
       case Compiler.dart2analyzer:
         return new AnalyzerCompilerConfiguration(configuration);
 
+      case Compiler.compareAnalyzerCfe:
+        return new CompareAnalyzerCfeCompilerConfiguration(configuration);
+
       case Compiler.dart2js:
         return new Dart2jsCompilerConfiguration(configuration);
 
@@ -244,7 +247,6 @@
     } else if (_configuration.hotReloadRollback) {
       args.add('--hot-reload-rollback-test-mode');
     }
-
     return args
       ..addAll(vmOptions)
       ..addAll(sharedOptions)
@@ -492,7 +494,11 @@
 
   Command createCommand(String inputFile, String outputFile,
       List<String> sharedOptions, Map<String, String> environment) {
-    var sdkSummaryFile = useKernel ? 'kernel/ddc_sdk.dill' : 'ddc_sdk.sum';
+    // TODO(jmesserly): restore testing on this once we have everyone migrated
+    // to DDC's Kernel backend. At that point we'd like to migrate from Analyzer
+    // summaries to Kernel IL.
+    final useDillFormat = false;
+    var sdkSummaryFile = useDillFormat ? 'kernel/ddc_sdk.dill' : 'ddc_sdk.sum';
     var sdkSummary = new Path(_configuration.buildDirectory)
         .append("/gen/utils/dartdevc/$sdkSummaryFile")
         .absolute
@@ -529,8 +535,8 @@
 
     // Link to the summaries for the available packages, so that they don't
     // get recompiled into the test's own module.
-    var pkgDir = useKernel ? 'pkg_kernel' : 'pkg';
-    var pkgExtension = useKernel ? 'dill' : 'sum';
+    var pkgDir = useDillFormat ? 'pkg_kernel' : 'pkg';
+    var pkgExtension = useDillFormat ? 'dill' : 'sum';
     for (var package in testPackages) {
       args.add("-s");
 
@@ -960,6 +966,46 @@
   }
 }
 
+/// Configuration for compareAnalyzerCfe.
+class CompareAnalyzerCfeCompilerConfiguration extends CompilerConfiguration {
+  CompareAnalyzerCfeCompilerConfiguration(TestConfiguration configuration)
+      : super._subclass(configuration);
+
+  int get timeoutMultiplier => 4;
+
+  String computeCompilerPath() {
+    String suffix = executableScriptSuffix;
+    if (_useSdk) {
+      throw "--use-sdk cannot be used with compiler compare_analyzer_cfe";
+    }
+    return 'pkg/analyzer_fe_comparison/bin/compare_sdk_tests$suffix';
+  }
+
+  CommandArtifact computeCompilationArtifact(String tempDir,
+      List<String> arguments, Map<String, String> environmentOverrides) {
+    arguments = arguments.toList();
+    if (!previewDart2) {
+      throw new ArgumentError('--no-preview-dart-2 not supported');
+    }
+
+    // Since this is not a real compilation, no artifacts are produced.
+    return new CommandArtifact([
+      Command.compareAnalyzerCfe(
+          computeCompilerPath(), arguments, environmentOverrides)
+    ], null, null);
+  }
+
+  List<String> computeRuntimeArguments(
+      RuntimeConfiguration runtimeConfiguration,
+      TestInformation info,
+      List<String> vmOptions,
+      List<String> sharedOptions,
+      List<String> originalArguments,
+      CommandArtifact artifact) {
+    return <String>[];
+  }
+}
+
 /// Configuration for spec_parser.
 class SpecParserCompilerConfiguration extends CompilerConfiguration {
   SpecParserCompilerConfiguration(TestConfiguration configuration)
diff --git a/tools/testing/dart/configuration.dart b/tools/testing/dart/configuration.dart
index bc2996a..bd53829 100644
--- a/tools/testing/dart/configuration.dart
+++ b/tools/testing/dart/configuration.dart
@@ -41,6 +41,7 @@
       this.writeDebugLog,
       this.writeTestOutcomeLog,
       this.writeResultLog,
+      this.writeResults,
       this.drtPath,
       this.chromePath,
       this.safariPath,
@@ -91,6 +92,7 @@
   final bool writeDebugLog;
   final bool writeTestOutcomeLog;
   final bool writeResultLog;
+  final bool writeResults;
   final bool printPassingStdout;
 
   Architecture get architecture => configuration.architecture;
@@ -417,10 +419,9 @@
     var os = '';
     if (system == System.android) os = "Android";
 
-    var kbc = useKernelBytecode ? 'KBC' : '';
     var arch = architecture.name.toUpperCase();
-    var normal = '$modeName$os$arch$kbc';
-    var cross = '$modeName${os}X$arch$kbc';
+    var normal = '$modeName$os$arch';
+    var cross = '$modeName${os}X$arch';
     var outDir = system.outputDirectory;
     var normalDir = new Directory(new Path('$outDir$normal').toNativePath());
     var crossDir = new Directory(new Path('$outDir$cross').toNativePath());
diff --git a/tools/testing/dart/options.dart b/tools/testing/dart/options.dart
index ca6272d..9f5aadf 100644
--- a/tools/testing/dart/options.dart
+++ b/tools/testing/dart/options.dart
@@ -96,6 +96,7 @@
 precompiler:   Compile into AOT snapshot before running the test.
 dart2js:       Compile to JavaScript using dart2js.
 dart2analyzer: Perform static analysis on Dart code using the analyzer.
+compareAnalyzerCfe: Compare analyzer and common front end representations.
 app_jit:       Compile the Dart code into an app snapshot.
 app_jitk:      Compile the Dart code into Kernel and then into an app snapshot.
 dartk:         Compile the Dart code into Kernel before running test.
@@ -262,6 +263,11 @@
         'located at the debug_output_directory.',
         hide: true),
     new _Option.bool(
+        'write_results',
+        'Write results to a "${TestUtils.resultsFileName}" json file '
+        'located at the debug_output_directory.',
+        hide: true),
+    new _Option.bool(
         'reset_browser_configuration',
         '''Browser specific reset of configuration.
 
@@ -669,6 +675,7 @@
                 writeDebugLog: data["write_debug_log"] as bool,
                 writeTestOutcomeLog: data["write_test_outcome_log"] as bool,
                 writeResultLog: data["write_result_log"] as bool,
+                writeResults: data["write_results"] as bool,
                 drtPath: data["drt"] as String,
                 chromePath: data["chrome"] as String,
                 safariPath: data["safari"] as String,
diff --git a/tools/testing/dart/runtime_configuration.dart b/tools/testing/dart/runtime_configuration.dart
index c8c922785..b2227f7 100644
--- a/tools/testing/dart/runtime_configuration.dart
+++ b/tools/testing/dart/runtime_configuration.dart
@@ -217,20 +217,11 @@
       throw "Dart VM cannot run files of type '$type'.";
     }
 
-    List<String> args = arguments;
-    if (suite.configuration.compiler == Compiler.dartkb) {
-      args.removeWhere(
-          (String arg) => arg.startsWith('--optimization-counter-threshold'));
-      args.removeWhere(
-          (String arg) => arg.startsWith('--optimization_counter_threshold'));
-      args = <String>['--optimization-counter-threshold=-1']..addAll(args);
-    }
-
     String executable = suite.dartVmBinaryFileName;
     if (type == 'application/kernel-ir-fully-linked') {
       executable = suite.dartVmExecutableFileName;
     }
-    return [Command.vm(executable, args, environmentOverrides)];
+    return [Command.vm(executable, arguments, environmentOverrides)];
   }
 }
 
diff --git a/tools/testing/dart/status_reporter.dart b/tools/testing/dart/status_reporter.dart
index b3d0e27..c5a69ec 100644
--- a/tools/testing/dart/status_reporter.dart
+++ b/tools/testing/dart/status_reporter.dart
@@ -14,6 +14,12 @@
       'compiler': 'dart2analyzer'
     },
     {
+      'runtimes': ['none'],
+      'modes': ['release'],
+      'archs': ['x64'],
+      'compiler': 'compare_analyzer_cfe'
+    },
+    {
       'runtimes': ['vm'],
       'modes': ['debug', 'release'],
       'archs': ['ia32', 'x64', 'simarm'],
diff --git a/tools/testing/dart/test_configurations.dart b/tools/testing/dart/test_configurations.dart
index e21cf48..05c85c8 100644
--- a/tools/testing/dart/test_configurations.dart
+++ b/tools/testing/dart/test_configurations.dart
@@ -53,7 +53,9 @@
 final VS_TOOLCHAIN_FILE = new Path("build/win_toolchain.json");
 
 Future testConfigurations(List<TestConfiguration> configurations) async {
-  var startTime = new DateTime.now();
+  var startTime = DateTime.now();
+  var startStopwatch = Stopwatch()..start();
+
   // Extract global options from first configuration.
   var firstConf = configurations[0];
   var maxProcesses = firstConf.taskCount;
@@ -221,6 +223,9 @@
       eventListener.add(new TimingPrinter(startTime));
     }
     eventListener.add(new SkippedCompilationsPrinter());
+    if (progressIndicator == Progress.status) {
+      eventListener.add(new TimedProgressPrinter());
+    }
   }
 
   if (firstConf.writeTestOutcomeLog) {
@@ -231,6 +236,10 @@
     eventListener.add(new ResultLogWriter(firstConf.outputDirectory));
   }
 
+  if (firstConf.writeResults) {
+    eventListener.add(new ResultWriter(firstConf, startTime, startStopwatch));
+  }
+
   if (firstConf.copyCoreDumps) {
     eventListener.add(new UnexpectedCrashLogger());
   }
diff --git a/tools/testing/dart/test_progress.dart b/tools/testing/dart/test_progress.dart
index a5e099d..bdb8a0b 100644
--- a/tools/testing/dart/test_progress.dart
+++ b/tools/testing/dart/test_progress.dart
@@ -2,6 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+import 'dart:async';
 import 'dart:convert';
 import 'dart:io';
 
@@ -67,6 +68,33 @@
   }
 }
 
+class TimedProgressPrinter extends EventListener {
+  static const interval = Duration(minutes: 5);
+  int _numTests = 0;
+  int _numCompleted = 0;
+  bool _allKnown = false;
+  Timer _timer;
+
+  TimedProgressPrinter() {
+    _timer = Timer.periodic(interval, callback);
+  }
+
+  void callback(Timer timer) {
+    if (_allKnown) {
+      print('$_numCompleted out of $_numTests completed');
+    }
+    print("Tests running for ${(interval * timer.tick).inMinutes} minutes");
+  }
+
+  void testAdded() => _numTests++;
+
+  void done(TestCase test) => _numCompleted++;
+
+  void allTestsKnown() => _allKnown = true;
+
+  void allDone() => _timer.cancel();
+}
+
 class IgnoredTestMonitor extends EventListener {
   static final int maxIgnored = 10;
 
@@ -797,3 +825,75 @@
     }
   }
 }
+
+/// Writes a results.json file with a line for each test.
+/// Each line is a json map with the test name and result and expected result.
+/// Also writes a run.json file with a json map containing the configuration
+/// and the start time and duration of the run.
+class ResultWriter extends EventListener {
+  final TestConfiguration _configuration;
+  final List<Map> _results = [];
+  final String _outputDirectory;
+  final Stopwatch _startStopwatch;
+  final DateTime _startTime;
+
+  ResultWriter(this._configuration, this._startTime, this._startStopwatch)
+      : _outputDirectory = _configuration.outputDirectory;
+
+  void allTestsKnown() {
+    // Write an empty result log file, that will be overwritten if any tests
+    // are actually run, when the allDone event handler is invoked.
+    writeResultsFile([]);
+  }
+
+  void done(TestCase test) {
+    if (_configuration != test.configuration) {
+      throw new Exception("Two configurations in the same run. "
+          "Cannot output results for multiple configurations.");
+    }
+    final name = test.displayName;
+    final index = name.indexOf('/');
+    final suite = name.substring(0, index);
+    final testName = name.substring(index + 1);
+    Duration time =
+        test.commandOutputs.values.fold(Duration.zero, (d, o) => d + o.time);
+
+    var record = {
+      "name": name,
+      "suite": suite,
+      "test_name": testName,
+      "time_ms": time.inMilliseconds,
+      "result": test.realResult.toString(),
+      "expected": test.realExpected.toString(),
+      "matches": test.realResult.canBeOutcomeOf(test.realExpected)
+    };
+    _results.add(record);
+  }
+
+  void allDone() {
+    writeResultsFile(_results);
+    writeRunFile();
+  }
+
+  void writeResultsFile(List<Map> results) {
+    if (_outputDirectory == null) return;
+    final path =
+        Uri.directory(_outputDirectory).resolve(TestUtils.resultsFileName);
+    File.fromUri(path).writeAsStringSync(results.map(jsonEncode).join('\n'));
+  }
+
+  void writeRunFile() {
+    _startStopwatch.stop();
+    if (_outputDirectory == null) return;
+    var suites = _configuration.selectors.keys.toList();
+    var run = {
+      "start_time": _startTime.millisecondsSinceEpoch ~/ 1000,
+      "duration": _startStopwatch.elapsed.inSeconds,
+      "configuration": _configuration.configuration.name,
+      "suites": suites
+    };
+    final path = Uri.directory(_outputDirectory)
+        .resolve(TestUtils.resultsInstanceFileName);
+    File.fromUri(path).writeAsStringSync(jsonEncode(run));
+  }
+}
diff --git a/tools/testing/dart/utils.dart b/tools/testing/dart/utils.dart
index 2ff7b26..35a2b1a 100644
--- a/tools/testing/dart/utils.dart
+++ b/tools/testing/dart/utils.dart
@@ -477,6 +477,14 @@
   /// test outcomes to this file in the '--output-directory'.
   static const resultLogFileName = "result.log";
 
+  /// If test.py was invoked with '--write-results it will write
+  /// test outcomes to this file in the '--output-directory'.
+  static const resultsFileName = "results.json";
+
+  /// If test.py was invoked with '--write-results it will write
+  /// data about this run of test.py to this file in the '--output-directory'.
+  static const resultsInstanceFileName = "run.json";
+
   static void ensureExists(String filename, TestConfiguration configuration) {
     if (!configuration.listTests && !existsCache.doesFileExist(filename)) {
       throw "'$filename' does not exist";
diff --git a/tools/utils.py b/tools/utils.py
index a6b7578..38c1244 100644
--- a/tools/utils.py
+++ b/tools/utils.py
@@ -293,32 +293,27 @@
           (target_os != GuessOS()))
 
 
-def GetBuildConf(mode, arch, conf_os=None, kbc=False):
-  kbc_suffix = ''
-  if kbc:
-    kbc_suffix = 'KBC'
+def GetBuildConf(mode, arch, conf_os=None):
   if conf_os == 'android':
-    return '%s%s%s%s' % (GetBuildMode(mode), conf_os.title(), arch.upper(),
-                       kbc_suffix)
+    return '%s%s%s' % (GetBuildMode(mode), conf_os.title(), arch.upper())
   else:
     # Ask for a cross build if the host and target architectures don't match.
     host_arch = ARCH_GUESS
     cross_build = ''
     if GetArchFamily(host_arch) != GetArchFamily(arch):
       cross_build = 'X'
-    return '%s%s%s%s' % (GetBuildMode(mode), cross_build, arch.upper(),
-                       kbc_suffix)
+    return '%s%s%s' % (GetBuildMode(mode), cross_build, arch.upper())
 
 
 def GetBuildDir(host_os):
   return BUILD_ROOT[host_os]
 
 
-def GetBuildRoot(host_os, mode=None, arch=None, target_os=None, kbc=False):
+def GetBuildRoot(host_os, mode=None, arch=None, target_os=None):
   build_root = GetBuildDir(host_os)
   if mode:
     build_root = os.path.join(build_root,
-                              GetBuildConf(mode, arch, target_os, kbc))
+                              GetBuildConf(mode, arch, target_os))
   return build_root
 
 
diff --git a/utils/compiler/BUILD.gn b/utils/compiler/BUILD.gn
index f6024c4..3dbee83 100644
--- a/utils/compiler/BUILD.gn
+++ b/utils/compiler/BUILD.gn
@@ -60,14 +60,11 @@
 application_snapshot("dart2js") {
   deps = [
     ":compile_dart2js_platform",
-    ":compile_dart2js_platform_strong",
     ":dart2js_create_snapshot_entry",
   ]
   inputs = [
     "$root_out_dir/dart2js_platform.dill",
     "$root_out_dir/dart2js_outline.dill",
-    "$root_out_dir/dart2js_platform_strong.dill",
-    "$root_out_dir/dart2js_outline_strong.dill",
   ]
   vm_args = []
   main_dart = "$target_gen_dir/dart2js.dart"
@@ -91,27 +88,10 @@
 
   args = [
     "--target=dart2js",
-    "dart:core",
-  ]
-}
-
-compile_platform("compile_dart2js_platform_strong") {
-  single_root_scheme = "org-dartlang-sdk"
-  single_root_base = rebase_path("../../")
-  libraries_specification_uri = "org-dartlang-sdk:///sdk/lib/libraries.json"
-
-  outputs = [
-    "$root_out_dir/dart2js_platform_strong.dill",
-    "$root_out_dir/dart2js_outline_strong.dill",
-  ]
-
-  args = [
-    "--target=dart2js",
     "--strong",
     "dart:core",
   ]
 }
-
 compile_platform("compile_dart2js_server_platform") {
   single_root_scheme = "org-dartlang-sdk"
   single_root_base = rebase_path("../../")
@@ -124,22 +104,6 @@
 
   args = [
     "--target=dart2js_server",
-    "dart:core",
-  ]
-}
-
-compile_platform("compile_dart2js_server_platform_strong") {
-  single_root_scheme = "org-dartlang-sdk"
-  single_root_base = rebase_path("../../")
-  libraries_specification_uri = "org-dartlang-sdk:///sdk/lib/libraries.json"
-
-  outputs = [
-    "$root_out_dir/dart2js_server_platform_strong.dill",
-    "$root_out_dir/dart2js_server_outline_strong.dill",
-  ]
-
-  args = [
-    "--target=dart2js_server",
     "--strong",
     "dart:core",
   ]
diff --git a/utils/dartdevc/BUILD.gn b/utils/dartdevc/BUILD.gn
index 6fecc50..03be2cc 100644
--- a/utils/dartdevc/BUILD.gn
+++ b/utils/dartdevc/BUILD.gn
@@ -83,7 +83,6 @@
   dart_action(target_name) {
     deps = [
       "../compiler:compile_dart2js_platform",
-      "../compiler:compile_dart2js_platform_strong",
     ]
 
     # dart_action() needs kernel service snapshot to run in Dart 2 mode.
@@ -94,8 +93,6 @@
     inputs = sdk_lib_files + compiler_files + dev_compiler_files + [
                "$root_out_dir/dart2js_platform.dill",
                "$root_out_dir/dart2js_outline.dill",
-               "$root_out_dir/dart2js_platform_strong.dill",
-               "$root_out_dir/dart2js_outline_strong.dill",
              ]
     outputs = [
       out,
diff --git a/utils/kernel-service/BUILD.gn b/utils/kernel-service/BUILD.gn
index 489e38d..bcab702 100644
--- a/utils/kernel-service/BUILD.gn
+++ b/utils/kernel-service/BUILD.gn
@@ -29,7 +29,7 @@
   ]
   training_args = [
     "--train",
-    "file://" + rebase_path("../../pkg/compiler/lib/src/dart2js.dart"),
+    "file:///" + rebase_path("../../pkg/compiler/lib/src/dart2js.dart"),
   ]
   output = "$root_gen_dir/kernel-service.dart.snapshot"
 }