Version 1.22.0-dev.6.0

Merge badfd146d224e9a083cb038532273fa5f359e2ce into dev
diff --git a/.travis.yml b/.travis.yml
index f08c83f..0ec2814 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -43,13 +43,16 @@
   - git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git
   - export PATH=`pwd`/depot_tools:"$PATH"
 
-  # Checkout everything if we're building the SDK
+  # Checkout everything to pull in sdk and third_party dart packages
   - cd ..
   - 'gclient config --spec=''solutions = [ { "name": "sdk", "url": "git@github.com:dart-lang/sdk.git", "deps_file": "DEPS", "managed": False } ]'''
-  - gclient sync
+  - gclient sync -n
+  - download_from_google_storage --no_auth --no_resume --bucket dart-dependencies --extract -s sdk/third_party/pkg/unittest.tar.gz.sha1
   - cd sdk
 
-  # If a C++ compiler is set, build the SDK - else use the preinstalled SDK instead.
+  # If a C++ compiler is set, run hooks and build the SDK - else use the preinstalled SDK instead.
+  - export DART_USE_GYP=1
+  - if [ "$CXX" ]; then gclient runhooks ; fi
   - if [ "$CXX" ]; then ./tools/build.py -m release create_sdk ; fi
   - if [ "$CXX" ]; then export PATH=`pwd`/out/ReleaseX64/dart-sdk/bin:"$PATH" ; fi
   - dart --version
diff --git a/DEPS b/DEPS
index a9f0ba1..70e1d42 100644
--- a/DEPS
+++ b/DEPS
@@ -75,7 +75,7 @@
   "isolate_tag": "@0.2.3",
   "jinja2_rev": "@2222b31554f03e62600cd7e383376a7c187967a1",
   "json_rpc_2_tag": "@2.0.2",
-  "linter_rev": "@3ec970f7acc8599ad8fb08b848485205d48052cf",
+  "linter_rev": "@bde08fddf7a24e73d788e62b1725e4db95533269",
   "logging_tag": "@0.11.3+1",
   "markdown_tag": "@0.11.0",
   "matcher_tag": "@0.12.0+2",
diff --git a/docs/language/dart.sty b/docs/language/dart.sty
index d22dde6..281692e 100644
--- a/docs/language/dart.sty
+++ b/docs/language/dart.sty
@@ -3,64 +3,59 @@
 \def\comment#1{\textit{#1}}
 \def\capt#1{\rmfamily \caption{#1}}
 \newcommand{\cd}[1]{\textsf{#1}}
-\def\lt{$<$}
-\def\gt{$>$}
-\def\<{$\langle$}
-\def\>{$\rangle$}
+\def\lt{\ensuremath{<}}
+\def\gt{\ensuremath{>}}
+\def\<{\ensuremath{\langle}}
+\def\>{\ensuremath{\rangle}}
 \def\metavar#1{\ensuremath{\mathit{#1}}}
+
 \def\ABSTRACT{\builtinId{abstract}}
 \def\AS{\builtinId{as}}
+\def\DEFERRED{\builtinId{deferred}}
+\def\DYNAMIC{\builtinId{dynamic}}
+\def\EXPORT{\builtinId{export}}
+\def\EXTERNAL{\builtinId{external}}
+\def\FACTORY{\builtinId{factory}}
+\def\GET{\builtinId{get}}
+\def\IMPLEMENTS{\builtinId{implements}}
+\def\IMPORT{\builtinId{import}}
+\def\LIBRARY{\builtinId{library}}
+\def\OPERATOR{\builtinId{operator}}
+\def\PART{\builtinId{part}}
+\def\SET{\builtinId{set}}
+\def\STATIC{\builtinId{static}}
+\def\TYPEDEF{\builtinId{typedef}}
+
 \def\ASSERT{\keyword{assert}}
 \def\ASYNC{\keyword{async}}
 \def\AWAIT{\keyword{await}}
-\def\BOOLEAN{\keyword{boolean}}
 \def\BREAK{\keyword{break}}
-\def\CASE{\keyword{case}}
-\def\CLASS{\keyword{class}}
 \def\CALL{\keyword{call}}
+\def\CASE{\keyword{case}}
 \def\CATCH{\keyword{catch}}
+\def\CLASS{\keyword{class}}
 \def\CONST{\keyword{const}}
 \def\CONTINUE{\keyword{continue}}
 \def\DEFAULT{\keyword{default}}
-\def\DEFERRED{\keyword{deferred}}
-\def\DYNAMIC{\builtinId{dynamic}}
 \def\DO{\keyword{do}}
 \def\ELSE{\keyword{else}}
 \def\ENUM{\keyword{enum}}
-\def\EQUALS{\keyword{equals}}
-\def\EXPORT{\builtinId{export}}
 \def\EXTENDS{\keyword{extends}}
-\def\EXTERNAL{\builtinId{external}}
-\def\FACTORY{\builtinId{factory}}
 \def\FALSE{\keyword{false}}
 \def\FINAL{\keyword{final}}
 \def\FINALLY{\keyword{finally}}
 \def\FOR{\keyword{for}}
-\def\GET{\builtinId{get}}
 \def\HIDE{\keyword{hide}}
 \def\IF{\keyword{if}}
-\def\IMPLEMENTS{\builtinId{implements}}
-\def\IMPORT{\builtinId{import}}
 \def\IN{\keyword{in}}
-\def\INT{\keyword{int}}
-\def\INTERFACE{\keyword{interface}}
 \def\IS{\keyword{is}}
-\def\LIBRARY{\builtinId{library}}
-\def\NATIVE{\keyword{native}}
-\def\NEGATE{\keyword{negate}}
 \def\NEW{\keyword{new}}
 \def\NULL{\keyword{null}}
-\def\ON{\keyword{on}}
 \def\OF{\keyword{of}}
-\def\OPERATOR{\builtinId{operator}}
-\def\PART{\builtinId{part}}
-\def\PRIVATE{\keyword{private}}
+\def\ON{\keyword{on}}
 \def\RETHROW{\keyword{rethrow}}
 \def\RETURN{\keyword{return}}
-\def\SET{\builtinId{set}}
 \def\SHOW{\keyword{show}}
-\def\SOURCE{\keyword{source}}
-\def\STATIC{\builtinId{static}}
 \def\SUPER{\keyword{super}}
 \def\SWITCH{\keyword{switch}}
 \def\SYNC{\keyword{sync}}
@@ -68,19 +63,14 @@
 \def\THROW{\keyword{throw}}
 \def\TRUE{\keyword{true}}
 \def\TRY{\keyword{try}}
-\def\TYPEDEF{\builtinId{typedef}}
-\def\THIS{\keyword{this}}
 \def\VAR{\keyword{var}}
 \def\VOID{\keyword{void}}
 \def\WHILE{\keyword{while}}
 \def\WITH{\keyword{with}}
 \def\YIELD{\keyword{yield}}
-\def\TRUE{\keyword{true}}
 
 \newenvironment{Q}[1]{{\bf #1}}
-
 \newenvironment{rationale}[1]{{\it #1}}
-
 \newenvironment{commentary}[1]{{\sf #1}}
 
 \newenvironment{dartCode}[1][!ht] {
diff --git a/docs/language/dartLangSpec.tex b/docs/language/dartLangSpec.tex
index f2fee9d..1d41cf5 100644
--- a/docs/language/dartLangSpec.tex
+++ b/docs/language/dartLangSpec.tex
@@ -195,8 +195,10 @@
 \LMHash{}
 A scope $S_0$ induces a namespace $NS_0$ that maps the simple name of each variable, type or function declaration $d$ declared in $S_0$ to $d$. Labels are not included in the induced namespace of a scope; instead they have their own dedicated namespace.
 
-\commentary{It is therefore impossible, e.g.,  to define a class that declares a method and a field with the same name in Dart. Similarly one cannot declare a top-level function with the same name as a library variable or class.
-  }
+\commentary{
+It is therefore impossible, e.g., to define a class that declares a method and a getter with the same name in Dart.
+Similarly one cannot declare a top-level function with the same name as a library variable or a class.
+}
 
 \LMHash{}
 It is a compile-time error if there is more than one entity with the same name declared in the same scope.
@@ -1058,7 +1060,7 @@
 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.
 
 \commentary{
-This implies that a getter can never override a method, and a method can never override a getter or field.
+This implies that a getter can never override a method, and a method can never override a getter or an instance variable.
 }
 
 \LMHash{}
@@ -1245,7 +1247,9 @@
 A {\em constructor parameter list} is a parenthesized, comma-separated list of formal constructor parameters. A {\em formal constructor parameter} is either a formal parameter (\ref{formalParameters}) or an initializing formal. An {\em initializing formal} has the form \code{\THIS{}.$id$}, where $id$ is the name of an instance variable of the immediately enclosing class.  It is a compile-time error if $id$ is not an instance variable of the immediately enclosing class. It is a compile-time error if an initializing formal is used by a function other than a non-redirecting generative constructor.
 
 \LMHash{}
-If an explicit type is attached to the initializing formal, that is its static type. Otherwise, the type of an initializing formal named $id$ is $T_{id}$, where $T_{id}$ is the type of the field named $id$ in the immediately enclosing class. It is a static warning if the static type of $id$ is not assignable to $T_{id}$.
+If an explicit type is attached to the initializing formal, that is its static type.
+Otherwise, the type of an initializing formal named $id$ is $T_{id}$, where $T_{id}$ is the type of the instance variable named $id$ in the immediately enclosing class.
+It is a static warning if the static type of $id$ is not assignable to $T_{id}$.
 
 \LMHash{}
 Initializing formals constitute an exception to the rule that every formal parameter introduces a local variable into the formal parameter scope (\ref{formalParameters}).
@@ -1259,8 +1263,9 @@
 }
 
 \LMHash{}
-Initializing formals are executed during the execution of generative constructors detailed below. Executing an initializing formal  \code{\THIS{}.$id$} causes the field $id$ of the immediately surrounding class to be assigned the value of the corresponding actual parameter, unless $id$ is a final variable that has already been initialized, in which case a runtime error occurs.
-
+Initializing formals are executed during the execution of generative constructors detailed below.
+Executing an initializing formal \code{\THIS{}.$id$} causes the instance variable $id$ of the immediately surrounding class to be assigned the value of the corresponding actual parameter,
+unless $id$ is a final variable that has already been initialized, in which case a runtime error occurs.
 
 \commentary{
 The above rule allows initializing formals to be used as optional parameters:
@@ -1410,7 +1415,9 @@
 After the superinitializer has completed, the body of $k$ is executed in a scope where \THIS{} is bound to $i$.
 
 \rationale{
-This process ensures that no uninitialized final field is ever seen by code. Note that \THIS{} is not in scope on the right hand side of an initializer (see \ref{this}) so no instance method can execute during initialization: an instance method cannot be directly invoked, nor can \THIS{} be passed into any other code being invoked in the initializer.
+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.
 }
 
 \LMHash{}
@@ -1419,7 +1426,10 @@
 proceeds as follows:
 
 \LMHash{}
-First, the expression $e$ is evaluated to an object $o$. Then, the instance variable $v$ of $i$ is bound to $o$, unless $v$ is a final variable that has already been initialized, in which case a runtime error occurs. In checked mode, it is a dynamic type error if $o$ is not \NULL{} and the interface of the class of $o$ is not a subtype of the actual type of the field $v$.
+First, the expression $e$ is evaluated to an object $o$.
+%%STRONG_MODE: The runtime error in the next sentence will be compile-time.
+Then, the instance variable $v$ of $i$ is bound to $o$, unless $v$ is a final variable that has already been initialized, in which case a runtime error occurs.
+In checked mode, it is a dynamic type error if $o$ is not \NULL{} and the interface of the class of $o$ is not a subtype of the actual type of the instance variable $v$.
 
 \LMHash{}
 An initializer of the form \code{$v$ = $e$} is equivalent to an initializer of the form \code{\THIS{}.$v$ = $e$}.
@@ -1828,11 +1838,13 @@
 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^\prime$ be a member of $S_j, j  \in 1 .. k$,  that has the same name as $m$, such that $m^\prime$ is accessible to $L$.  Then $m$ overrides $m^\prime$ if $m^\prime$ is not already overridden by a member of at least one of $S_1 \ldots S_{j-1}$ and neither $m$ nor $m^\prime$ 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$.
+Let $C$ declare a member $m$, and let  $m^\prime$ be a member of $S_j, j  \in 1 .. k$,  that has the same name as $m$, such that $m^\prime$ is accessible to $L$.
+Then $m$ overrides $m^\prime$ if $m^\prime$ is not already overridden by a member of at least one of $S_1 \ldots S_{j-1}$ and neither $m$ nor $m^\prime$ 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^\prime$ with the same name as $m$. Then $m$ {\em overrides} $m^\prime$ iff $m^\prime$ is accessible (\ref{privacy}) to $L$, $m$ has the same name as  $m^\prime$  and neither $m$ nor $m^\prime$ are fields.
 
-\commentary{Fields never override each other. The getters and setters induced by fields do.}
+\commentary{Instance variables never override each other. The getters and setters induced by instance variables do.}
 
 \rationale{Again, a local definition of overriding would be preferable, but fails to account for library privacy.
 }
@@ -1859,7 +1871,9 @@
 
 \begin{enumerate}
 
-\item There is only one namespace for getters, setters, methods and constructors (\ref{scoping}). A field $f$ introduces a getter $f$ and a non-final field $f$ also introduces a setter $f=$ (\ref{instanceVariables}, \ref{staticVariables}). When we speak of members here, we mean accessible fields, getters, setters and methods (\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 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 Static members are never inherited.
 \item It is a warning if you have an  static member named $m$ in your class or any superclass (even though it is not inherited) and an  instance member of the same name (\ref{instanceMethods}, \ref{getters}, \ref{setters}).
@@ -2112,7 +2126,8 @@
 A  mixin application of the form  \code{$S$ \WITH{} $M_1, \ldots, M_k$;} defines a class  $C$ whose superclass is the application of the mixin composition (\ref{mixinComposition}) $M_{k-1} * \ldots * M_1$ to $S$.
 
 \LMHash{}
-In both cases above, $C$ declares the same instance members as $M$ (respectively, $M_k$). If any of the instance fields of $M$ (respectively, $M_k$) have initializers, they are executed in the scope of $M$ (respectively, $M_k$) to initialize the corresponding fields of $C$.
+In both cases above, $C$ declares the same instance members as $M$ (respectively, $M_k$).
+If any of the instance variables of $M$ (respectively, $M_k$) have initializers, they are executed in the scope of $M$ (respectively, $M_k$) to initialize the corresponding instance variables of $C$.
 
 \LMHash{}
 Let $L_M$ be the library in which $M$ is declared.
@@ -2252,7 +2267,7 @@
 }
 
 \begin{dartCode}
-\INTERFACE{} Ordered<T> \{
+\CLASS{} Ordered<T> \{
   operator > (T x);
 \}
 
@@ -2380,7 +2395,7 @@
 }
 
 \LMHash{}
-Metadata can appear before a library, part header, class, typedef, type parameter, constructor, factory, function, field, parameter, or variable declaration and before an import, export or part directive.
+Metadata can appear before a library, part header, class, typedef, type parameter, constructor, factory, function, parameter, or variable declaration and before an import, export or part directive.
 
 \LMHash{}
 The constant expression given in an annotation  is type checked and evaluated in the scope surrounding the declaration being annotated.
@@ -2462,8 +2477,8 @@
  OR
  \item $c_1$ and $c_2$ are constant lists that are defined to be identical in the specification of literal list expressions (\ref{lists}), OR
  \item $c_1$ and $c_2$ are constant maps that are defined to be identical in the specification of literal map expressions (\ref{maps}), OR
- \item $c_1$ and $c_2$ are constant objects of the same class $C$ and each member field of $c_1$ is identical to the corresponding field of $c_2$. OR
-\item $c_1$ and $c_2$ are the same object.
+ \item $c_1$ and $c_2$ are constant objects of the same class $C$ and the value of each instance variable of $c_1$ is identical to the value of the corresponding instance variable of $c_2$. OR
+ \item $c_1$ and $c_2$ are the same object.
 \end{itemize}
 
 \commentary{
@@ -3535,13 +3550,19 @@
 \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:
 \begin{itemize}
-\item For each instance variable $f$ of $i$, let $v_{if}$ be the value of the field $f$ in $i$, and let $v_{jf}$ be the value of the field $f$ in $j$. If  \code{identical($v_{if}$, $v_{jf}$)} for all fields $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 fields and identical type arguments. 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.
+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.
+The constructor need only be executed once per call site, at compile-time.
 }
 
 \LMHash{}
@@ -5068,8 +5089,9 @@
 \LMHash{}
 The static type of such an expression is the static type of $v$.
 
-
-\rationale{The above ensures that if $v$ is a field, the getter gets called exactly once. Likewise in the cases below.
+\rationale{
+The above ensures that if $v$ is a variable, the getter gets called exactly once.
+Likewise in the cases below.
 }
 
 \LMHash{}
@@ -5434,13 +5456,18 @@
 Let $v$  be a local variable or a formal parameter. An is-expression of the form \code{$v$ \IS{} $T$} shows that $v$  has type $T$ iff $T$ is more specific than the type $S$ of the expression $v$ and  both $T \ne \DYNAMIC{}$ and $S \ne \DYNAMIC{}$.
 
 \rationale{
-The motivation for the ``shows that v has type T" relation is to reduce spurious warnings thereby enabling a more natural coding style. 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 warning, but not reject any code now warning-free.
+The motivation for the ``shows that v has type T" relation is to reduce spurious warnings thereby enabling a more natural coding style.
+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 warning, but not reject any code now warning-free.
 
-The rule only applies to locals and parameters, as fields 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 or 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. Hence the requirement that $T << S$ (we use $<<$ rather than subtyping because subtyping is not a partial order).
+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.
+Hence the requirement that $T << S$ (we use $<<$ rather than subtyping because subtyping is not a partial order).
 
-We do not want to refine the type of a variable of type \DYNAMIC{}, as this could lead to more warnings rather than less.  The opposite requirement, that $T \ne \DYNAMIC{}$ is a safeguard lest $S$ ever be $\bot$.
+We do not want to refine the type of a variable of type \DYNAMIC{}, as this could lead to more warnings rather than fewer.
+The opposite requirement, that $T \ne \DYNAMIC{}$ is a safeguard lest $S$ ever be $\bot$.
 }
 
 \LMHash{}
diff --git a/pkg/analysis_server/lib/src/context_manager.dart b/pkg/analysis_server/lib/src/context_manager.dart
index b16e782..c8faf13 100644
--- a/pkg/analysis_server/lib/src/context_manager.dart
+++ b/pkg/analysis_server/lib/src/context_manager.dart
@@ -716,38 +716,20 @@
   /**
    * Process [options] for the given context [info].
    */
-  void processOptionsForDriver(ContextInfo info, Map<String, Object> options,
-      {bool optionsRemoved: false}) {
-    if (options == null && !optionsRemoved) {
-      return;
-    }
-    AnalysisOptionsImpl analysisOptions = info.analysisDriver.analysisOptions;
-
-    // In case options files are removed, revert to defaults.
-    if (optionsRemoved) {
-      // Start with defaults.
-      analysisOptions.resetToDefaults();
-
-      // Apply inherited options.
-      options = _toStringMap(_getEmbeddedOptions(info));
-      if (options != null) {
-        applyToAnalysisOptions(analysisOptions, options);
-      }
-    } else {
-      // Check for embedded options.
-      Map embeddedOptions = _getEmbeddedOptions(info);
-      if (embeddedOptions != null) {
-        options = _toStringMap(new Merger().merge(embeddedOptions, options));
-      }
-    }
-
-    applyToAnalysisOptions(analysisOptions, options);
-
-    // Nothing more to do.
+  void processOptionsForDriver(ContextInfo info,
+      AnalysisOptionsImpl analysisOptions, Map<String, Object> options) {
     if (options == null) {
       return;
     }
 
+    // Check for embedded options.
+    Map embeddedOptions = _getEmbeddedOptions(info);
+    if (embeddedOptions != null) {
+      options = _toStringMap(new Merger().merge(embeddedOptions, options));
+    }
+
+    applyToAnalysisOptions(analysisOptions, options);
+
     var analyzer = options[AnalyzerOptions.analyzer];
     if (analyzer is Map) {
       // Set ignore patterns.
@@ -1183,30 +1165,12 @@
 
     info.setDependencies(dependencies);
     if (enableNewAnalysisDriver) {
+      processOptionsForDriver(info, options, optionMap);
       info.analysisDriver = callbacks.addAnalysisDriver(folder, options);
     } else {
       info.context = callbacks.addContext(folder, options);
       _folderMap[folder] = info.context;
       info.context.name = folder.path;
-    }
-
-    // Look for pubspec-specified analysis configuration.
-    File pubspec;
-    if (packagespecFile?.exists == true) {
-      if (packagespecFile.shortName == PUBSPEC_NAME) {
-        pubspec = packagespecFile;
-      }
-    }
-    if (pubspec == null) {
-      Resource child = folder.getChild(PUBSPEC_NAME);
-      if (child.exists && child is File) {
-        pubspec = child;
-      }
-    }
-
-    if (enableNewAnalysisDriver) {
-      processOptionsForDriver(info, optionMap);
-    } else {
       processOptionsForContext(info, optionMap);
     }
 
diff --git a/pkg/analysis_server/lib/src/domain_completion.dart b/pkg/analysis_server/lib/src/domain_completion.dart
index 6bad443..436254e 100644
--- a/pkg/analysis_server/lib/src/domain_completion.dart
+++ b/pkg/analysis_server/lib/src/domain_completion.dart
@@ -138,7 +138,7 @@
     if (server.options.enableNewAnalysisDriver) {
       result = await server.getAnalysisResult(params.file);
 
-      if (result == null) {
+      if (result == null || !result.exists) {
         server.sendResponse(new Response.unknownSource(request));
         return;
       }
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/label_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/label_contributor.dart
index a540887..0db3193 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/label_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/label_contributor.dart
@@ -7,148 +7,17 @@
 import 'dart:async';
 
 import 'package:analysis_server/plugin/protocol/protocol.dart' as protocol
-    show Element, ElementKind;
+    show ElementKind;
+import 'package:analysis_server/src/protocol_server.dart'
+    show CompletionSuggestion, CompletionSuggestionKind;
 import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
 import 'package:analysis_server/src/services/completion/dart/completion_manager.dart'
     show DartCompletionRequestImpl;
 import 'package:analysis_server/src/services/completion/dart/local_declaration_visitor.dart'
     show LocalDeclarationVisitor;
 import 'package:analysis_server/src/services/completion/dart/optype.dart';
+import 'package:analysis_server/src/services/completion/dart/utilities.dart';
 import 'package:analyzer/dart/ast/ast.dart';
-import 'package:analyzer/dart/ast/standard_ast_factory.dart';
-import 'package:analyzer/dart/ast/token.dart';
-import 'package:analyzer/src/dart/ast/token.dart';
-import 'package:analyzer/src/generated/source.dart';
-
-import '../../../protocol_server.dart'
-    show CompletionSuggestion, CompletionSuggestionKind, Location;
-
-const DYNAMIC = 'dynamic';
-
-final TypeName NO_RETURN_TYPE = astFactory.typeName(
-    astFactory.simpleIdentifier(new StringToken(TokenType.IDENTIFIER, '', 0)),
-    null);
-
-/**
-* Create a new protocol Element for inclusion in a completion suggestion.
-*/
-protocol.Element createLocalElement(
-    Source source, protocol.ElementKind kind, SimpleIdentifier id,
-    {String parameters,
-    TypeName returnType,
-    bool isAbstract: false,
-    bool isDeprecated: false}) {
-  String name;
-  Location location;
-  if (id != null) {
-    name = id.name;
-    // TODO(danrubel) use lineInfo to determine startLine and startColumn
-    location = new Location(source.fullName, id.offset, id.length, 0, 0);
-  } else {
-    name = '';
-    location = new Location(source.fullName, -1, 0, 1, 0);
-  }
-  int flags = protocol.Element.makeFlags(
-      isAbstract: isAbstract,
-      isDeprecated: isDeprecated,
-      isPrivate: Identifier.isPrivateName(name));
-  return new protocol.Element(kind, name, flags,
-      location: location,
-      parameters: parameters,
-      returnType: nameForType(returnType));
-}
-
-/**
-* Create a new suggestion for the given field.
-* Return the new suggestion or `null` if it could not be created.
-*/
-CompletionSuggestion createLocalFieldSuggestion(
-    Source source, FieldDeclaration fieldDecl, VariableDeclaration varDecl) {
-  bool deprecated = isDeprecated(fieldDecl) || isDeprecated(varDecl);
-  TypeName type = fieldDecl.fields.type;
-  return createLocalSuggestion(
-      varDecl.name, deprecated, DART_RELEVANCE_LOCAL_FIELD, type,
-      classDecl: fieldDecl.parent,
-      element: createLocalElement(
-          source, protocol.ElementKind.FIELD, varDecl.name,
-          returnType: type, isDeprecated: deprecated));
-}
-
-/**
-* Create a new suggestion based upon the given information.
-* Return the new suggestion or `null` if it could not be created.
-*/
-CompletionSuggestion createLocalSuggestion(SimpleIdentifier id,
-    bool isDeprecated, int defaultRelevance, TypeName returnType,
-    {ClassDeclaration classDecl, protocol.Element element}) {
-  if (id == null) {
-    return null;
-  }
-  String completion = id.name;
-  if (completion == null || completion.length <= 0 || completion == '_') {
-    return null;
-  }
-  CompletionSuggestion suggestion = new CompletionSuggestion(
-      CompletionSuggestionKind.INVOCATION,
-      isDeprecated ? DART_RELEVANCE_LOW : defaultRelevance,
-      completion,
-      completion.length,
-      0,
-      isDeprecated,
-      false,
-      returnType: nameForType(returnType),
-      element: element);
-  if (classDecl != null) {
-    SimpleIdentifier classId = classDecl.name;
-    if (classId != null) {
-      String className = classId.name;
-      if (className != null && className.length > 0) {
-        suggestion.declaringType = className;
-      }
-    }
-  }
-  return suggestion;
-}
-
-/**
-* Return `true` if the @deprecated annotation is present
-*/
-bool isDeprecated(AnnotatedNode node) {
-  if (node != null) {
-    NodeList<Annotation> metadata = node.metadata;
-    if (metadata != null) {
-      return metadata.any((Annotation a) {
-        return a.name is SimpleIdentifier && a.name.name == 'deprecated';
-      });
-    }
-  }
-  return false;
-}
-
-/**
-* Return the name for the given type.
-*/
-String nameForType(TypeName type) {
-  if (type == NO_RETURN_TYPE) {
-    return null;
-  }
-  if (type == null) {
-    return DYNAMIC;
-  }
-  Identifier id = type.name;
-  if (id == null) {
-    return DYNAMIC;
-  }
-  String name = id.name;
-  if (name == null || name.length <= 0) {
-    return DYNAMIC;
-  }
-  TypeArgumentList typeArgs = type.typeArguments;
-  if (typeArgs != null) {
-    //TODO (danrubel) include type arguments
-  }
-  return name;
-}
 
 /**
  * A contributor for calculating label suggestions.
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/local_constructor_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/local_constructor_contributor.dart
index ad8e2b4..e2b3a46 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/local_constructor_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/local_constructor_contributor.dart
@@ -8,6 +8,8 @@
 
 import 'package:analysis_server/plugin/protocol/protocol.dart' as protocol
     show Element, ElementKind;
+import 'package:analysis_server/src/protocol_server.dart'
+    show CompletionSuggestion, CompletionSuggestionKind;
 import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
 import 'package:analysis_server/src/services/completion/dart/completion_manager.dart'
     show DartCompletionRequestImpl;
@@ -15,143 +17,10 @@
     show LocalDeclarationVisitor;
 import 'package:analysis_server/src/services/completion/dart/optype.dart';
 import 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart';
+import 'package:analysis_server/src/services/completion/dart/utilities.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/ast/standard_resolution_map.dart';
-import 'package:analyzer/dart/ast/standard_ast_factory.dart';
-import 'package:analyzer/dart/ast/token.dart';
 import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/src/dart/ast/token.dart';
-import 'package:analyzer/src/generated/source.dart';
-
-import '../../../protocol_server.dart'
-    show CompletionSuggestion, CompletionSuggestionKind, Location;
-
-const DYNAMIC = 'dynamic';
-
-final TypeName NO_RETURN_TYPE = astFactory.typeName(
-    astFactory.simpleIdentifier(new StringToken(TokenType.IDENTIFIER, '', 0)),
-    null);
-
-/**
-* Create a new protocol Element for inclusion in a completion suggestion.
-*/
-protocol.Element createLocalElement(
-    Source source, protocol.ElementKind kind, SimpleIdentifier id,
-    {String parameters,
-    TypeName returnType,
-    bool isAbstract: false,
-    bool isDeprecated: false}) {
-  String name;
-  Location location;
-  if (id != null) {
-    name = id.name;
-    // TODO(danrubel) use lineInfo to determine startLine and startColumn
-    location = new Location(source.fullName, id.offset, id.length, 0, 0);
-  } else {
-    name = '';
-    location = new Location(source.fullName, -1, 0, 1, 0);
-  }
-  int flags = protocol.Element.makeFlags(
-      isAbstract: isAbstract,
-      isDeprecated: isDeprecated,
-      isPrivate: Identifier.isPrivateName(name));
-  return new protocol.Element(kind, name, flags,
-      location: location,
-      parameters: parameters,
-      returnType: nameForType(returnType));
-}
-
-/**
-* Create a new suggestion for the given field.
-* Return the new suggestion or `null` if it could not be created.
-*/
-CompletionSuggestion createLocalFieldSuggestion(
-    Source source, FieldDeclaration fieldDecl, VariableDeclaration varDecl) {
-  bool deprecated = isDeprecated(fieldDecl) || isDeprecated(varDecl);
-  TypeName type = fieldDecl.fields.type;
-  return createLocalSuggestion(
-      varDecl.name, deprecated, DART_RELEVANCE_LOCAL_FIELD, type,
-      classDecl: fieldDecl.parent,
-      element: createLocalElement(
-          source, protocol.ElementKind.FIELD, varDecl.name,
-          returnType: type, isDeprecated: deprecated));
-}
-
-/**
-* Create a new suggestion based upon the given information.
-* Return the new suggestion or `null` if it could not be created.
-*/
-CompletionSuggestion createLocalSuggestion(SimpleIdentifier id,
-    bool isDeprecated, int defaultRelevance, TypeName returnType,
-    {ClassDeclaration classDecl, protocol.Element element}) {
-  if (id == null) {
-    return null;
-  }
-  String completion = id.name;
-  if (completion == null || completion.length <= 0 || completion == '_') {
-    return null;
-  }
-  CompletionSuggestion suggestion = new CompletionSuggestion(
-      CompletionSuggestionKind.INVOCATION,
-      isDeprecated ? DART_RELEVANCE_LOW : defaultRelevance,
-      completion,
-      completion.length,
-      0,
-      isDeprecated,
-      false,
-      returnType: nameForType(returnType),
-      element: element);
-  if (classDecl != null) {
-    SimpleIdentifier classId = classDecl.name;
-    if (classId != null) {
-      String className = classId.name;
-      if (className != null && className.length > 0) {
-        suggestion.declaringType = className;
-      }
-    }
-  }
-  return suggestion;
-}
-
-/**
-* Return `true` if the @deprecated annotation is present
-*/
-bool isDeprecated(AnnotatedNode node) {
-  if (node != null) {
-    NodeList<Annotation> metadata = node.metadata;
-    if (metadata != null) {
-      return metadata.any((Annotation a) {
-        return a.name is SimpleIdentifier && a.name.name == 'deprecated';
-      });
-    }
-  }
-  return false;
-}
-
-/**
-* Return the name for the given type.
-*/
-String nameForType(TypeName type) {
-  if (type == NO_RETURN_TYPE) {
-    return null;
-  }
-  if (type == null) {
-    return DYNAMIC;
-  }
-  Identifier id = type.name;
-  if (id == null) {
-    return DYNAMIC;
-  }
-  String name = id.name;
-  if (name == null || name.length <= 0) {
-    return DYNAMIC;
-  }
-  TypeArgumentList typeArgs = type.typeArguments;
-  if (typeArgs != null) {
-    //TODO (danrubel) include type arguments
-  }
-  return name;
-}
 
 /**
  * A contributor for calculating constructor suggestions
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/local_reference_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/local_reference_contributor.dart
index 2d3bdd1..41e50c5 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/local_reference_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/local_reference_contributor.dart
@@ -8,143 +8,24 @@
 
 import 'package:analysis_server/plugin/protocol/protocol.dart' as protocol
     show Element, ElementKind;
+import 'package:analysis_server/src/protocol_server.dart'
+    show CompletionSuggestion, CompletionSuggestionKind, Location;
 import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
 import 'package:analysis_server/src/services/completion/dart/completion_manager.dart'
     show DartCompletionRequestImpl;
 import 'package:analysis_server/src/services/completion/dart/local_declaration_visitor.dart'
     show LocalDeclarationVisitor;
 import 'package:analysis_server/src/services/completion/dart/optype.dart';
+import 'package:analysis_server/src/services/completion/dart/utilities.dart';
 import 'package:analysis_server/src/services/correction/strings.dart';
 import 'package:analysis_server/src/utilities/documentation.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/ast/standard_resolution_map.dart';
-import 'package:analyzer/dart/ast/standard_ast_factory.dart';
 import 'package:analyzer/dart/ast/token.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/type.dart';
-import 'package:analyzer/src/dart/ast/token.dart';
-import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/generated/utilities_dart.dart' show ParameterKind;
 
-import '../../../protocol_server.dart'
-    show CompletionSuggestion, CompletionSuggestionKind, Location;
-
-const DYNAMIC = 'dynamic';
-
-final TypeName NO_RETURN_TYPE = astFactory.typeName(
-    astFactory.simpleIdentifier(new StringToken(TokenType.IDENTIFIER, '', 0)),
-    null);
-
-/**
-* Create a new protocol Element for inclusion in a completion suggestion.
-*/
-protocol.Element _createLocalElement(
-    Source source, protocol.ElementKind kind, SimpleIdentifier id,
-    {String parameters,
-    TypeName returnType,
-    bool isAbstract: false,
-    bool isDeprecated: false}) {
-  String name;
-  Location location;
-  if (id != null) {
-    name = id.name;
-    // TODO(danrubel) use lineInfo to determine startLine and startColumn
-    location = new Location(source.fullName, id.offset, id.length, 0, 0);
-  } else {
-    name = '';
-    location = new Location(source.fullName, -1, 0, 1, 0);
-  }
-  int flags = protocol.Element.makeFlags(
-      isAbstract: isAbstract,
-      isDeprecated: isDeprecated,
-      isPrivate: Identifier.isPrivateName(name));
-  return new protocol.Element(kind, name, flags,
-      location: location,
-      parameters: parameters,
-      returnType: _nameForType(returnType));
-}
-
-/**
-* Create a new suggestion based upon the given information.
-* Return the new suggestion or `null` if it could not be created.
-*/
-CompletionSuggestion _createLocalSuggestion(
-    SimpleIdentifier id,
-    CompletionSuggestionKind kind,
-    bool isDeprecated,
-    int defaultRelevance,
-    TypeName returnType,
-    {ClassDeclaration classDecl,
-    protocol.Element element}) {
-  if (id == null) {
-    return null;
-  }
-  String completion = id.name;
-  if (completion == null || completion.length <= 0 || completion == '_') {
-    return null;
-  }
-  CompletionSuggestion suggestion = new CompletionSuggestion(
-      kind,
-      isDeprecated ? DART_RELEVANCE_LOW : defaultRelevance,
-      completion,
-      completion.length,
-      0,
-      isDeprecated,
-      false,
-      returnType: _nameForType(returnType),
-      element: element);
-  if (classDecl != null) {
-    SimpleIdentifier classId = classDecl.name;
-    if (classId != null) {
-      String className = classId.name;
-      if (className != null && className.length > 0) {
-        suggestion.declaringType = className;
-      }
-    }
-  }
-  return suggestion;
-}
-
-/**
-* Return `true` if the @deprecated annotation is present
-*/
-bool _isDeprecated(AnnotatedNode node) {
-  if (node != null) {
-    NodeList<Annotation> metadata = node.metadata;
-    if (metadata != null) {
-      return metadata.any((Annotation a) {
-        return a.name is SimpleIdentifier && a.name.name == 'deprecated';
-      });
-    }
-  }
-  return false;
-}
-
-/**
-* Return the name for the given type.
-*/
-String _nameForType(TypeName type) {
-  if (type == NO_RETURN_TYPE) {
-    return null;
-  }
-  if (type == null) {
-    return DYNAMIC;
-  }
-  Identifier id = type.name;
-  if (id == null) {
-    return DYNAMIC;
-  }
-  String name = id.name;
-  if (name == null || name.length <= 0) {
-    return DYNAMIC;
-  }
-  TypeArgumentList typeArgs = type.typeArguments;
-  if (typeArgs != null) {
-    //TODO (danrubel) include type arguments
-  }
-  return name;
-}
-
 /**
  * A contributor for calculating suggestions for declarations in the local
  * file and containing library.
@@ -244,7 +125,7 @@
           NO_RETURN_TYPE,
           protocol.ElementKind.CLASS,
           isAbstract: declaration.isAbstract,
-          isDeprecated: _isDeprecated(declaration));
+          isDeprecated: isDeprecated(declaration));
     }
   }
 
@@ -257,7 +138,7 @@
           NO_RETURN_TYPE,
           protocol.ElementKind.CLASS_TYPE_ALIAS,
           isAbstract: true,
-          isDeprecated: _isDeprecated(declaration));
+          isDeprecated: isDeprecated(declaration));
     }
   }
 
@@ -269,12 +150,12 @@
           declaration.name,
           NO_RETURN_TYPE,
           protocol.ElementKind.ENUM,
-          isDeprecated: _isDeprecated(declaration));
+          isDeprecated: isDeprecated(declaration));
       for (EnumConstantDeclaration enumConstant in declaration.constants) {
         if (!enumConstant.isSynthetic) {
           _addLocalSuggestion_includeReturnValueSuggestions_enumConstant(
               enumConstant, declaration,
-              isDeprecated: _isDeprecated(declaration));
+              isDeprecated: isDeprecated(declaration));
         }
       }
     }
@@ -284,7 +165,7 @@
   void declaredField(FieldDeclaration fieldDecl, VariableDeclaration varDecl) {
     if (optype.includeReturnValueSuggestions &&
         (!optype.inStaticMethodBody || fieldDecl.isStatic)) {
-      bool deprecated = _isDeprecated(fieldDecl) || _isDeprecated(varDecl);
+      bool deprecated = isDeprecated(fieldDecl) || isDeprecated(varDecl);
       TypeName typeName = fieldDecl.fields.type;
       _addLocalSuggestion_includeReturnValueSuggestions(
           fieldDecl.documentationComment,
@@ -326,7 +207,7 @@
           declaration.name,
           typeName,
           elemKind,
-          isDeprecated: _isDeprecated(declaration),
+          isDeprecated: isDeprecated(declaration),
           param: declaration.functionExpression.parameters,
           relevance: relevance);
     }
@@ -342,7 +223,7 @@
           declaration.returnType,
           protocol.ElementKind.FUNCTION_TYPE_ALIAS,
           isAbstract: true,
-          isDeprecated: _isDeprecated(declaration));
+          isDeprecated: isDeprecated(declaration));
     }
   }
 
@@ -394,7 +275,7 @@
           typeName,
           elemKind,
           isAbstract: declaration.isAbstract,
-          isDeprecated: _isDeprecated(declaration),
+          isDeprecated: isDeprecated(declaration),
           classDecl: declaration.parent,
           param: param,
           relevance: relevance);
@@ -419,7 +300,7 @@
           varDecl.name,
           varList.type,
           protocol.ElementKind.TOP_LEVEL_VARIABLE,
-          isDeprecated: _isDeprecated(varList) || _isDeprecated(varDecl),
+          isDeprecated: isDeprecated(varList) || isDeprecated(varDecl),
           relevance: DART_RELEVANCE_LOCAL_TOP_LEVEL_VARIABLE);
     }
   }
@@ -434,9 +315,9 @@
     CompletionSuggestionKind kind = targetIsFunctionalArgument
         ? CompletionSuggestionKind.IDENTIFIER
         : optype.suggestKind;
-    CompletionSuggestion suggestion = _createLocalSuggestion(
-        id, kind, isDeprecated, relevance, typeName,
-        classDecl: classDecl);
+    CompletionSuggestion suggestion = createLocalSuggestion(
+        id, isDeprecated, relevance, typeName,
+        classDecl: classDecl, kind: kind);
     if (suggestion != null) {
       _setDocumentation(suggestion, documentationComment);
       if (privateMemberRelevance != null &&
@@ -444,7 +325,7 @@
         suggestion.relevance = privateMemberRelevance;
       }
       suggestionMap.putIfAbsent(suggestion.completion, () => suggestion);
-      suggestion.element = _createLocalElement(request.source, elemKind, id,
+      suggestion.element = createLocalElement(request.source, elemKind, id,
           isAbstract: isAbstract,
           isDeprecated: isDeprecated,
           parameters: param?.toSource(),
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/utilities.dart b/pkg/analysis_server/lib/src/services/completion/dart/utilities.dart
new file mode 100644
index 0000000..0cba871
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/completion/dart/utilities.dart
@@ -0,0 +1,152 @@
+// 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.
+
+/**
+ * A collection of utility methods used by completion contributors.
+ */
+import 'package:analysis_server/plugin/protocol/protocol.dart' as protocol
+    show Element, ElementKind;
+import 'package:analysis_server/src/protocol_server.dart'
+    show CompletionSuggestion, CompletionSuggestionKind, Location;
+import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/ast/standard_ast_factory.dart';
+import 'package:analyzer/dart/ast/token.dart';
+import 'package:analyzer/src/dart/ast/token.dart';
+import 'package:analyzer/src/generated/source.dart';
+
+/**
+ * The name of the type `dynamic`;
+ */
+const DYNAMIC = 'dynamic';
+
+/**
+ * A marker used in place of `null` when a function has no return type.
+ */
+final TypeName NO_RETURN_TYPE = astFactory.typeName(
+    astFactory.simpleIdentifier(new StringToken(TokenType.IDENTIFIER, '', 0)),
+    null);
+
+/**
+ * Create a new protocol Element for inclusion in a completion suggestion.
+ */
+protocol.Element createLocalElement(
+    Source source, protocol.ElementKind kind, SimpleIdentifier id,
+    {String parameters,
+    TypeName returnType,
+    bool isAbstract: false,
+    bool isDeprecated: false}) {
+  String name;
+  Location location;
+  if (id != null) {
+    name = id.name;
+    // TODO(danrubel) use lineInfo to determine startLine and startColumn
+    location = new Location(source.fullName, id.offset, id.length, 0, 0);
+  } else {
+    name = '';
+    location = new Location(source.fullName, -1, 0, 1, 0);
+  }
+  int flags = protocol.Element.makeFlags(
+      isAbstract: isAbstract,
+      isDeprecated: isDeprecated,
+      isPrivate: Identifier.isPrivateName(name));
+  return new protocol.Element(kind, name, flags,
+      location: location,
+      parameters: parameters,
+      returnType: nameForType(returnType));
+}
+
+/**
+ * Create a new suggestion for the given [fieldDecl]. Return the new suggestion
+ * or `null` if it could not be created.
+ */
+CompletionSuggestion createLocalFieldSuggestion(
+    Source source, FieldDeclaration fieldDecl, VariableDeclaration varDecl) {
+  bool deprecated = isDeprecated(fieldDecl) || isDeprecated(varDecl);
+  TypeName type = fieldDecl.fields.type;
+  return createLocalSuggestion(
+      varDecl.name, deprecated, DART_RELEVANCE_LOCAL_FIELD, type,
+      classDecl: fieldDecl.parent,
+      element: createLocalElement(
+          source, protocol.ElementKind.FIELD, varDecl.name,
+          returnType: type, isDeprecated: deprecated));
+}
+
+/**
+ * Create a new suggestion based upon the given information. Return the new
+ * suggestion or `null` if it could not be created.
+ */
+CompletionSuggestion createLocalSuggestion(SimpleIdentifier id,
+    bool isDeprecated, int defaultRelevance, TypeName returnType,
+    {ClassDeclaration classDecl,
+    CompletionSuggestionKind kind = CompletionSuggestionKind.INVOCATION,
+    protocol.Element element}) {
+  if (id == null) {
+    return null;
+  }
+  String completion = id.name;
+  if (completion == null || completion.length <= 0 || completion == '_') {
+    return null;
+  }
+  CompletionSuggestion suggestion = new CompletionSuggestion(
+      kind,
+      isDeprecated ? DART_RELEVANCE_LOW : defaultRelevance,
+      completion,
+      completion.length,
+      0,
+      isDeprecated,
+      false,
+      returnType: nameForType(returnType),
+      element: element);
+  if (classDecl != null) {
+    SimpleIdentifier classId = classDecl.name;
+    if (classId != null) {
+      String className = classId.name;
+      if (className != null && className.length > 0) {
+        suggestion.declaringType = className;
+      }
+    }
+  }
+  return suggestion;
+}
+
+/**
+ * Return `true` if the @deprecated annotation is present on the given [node].
+ */
+bool isDeprecated(AnnotatedNode node) {
+  if (node != null) {
+    NodeList<Annotation> metadata = node.metadata;
+    if (metadata != null) {
+      return metadata.any((Annotation a) {
+        return a.name is SimpleIdentifier && a.name.name == 'deprecated';
+      });
+    }
+  }
+  return false;
+}
+
+/**
+ * Return the name for the given [type].
+ */
+String nameForType(TypeName type) {
+  if (type == NO_RETURN_TYPE) {
+    return null;
+  }
+  if (type == null) {
+    return DYNAMIC;
+  }
+  Identifier id = type.name;
+  if (id == null) {
+    return DYNAMIC;
+  }
+  String name = id.name;
+  if (name == null || name.length <= 0) {
+    return DYNAMIC;
+  }
+  TypeArgumentList typeArgs = type.typeArguments;
+  if (typeArgs != null) {
+    //TODO (danrubel) include type arguments
+  }
+  return name;
+}
diff --git a/pkg/analysis_server/lib/src/services/correction/fix.dart b/pkg/analysis_server/lib/src/services/correction/fix.dart
index 0d49cf4..124621e 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix.dart
@@ -126,8 +126,6 @@
   static const ADD_NE_NULL = const FixKind('ADD_NE_NULL', 50, "Add != null");
   static const ADD_PACKAGE_DEPENDENCY = const FixKind(
       'ADD_PACKAGE_DEPENDENCY', 50, "Add dependency on package '{0}'");
-  static const ADD_PART_OF =
-      const FixKind('ADD_PART_OF', 50, "Add 'part of' directive");
   static const ADD_SUPER_CONSTRUCTOR_INVOCATION = const FixKind(
       'ADD_SUPER_CONSTRUCTOR_INVOCATION',
       50,
@@ -209,8 +207,6 @@
       const FixKind('REMOVE_UNUSED_IMPORT', 50, "Remove unused import");
   static const REPLACE_BOOLEAN_WITH_BOOL = const FixKind(
       'REPLACE_BOOLEAN_WITH_BOOL', 50, "Replace 'boolean' with 'bool'");
-  static const REPLACE_IMPORT_URI =
-      const FixKind('REPLACE_IMPORT_URI', 50, "Replace with '{0}'");
   static const REPLACE_VAR_WITH_DYNAMIC = const FixKind(
       'REPLACE_VAR_WITH_DYNAMIC', 50, "Replace 'var' with 'dynamic'");
   static const REPLACE_RETURN_TYPE_FUTURE = 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 efec5ee..c96165d 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
@@ -200,9 +200,6 @@
         CompileTimeErrorCode.NO_DEFAULT_SUPER_CONSTRUCTOR_IMPLICIT) {
       _addFix_createConstructorSuperImplicit();
     }
-    if (errorCode == CompileTimeErrorCode.PART_OF_NON_PART) {
-      _addFix_addPartOfDirective();
-    }
     if (errorCode ==
         CompileTimeErrorCode.UNDEFINED_CONSTRUCTOR_IN_INITIALIZER_DEFAULT) {
       _addFix_createConstructorSuperExplicit();
@@ -210,10 +207,6 @@
     if (errorCode == CompileTimeErrorCode.URI_DOES_NOT_EXIST) {
       _addFix_createImportUri();
       _addFix_createPartUri();
-      _addFix_replaceImportUri();
-    }
-    if (errorCode == CompileTimeErrorCode.URI_HAS_NOT_BEEN_GENERATED) {
-      _addFix_replaceImportUri();
     }
     if (errorCode == HintCode.CAN_BE_NULL_AFTER_NULL_AWARE) {
       _addFix_canBeNullAfterNullAware();
@@ -545,26 +538,6 @@
     }
   }
 
-  void _addFix_addPartOfDirective() {
-    // TODO(brianwilkerson) Generalize this to allow other valid string literals.
-    if (node is SimpleStringLiteral && node.parent is PartDirective) {
-      PartDirective directive = node.parent;
-      Source partSource = directive.uriSource;
-      CompilationUnit partUnit;
-      partUnit = context.getResolvedCompilationUnit2(partSource, partSource);
-      if (partUnit != null) {
-        CorrectionUtils partUtils = new CorrectionUtils(partUnit);
-        CorrectionUtils_InsertDesc desc = partUtils.getInsertDescTop();
-        String libraryName = unitLibraryElement.name;
-        _addInsertEdit(
-            desc.offset,
-            '${desc.prefix}part of $libraryName;$eol${desc.suffix}',
-            partUnit.element);
-        _addFix(DartFixKind.ADD_PART_OF, []);
-      }
-    }
-  }
-
   void _addFix_boolInsteadOfBoolean() {
     SourceRange range = rf.rangeError(error);
     _addReplaceEdit(range, 'bool');
@@ -1365,6 +1338,7 @@
 
   void _addFix_createMissingOverrides_single(SourceBuilder sb,
       ClassDeclaration targetClass, ExecutableElement element) {
+    utils.targetExecutableElement = element;
     // prepare environment
     String prefix = utils.getIndent(1);
     String prefix2 = utils.getIndent(2);
@@ -1400,6 +1374,7 @@
     }
     // name
     sb.append(element.displayName);
+    _appendTypeParameters(sb, element.typeParameters);
     // parameters + body
     if (isGetter) {
       sb.append(' => null;');
@@ -1417,6 +1392,7 @@
       sb.append('}');
     }
     sb.append(eol);
+    utils.targetExecutableElement = null;
   }
 
   void _addFix_createNoSuchMethod() {
@@ -1811,32 +1787,6 @@
     _addFix(DartFixKind.REMOVE_UNUSED_IMPORT, []);
   }
 
-  void _addFix_replaceImportUri() {
-    if (node is SimpleStringLiteral) {
-      SimpleStringLiteral stringLiteral = node;
-      String uri = stringLiteral.value;
-      String uriName = substringAfterLast(uri, '/');
-      for (Source libSource in context.librarySources) {
-        String libFile = libSource.fullName;
-        if (substringAfterLast(libFile, '/') == uriName) {
-          String fixedUri;
-          // may be "package:" URI
-          String libPackageUri = findNonFileUri(context, libFile);
-          if (libPackageUri != null) {
-            fixedUri = libPackageUri;
-          } else {
-            String relativeFile = relative(libFile, from: unitLibraryFolder);
-            fixedUri = split(relativeFile).join('/');
-          }
-          // add fix
-          SourceRange range = rf.rangeNode(node);
-          _addReplaceEdit(range, "'$fixedUri'");
-          _addFix(DartFixKind.REPLACE_IMPORT_URI, [fixedUri]);
-        }
-      }
-    }
-  }
-
   void _addFix_replaceVarWithDynamic() {
     SourceRange range = rf.rangeError(error);
     _addReplaceEdit(range, 'dynamic');
@@ -2164,33 +2114,31 @@
     ConstructorDeclaration constructor = node.parent;
     // add these fields
     List<FieldElement> fields =
-        error.getProperty(ErrorProperty.NOT_INITIALIZED_FIELDS);
-    if (fields != null) {
-      // prepare new parameters code
-      fields.sort((a, b) => a.nameOffset - b.nameOffset);
-      String fieldParametersCode =
-          fields.map((field) => 'this.${field.name}').join(', ');
-      // prepare the last required parameter
-      FormalParameter lastRequiredParameter;
-      List<FormalParameter> parameters = constructor.parameters.parameters;
-      for (FormalParameter parameter in parameters) {
-        if (parameter.kind == ParameterKind.REQUIRED) {
-          lastRequiredParameter = parameter;
-        }
+        ErrorVerifier.computeNotInitializedFields(constructor);
+    // prepare new parameters code
+    fields.sort((a, b) => a.nameOffset - b.nameOffset);
+    String fieldParametersCode =
+        fields.map((field) => 'this.${field.name}').join(', ');
+    // prepare the last required parameter
+    FormalParameter lastRequiredParameter;
+    List<FormalParameter> parameters = constructor.parameters.parameters;
+    for (FormalParameter parameter in parameters) {
+      if (parameter.kind == ParameterKind.REQUIRED) {
+        lastRequiredParameter = parameter;
       }
-      // append new field formal initializers
-      if (lastRequiredParameter != null) {
-        _addInsertEdit(lastRequiredParameter.end, ', $fieldParametersCode');
-      } else {
-        int offset = constructor.parameters.leftParenthesis.end;
-        if (parameters.isNotEmpty) {
-          fieldParametersCode += ', ';
-        }
-        _addInsertEdit(offset, fieldParametersCode);
-      }
-      // add proposal
-      _addFix(DartFixKind.ADD_FIELD_FORMAL_PARAMETERS, []);
     }
+    // append new field formal initializers
+    if (lastRequiredParameter != null) {
+      _addInsertEdit(lastRequiredParameter.end, ', $fieldParametersCode');
+    } else {
+      int offset = constructor.parameters.leftParenthesis.end;
+      if (parameters.isNotEmpty) {
+        fieldParametersCode += ', ';
+      }
+      _addInsertEdit(offset, fieldParametersCode);
+    }
+    // add proposal
+    _addFix(DartFixKind.ADD_FIELD_FORMAL_PARAMETERS, []);
   }
 
   void _addFix_useEffectiveIntegerDivision() {
@@ -2534,7 +2482,7 @@
   }
 
   void _appendType(SourceBuilder sb, DartType type,
-      {String groupId, bool orVar: false}) {
+      {String groupId, bool orVar: false, bool trailingSpace: true}) {
     if (type != null && !type.isDynamic) {
       String typeSource = utils.getTypeSource(type, librariesToImport);
       if (groupId != null) {
@@ -2544,12 +2492,39 @@
       } else {
         sb.append(typeSource);
       }
-      sb.append(' ');
+      if (trailingSpace) {
+        sb.append(' ');
+      }
     } else if (orVar) {
       sb.append('var ');
     }
   }
 
+  void _appendTypeParameter(
+      SourceBuilder sb, TypeParameterElement typeParameter) {
+    sb.append(typeParameter.name);
+    if (typeParameter.bound != null) {
+      sb.append(' extends ');
+      _appendType(sb, typeParameter.bound, trailingSpace: false);
+    }
+  }
+
+  void _appendTypeParameters(
+      SourceBuilder sb, List<TypeParameterElement> typeParameters) {
+    if (typeParameters.isNotEmpty) {
+      sb.append('<');
+      bool isFirst = true;
+      for (TypeParameterElement typeParameter in typeParameters) {
+        if (!isFirst) {
+          sb.append(', ');
+        }
+        isFirst = false;
+        _appendTypeParameter(sb, typeParameter);
+      }
+      sb.append('>');
+    }
+  }
+
   /**
    * Computes the name of the library at the given [path].
    * See https://www.dartlang.org/articles/style-guide/#names for conventions.
diff --git a/pkg/analysis_server/lib/src/services/correction/util.dart b/pkg/analysis_server/lib/src/services/correction/util.dart
index d5eeeb0..82217a2 100644
--- a/pkg/analysis_server/lib/src/services/correction/util.dart
+++ b/pkg/analysis_server/lib/src/services/correction/util.dart
@@ -158,25 +158,6 @@
 }
 
 /**
- * Attempts to convert the given absolute path into an absolute URI, such as
- * "dart" or "package" URI.
- *
- * [context] - the [AnalysisContext] to work in.
- * [path] - the absolute path, not `null`.
- *
- * Returns the absolute (non-file) URI or `null`.
- */
-String findNonFileUri(AnalysisContext context, String path) {
-  Source fileSource =
-      new NonExistingSource(path, toUri(path), UriKind.FILE_URI);
-  Uri uri = context.sourceFactory.restoreUri(fileSource);
-  if (uri == null || uri.scheme == 'file') {
-    return null;
-  }
-  return uri.toString();
-}
-
-/**
  * Returns the EOL to use for the given [code].
  */
 String getCodeEndOfLine(String code) {
@@ -699,6 +680,8 @@
    */
   ClassElement targetClassElement;
 
+  ExecutableElement targetExecutableElement;
+
   LibraryElement _library;
   String _buffer;
   String _endOfLine;
@@ -1500,13 +1483,15 @@
   }
 
   /**
-   * Checks if [type] is visible at [targetOffset].
+   * Checks if [type] is visible in [targetExecutableElement] or
+   * [targetClassElement].
    */
   bool _isTypeVisible(DartType type) {
     if (type is TypeParameterType) {
       TypeParameterElement parameterElement = type.element;
       Element parameterClassElement = parameterElement.enclosingElement;
-      return identical(parameterClassElement, targetClassElement);
+      return identical(parameterClassElement, targetExecutableElement) ||
+          identical(parameterClassElement, targetClassElement);
     }
     return true;
   }
diff --git a/pkg/analysis_server/lib/src/services/refactoring/extract_method.dart b/pkg/analysis_server/lib/src/services/refactoring/extract_method.dart
index 119b89e..e904e14 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/extract_method.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/extract_method.dart
@@ -1219,8 +1219,7 @@
       if (returnType is InterfaceType && type is InterfaceType) {
         returnType = InterfaceType.getSmartLeastUpperBound(returnType, type);
       } else {
-        returnType = context.typeSystem
-            .getLeastUpperBound(context.typeProvider, returnType, type);
+        returnType = context.typeSystem.getLeastUpperBound(returnType, type);
       }
     }
   }
diff --git a/pkg/analysis_server/lib/src/services/refactoring/inline_method.dart b/pkg/analysis_server/lib/src/services/refactoring/inline_method.dart
index d1a8165..68acb96 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/inline_method.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/inline_method.dart
@@ -199,6 +199,7 @@
   final GetResolvedUnit getResolvedUnit;
   final CompilationUnit unit;
   final int offset;
+  _UnitCache _unitCache;
   CorrectionUtils utils;
   SourceChange change;
 
@@ -221,6 +222,7 @@
 
   InlineMethodRefactoringImpl(
       this.searchEngine, this.getResolvedUnit, this.unit, this.offset) {
+    _unitCache = new _UnitCache(getResolvedUnit, unit);
     utils = new CorrectionUtils(unit);
   }
 
@@ -317,6 +319,20 @@
   @override
   bool requiresPreview() => false;
 
+  Future<FunctionDeclaration> _computeFunctionDeclaration() async {
+    CompilationUnit unit = await _unitCache.getUnit(_methodElement);
+    return new NodeLocator(_methodElement.nameOffset)
+        .searchWithin(unit)
+        .getAncestor((n) => n is FunctionDeclaration) as FunctionDeclaration;
+  }
+
+  Future<MethodDeclaration> _computeMethodDeclaration() async {
+    CompilationUnit unit = await _unitCache.getUnit(_methodElement);
+    return new NodeLocator(_methodElement.nameOffset)
+        .searchWithin(unit)
+        .getAncestor((n) => n is MethodDeclaration) as MethodDeclaration;
+  }
+
   _SourcePart _createSourcePart(SourceRange range) {
     String source = _methodUtils.getRangeText(range);
     String prefix = getLinePrefix(source);
@@ -355,12 +371,12 @@
     }
     _methodElement = element as ExecutableElement;
     _isAccessor = element is PropertyAccessorElement;
-    _methodUnit = await getResolvedUnit(element);
+    _methodUnit = await _unitCache.getUnit(element);
     _methodUtils = new CorrectionUtils(_methodUnit);
     // class member
     bool isClassMember = element.enclosingElement is ClassElement;
     if (element is MethodElement || _isAccessor && isClassMember) {
-      MethodDeclaration methodDeclaration = element.computeNode();
+      MethodDeclaration methodDeclaration = await _computeMethodDeclaration();
       _methodNode = methodDeclaration;
       _methodParameters = methodDeclaration.parameters;
       _methodBody = methodDeclaration.body;
@@ -373,7 +389,8 @@
     // unit member
     bool isUnitMember = element.enclosingElement is CompilationUnitElement;
     if (element is FunctionElement || _isAccessor && isUnitMember) {
-      FunctionDeclaration functionDeclaration = element.computeNode();
+      FunctionDeclaration functionDeclaration =
+          await _computeFunctionDeclaration();
       _methodNode = functionDeclaration;
       _methodParameters = functionDeclaration.functionExpression.parameters;
       _methodBody = functionDeclaration.functionExpression.body;
@@ -451,7 +468,7 @@
   Future<Null> init() async {
     refElement = reference.element;
     // prepare CorrectionUtils
-    CompilationUnit refUnit = await ref.getResolvedUnit(refElement);
+    CompilationUnit refUnit = await ref._unitCache.getUnit(refElement);
     _refUtils = new CorrectionUtils(refUnit);
     // prepare node and environment
     _node = _refUtils.findNode(reference.sourceRange.offset);
@@ -771,6 +788,26 @@
   }
 }
 
+class _UnitCache {
+  final GetResolvedUnit getResolvedUnit;
+  final Map<CompilationUnitElement, CompilationUnit> map = {};
+
+  _UnitCache(this.getResolvedUnit, CompilationUnit unit) {
+    map[unit.element] = unit;
+  }
+
+  Future<CompilationUnit> getUnit(Element element) async {
+    Element unitElement =
+        element.getAncestor((e) => e is CompilationUnitElement);
+    CompilationUnit unit = map[unitElement];
+    if (unit == null) {
+      unit = unitElement.unit;
+      map[unitElement] = unit;
+    }
+    return unit;
+  }
+}
+
 /**
  * A visitor that fills [_SourcePart] with fields, parameters and variables.
  */
diff --git a/pkg/analysis_server/test/abstract_context.dart b/pkg/analysis_server/test/abstract_context.dart
index ac7d8c0..6d804be 100644
--- a/pkg/analysis_server/test/abstract_context.dart
+++ b/pkg/analysis_server/test/abstract_context.dart
@@ -4,6 +4,8 @@
 
 library testing.abstract_context;
 
+import 'dart:async';
+
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/visitor.dart';
@@ -111,6 +113,9 @@
    * Performs all analysis tasks in [context].
    */
   void performAllAnalysisTasks() {
+    if (enableNewAnalysisDriver) {
+      return;
+    }
     while (true) {
       engine.AnalysisResult result = context.performAnalysisTask();
       if (!result.hasMoreWork) {
@@ -123,12 +128,12 @@
     AnalysisEngine.instance.processRequiredPlugins();
   }
 
-  CompilationUnit resolveDartUnit(Source unitSource, Source librarySource) {
-    return context.resolveCompilationUnit2(unitSource, librarySource);
-  }
-
-  CompilationUnit resolveLibraryUnit(Source source) {
-    return context.resolveCompilationUnit2(source, source);
+  Future<CompilationUnit> resolveLibraryUnit(Source source) async {
+    if (enableNewAnalysisDriver) {
+      return (await driver.getResult(source.fullName))?.unit;
+    } else {
+      return context.resolveCompilationUnit2(source, source);
+    }
   }
 
   void setUp() {
diff --git a/pkg/analysis_server/test/abstract_single_unit.dart b/pkg/analysis_server/test/abstract_single_unit.dart
index bda1d20..b515476 100644
--- a/pkg/analysis_server/test/abstract_single_unit.dart
+++ b/pkg/analysis_server/test/abstract_single_unit.dart
@@ -4,10 +4,12 @@
 
 library test.services.src.index.abstract_single_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/ast/utilities.dart';
+import 'package:analyzer/src/dart/error/hint_codes.dart';
 import 'package:analyzer/src/generated/java_engine.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:test/test.dart';
@@ -29,11 +31,6 @@
     testSource = addSource(testFile, code, uri);
   }
 
-  void assertNoErrorsInSource(Source source) {
-    List<AnalysisError> errors = context.getErrors(source).errors;
-    expect(errors, isEmpty);
-  }
-
   Element findElement(String name, [ElementKind kind]) {
     return findChildElement(testUnitElement, name, kind);
   }
@@ -98,11 +95,28 @@
     return length;
   }
 
-  void resolveTestUnit(String code) {
+  Future<Null> resolveTestUnit(String code) async {
     addTestSource(code);
-    testUnit = resolveLibraryUnit(testSource);
-    if (verifyNoTestUnitErrors) {
-      assertNoErrorsInSource(testSource);
+    if (enableNewAnalysisDriver) {
+      var result = await driver.getResult(testFile);
+      testUnit = (result).unit;
+      if (verifyNoTestUnitErrors) {
+        expect(result.errors.where((AnalysisError error) {
+          return
+            error.errorCode != HintCode.DEAD_CODE &&
+            error.errorCode != HintCode.UNUSED_CATCH_CLAUSE &&
+              error.errorCode != HintCode.UNUSED_CATCH_STACK &&
+              error.errorCode != HintCode.UNUSED_ELEMENT &&
+              error.errorCode != HintCode.UNUSED_FIELD &&
+              error.errorCode != HintCode.UNUSED_IMPORT &&
+              error.errorCode != HintCode.UNUSED_LOCAL_VARIABLE;
+        }), isEmpty);
+      }
+    } else {
+      testUnit = await resolveLibraryUnit(testSource);
+      if (verifyNoTestUnitErrors) {
+        expect(context.getErrors(testSource).errors, isEmpty);
+      }
     }
     testUnitElement = testUnit.element;
     testLibraryElement = testUnitElement.library;
diff --git a/pkg/analysis_server/test/integration/completion/get_suggestions_test.dart b/pkg/analysis_server/test/integration/completion/get_suggestions_test.dart
index d899821..6376aa5 100644
--- a/pkg/analysis_server/test/integration/completion/get_suggestions_test.dart
+++ b/pkg/analysis_server/test/integration/completion/get_suggestions_test.dart
@@ -129,11 +129,4 @@
 class GetSuggestionsTest_Driver extends AbstractGetSuggestionsTest {
   @override
   bool get enableNewAnalysisDriver => true;
-
-  @failingTest
-  test_getSuggestions_sourceMissing_noWait() {
-    //  Expected: same instance as 'exception from server'
-    //    Actual: CompletionGetSuggestionsResult:<{"id":"0"}>
-    return super.test_getSuggestions_sourceMissing_noWait();
-  }
 }
diff --git a/pkg/analysis_server/test/plugin/protocol_dart_test.dart b/pkg/analysis_server/test/plugin/protocol_dart_test.dart
index 5f45220..a08ff88 100644
--- a/pkg/analysis_server/test/plugin/protocol_dart_test.dart
+++ b/pkg/analysis_server/test/plugin/protocol_dart_test.dart
@@ -102,14 +102,14 @@
     return findChildElement(unit.element, name, kind);
   }
 
-  void test_fromElement_CLASS() {
+  test_fromElement_CLASS() async {
     engine.Source source = addSource(
         '/test.dart',
         '''
 @deprecated
 abstract class _A {}
 class B<K, V> {}''');
-    engine.CompilationUnit unit = resolveLibraryUnit(source);
+    engine.CompilationUnit unit = await resolveLibraryUnit(source);
     {
       engine.ClassElement engineElement = findElementInUnit(unit, '_A');
       // create notification Element
@@ -143,14 +143,14 @@
     }
   }
 
-  void test_fromElement_CONSTRUCTOR() {
+  test_fromElement_CONSTRUCTOR() async {
     engine.Source source = addSource(
         '/test.dart',
         '''
 class A {
   const A.myConstructor(int a, [String b]);
 }''');
-    engine.CompilationUnit unit = resolveLibraryUnit(source);
+    engine.CompilationUnit unit = await resolveLibraryUnit(source);
     engine.ConstructorElement engineElement =
         findElementInUnit(unit, 'myConstructor');
     // create notification Element
@@ -183,14 +183,14 @@
     expect(element.flags, 0);
   }
 
-  void test_fromElement_ENUM() {
+  test_fromElement_ENUM() async {
     engine.Source source = addSource(
         '/test.dart',
         '''
 @deprecated
 enum _E1 { one, two }
 enum E2 { three, four }''');
-    engine.CompilationUnit unit = resolveLibraryUnit(source);
+    engine.CompilationUnit unit = await resolveLibraryUnit(source);
     {
       engine.ClassElement engineElement = findElementInUnit(unit, '_E1');
       expect(engineElement.isDeprecated, isTrue);
@@ -224,14 +224,14 @@
     }
   }
 
-  void test_fromElement_ENUM_CONSTANT() {
+  test_fromElement_ENUM_CONSTANT() async {
     engine.Source source = addSource(
         '/test.dart',
         '''
 @deprecated
 enum _E1 { one, two }
 enum E2 { three, four }''');
-    engine.CompilationUnit unit = resolveLibraryUnit(source);
+    engine.CompilationUnit unit = await resolveLibraryUnit(source);
     {
       engine.FieldElement engineElement = findElementInUnit(unit, 'one');
       // create notification Element
@@ -312,14 +312,14 @@
     }
   }
 
-  void test_fromElement_FIELD() {
+  test_fromElement_FIELD() async {
     engine.Source source = addSource(
         '/test.dart',
         '''
 class A {
   static const myField = 42;
 }''');
-    engine.CompilationUnit unit = resolveLibraryUnit(source);
+    engine.CompilationUnit unit = await resolveLibraryUnit(source);
     engine.FieldElement engineElement = findElementInUnit(unit, 'myField');
     // create notification Element
     Element element = convertElement(engineElement);
@@ -338,13 +338,13 @@
     expect(element.flags, Element.FLAG_CONST | Element.FLAG_STATIC);
   }
 
-  void test_fromElement_FUNCTION_TYPE_ALIAS() {
+  test_fromElement_FUNCTION_TYPE_ALIAS() async {
     engine.Source source = addSource(
         '/test.dart',
         '''
 typedef int F<T>(String x);
 ''');
-    engine.CompilationUnit unit = resolveLibraryUnit(source);
+    engine.CompilationUnit unit = await resolveLibraryUnit(source);
     engine.FunctionTypeAliasElement engineElement =
         findElementInUnit(unit, 'F');
     // create notification Element
@@ -365,14 +365,14 @@
     expect(element.flags, 0);
   }
 
-  void test_fromElement_GETTER() {
+  test_fromElement_GETTER() async {
     engine.Source source = addSource(
         '/test.dart',
         '''
 class A {
   String get myGetter => 42;
 }''');
-    engine.CompilationUnit unit = resolveLibraryUnit(source);
+    engine.CompilationUnit unit = await resolveLibraryUnit(source);
     engine.PropertyAccessorElement engineElement =
         findElementInUnit(unit, 'myGetter', engine.ElementKind.GETTER);
     // create notification Element
@@ -392,7 +392,7 @@
     expect(element.flags, 0);
   }
 
-  void test_fromElement_LABEL() {
+  test_fromElement_LABEL() async {
     engine.Source source = addSource(
         '/test.dart',
         '''
@@ -402,7 +402,7 @@
     break myLabel;
   }
 }''');
-    engine.CompilationUnit unit = resolveLibraryUnit(source);
+    engine.CompilationUnit unit = await resolveLibraryUnit(source);
     engine.LabelElement engineElement = findElementInUnit(unit, 'myLabel');
     // create notification Element
     Element element = convertElement(engineElement);
@@ -421,7 +421,7 @@
     expect(element.flags, 0);
   }
 
-  void test_fromElement_METHOD() {
+  test_fromElement_METHOD() async {
     engine.Source source = addSource(
         '/test.dart',
         '''
@@ -430,7 +430,7 @@
     return null;
   }
 }''');
-    engine.CompilationUnit unit = resolveLibraryUnit(source);
+    engine.CompilationUnit unit = await resolveLibraryUnit(source);
     engine.MethodElement engineElement = findElementInUnit(unit, 'myMethod');
     // create notification Element
     Element element = convertElement(engineElement);
@@ -449,14 +449,14 @@
     expect(element.flags, Element.FLAG_STATIC);
   }
 
-  void test_fromElement_SETTER() {
+  test_fromElement_SETTER() async {
     engine.Source source = addSource(
         '/test.dart',
         '''
 class A {
   set mySetter(String x) {}
 }''');
-    engine.CompilationUnit unit = resolveLibraryUnit(source);
+    engine.CompilationUnit unit = await resolveLibraryUnit(source);
     engine.FieldElement engineFieldElement =
         findElementInUnit(unit, 'mySetter', engine.ElementKind.FIELD);
     engine.PropertyAccessorElement engineElement = engineFieldElement.setter;
diff --git a/pkg/analysis_server/test/services/completion/dart/completion_manager_test.dart b/pkg/analysis_server/test/services/completion/dart/completion_manager_test.dart
index f931c0d..055cfa0 100644
--- a/pkg/analysis_server/test/services/completion/dart/completion_manager_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/completion_manager_test.dart
@@ -54,12 +54,14 @@
     addTestSource('part of libB; main() {^}');
 
     // Associate part with library
-    context.computeResult(libSource, LIBRARY_CYCLE_UNITS);
+    if (!enableNewAnalysisDriver) {
+      context.computeResult(libSource, LIBRARY_CYCLE_UNITS);
+    }
 
     // Build the request
     CompletionRequestImpl baseRequest = new CompletionRequestImpl(
-        null,
-        context,
+        enableNewAnalysisDriver ? await driver.getResult(testFile) : null,
+        enableNewAnalysisDriver ? null : context,
         provider,
         searchEngine,
         testSource,
@@ -78,8 +80,10 @@
     var directives = request.target.unit.directives;
 
     // Assert that the import does not have an export namespace
-    Element element = resolutionMap.elementDeclaredByDirective(directives[0]);
-    expect(element?.library?.exportNamespace, isNull);
+    if (!enableNewAnalysisDriver) {
+      Element element = resolutionMap.elementDeclaredByDirective(directives[0]);
+      expect(element?.library?.exportNamespace, isNull);
+    }
 
     // Resolve directives
     var importCompleter = new Completer<List<ImportElement>>();
@@ -111,11 +115,4 @@
 class CompletionManagerTest_Driver extends CompletionManagerTest {
   @override
   bool get enableNewAnalysisDriver => true;
-
-  @failingTest
-  @override
-  test_resolveDirectives() {
-//    Bad state: Should not be used with the new analysis driver.
-    return super.test_resolveDirectives();
-  }
 }
diff --git a/pkg/analysis_server/test/services/completion/dart/imported_reference_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/imported_reference_contributor_test.dart
index 9f3ce39..954432c 100644
--- a/pkg/analysis_server/test/services/completion/dart/imported_reference_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/imported_reference_contributor_test.dart
@@ -4518,29 +4518,8 @@
   @override
   bool get enableNewAnalysisDriver => true;
 
-  @failingTest
-  @override
-  test_doc_function() {
-    // Bad state: Should not be used with the new analysis driver.
-    return super.test_doc_function();
-  }
-
   @override
   test_enum_deprecated() {
     // TODO(scheglov) remove it?
   }
-
-  @failingTest
-  @override
-  test_doc_class() {
-//    Expected: 'My class.\n'
-//        'Short description.'
-//    Actual: 'My class./// Short description.////// Longer description.'
-//    Which: is different.
-//    Expected: My class.\nShort de ...
-//    Actual: My class./// Short  ...
-//    ^
-//    Differ at offset 9
-    return super.test_doc_class();
-  }
 }
diff --git a/pkg/analysis_server/test/services/completion/dart/uri_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/uri_contributor_test.dart
index 603a1c2..2df2669 100644
--- a/pkg/analysis_server/test/services/completion/dart/uri_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/uri_contributor_test.dart
@@ -468,117 +468,6 @@
 class UriContributorTest_Driver extends UriContributorTest {
   @override
   bool get enableNewAnalysisDriver => true;
-
-  @failingTest
-  @override
-  test_part_file() {
-//    NoSuchMethodError: The getter 'uri' was called on null.
-//    Receiver: null
-//    Tried calling: uri
-//    dart:core                                                       Object.noSuchMethod
-//    package:analyzer/src/summary/resynthesize.dart 233:40           SummaryResynthesizer.getLibraryElement.<fn>
-//    dart:collection                                                 _HashVMBase&MapMixin&&_LinkedHashMapMixin.putIfAbsent
-//    package:analyzer/src/summary/resynthesize.dart 209:36           SummaryResynthesizer.getLibraryElement
-//    package:analyzer/src/summary/package_bundle_reader.dart 206:27  ResynthesizerResultProvider.compute
-//    package:analyzer/src/context/context.dart 573:52                AnalysisContextImpl.aboutToComputeResult.<fn>
-//    package:analyzer/src/generated/utilities_general.dart 189:15    _PerformanceTagImpl.makeCurrentWhile
-//    package:analyzer/src/context/context.dart 571:42                AnalysisContextImpl.aboutToComputeResult
-//    package:analyzer/src/task/driver.dart 746:21                    WorkItem.gatherInputs
-//    package:analyzer/src/task/driver.dart 879:17                    _WorkOrderDependencyWalker.getNextInput
-//    package:analyzer/src/task/driver.dart 414:35                    CycleAwareDependencyWalker.getNextStronglyConnectedComponent
-//    package:analyzer/src/task/driver.dart 845:31                    WorkOrder.moveNext.<fn>
-//    package:analyzer/src/generated/utilities_general.dart 189:15    _PerformanceTagImpl.makeCurrentWhile
-//    package:analyzer/src/task/driver.dart 837:44                    WorkOrder.moveNext
-//    package:analyzer/src/task/driver.dart 108:30                    AnalysisDriver.computeResult
-//    package:analyzer/src/context/context.dart 723:14                AnalysisContextImpl.computeResult
-//    package:analyzer/src/context/context.dart 1292:12               AnalysisContextImpl.resolveCompilationUnit2
-//    package:analyzer/src/dart/analysis/driver.dart 656:56           AnalysisDriver._computeAnalysisResult.<fn>
-//    package:analyzer/src/dart/analysis/driver.dart 1427:15          PerformanceLog.run
-//    package:analyzer/src/dart/analysis/driver.dart 643:20           AnalysisDriver._computeAnalysisResult
-//    package:analyzer/src/dart/analysis/driver.dart 910:33           AnalysisDriver._performWork.<async>
-    return super.test_part_file();
-  }
-
-  @failingTest
-  @override
-  test_part_file2() {
-//    Task failed: BuildCompilationUnitElementTask for source /
-//    Unexpected exception while performing BuildCompilationUnitElementTask for source /
-//    #0      AnalysisTask._safelyPerform (package:analyzer/task/model.dart:333:7)
-//    #1      AnalysisTask.perform (package:analyzer/task/model.dart:220:7)
-//    #2      AnalysisDriver.performWorkItem (package:analyzer/src/task/driver.dart:284:10)
-//    #3      AnalysisDriver.computeResult (package:analyzer/src/task/driver.dart:109:22)
-//    #4      AnalysisContextImpl.computeResult (package:analyzer/src/context/context.dart:723:14)
-//    #5      AnalysisContextImpl.computeErrors (package:analyzer/src/context/context.dart:665:12)
-//    #6      AnalysisDriver._computeAnalysisResult.<anonymous closure> (package:analyzer/src/dart/analysis/driver.dart:658:54)
-//    #7      PerformanceLog.run (package:analyzer/src/dart/analysis/driver.dart:1427:15)
-//    #8      AnalysisDriver._computeAnalysisResult (package:analyzer/src/dart/analysis/driver.dart:643:20)
-//    #9      AnalysisDriver._performWork.<_performWork_async_body> (package:analyzer/src/dart/analysis/driver.dart:910:33)
-//    #10     Future.Future.microtask.<anonymous closure> (dart:async/future.dart:184)
-//    #11     _rootRun (dart:async/zone.dart:1146)
-//    #12     _CustomZone.run (dart:async/zone.dart:1026)
-//    #13     _CustomZone.runGuarded (dart:async/zone.dart:924)
-//    #14     _CustomZone.bindCallback.<anonymous closure> (dart:async/zone.dart:951)
-//    #15     _rootRun (dart:async/zone.dart:1150)
-//    #16     _CustomZone.run (dart:async/zone.dart:1026)
-//    #17     _CustomZone.runGuarded (dart:async/zone.dart:924)
-//    #18     _CustomZone.bindCallback.<anonymous closure> (dart:async/zone.dart:951)
-//    #19     _microtaskLoop (dart:async/schedule_microtask.dart:41)
-//    #20     _startMicrotaskLoop (dart:async/schedule_microtask.dart:50)
-//    #21     _Timer._runTimers (dart:isolate-patch/timer_impl.dart:394)
-//    #22     _Timer._handleMessage (dart:isolate-patch/timer_impl.dart:414)
-//    #23     _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:148)
-//
-//    Caused by Exception: Unit element not found in summary: file:///proj/completion.dart;file:///
-//    #0      SummaryResynthesizer.getElement (package:analyzer/src/summary/resynthesize.dart:124:9)
-//    #1      ResynthesizerResultProvider.compute (package:analyzer/src/summary/package_bundle_reader.dart:265:53)
-//    #2      AnalysisContextImpl.aboutToComputeResult.<anonymous closure> (package:analyzer/src/context/context.dart:573:52)
-//    #3      _PerformanceTagImpl.makeCurrentWhile (package:analyzer/src/generated/utilities_general.dart:189:15)
-//    #4      AnalysisContextImpl.aboutToComputeResult (package:analyzer/src/context/context.dart:571:42)
-//    #5      BuildCompilationUnitElementTask.internalPerform (package:analyzer/src/task/dart.dart:1071:27)
-//    #6      AnalysisTask._safelyPerform (package:analyzer/task/model.dart:321:9)
-//    #7      AnalysisTask.perform (package:analyzer/task/model.dart:220:7)
-//    #8      AnalysisDriver.performWorkItem (package:analyzer/src/task/driver.dart:284:10)
-//    #9      AnalysisDriver.computeResult (package:analyzer/src/task/driver.dart:109:22)
-//    #10     AnalysisContextImpl.computeResult (package:analyzer/src/context/context.dart:723:14)
-//    #11     AnalysisContextImpl.computeErrors (package:analyzer/src/context/context.dart:665:12)
-//    #12     AnalysisDriver._computeAnalysisResult.<anonymous closure> (package:analyzer/src/dart/analysis/driver.dart:658:54)
-//    #13     PerformanceLog.run (package:analyzer/src/dart/analysis/driver.dart:1427:15)
-//    #14     AnalysisDriver._computeAnalysisResult (package:analyzer/src/dart/analysis/driver.dart:643:20)
-//    #15     AnalysisDriver._performWork.<_performWork_async_body> (package:analyzer/src/dart/analysis/driver.dart:910:33)
-//    #16     Future.Future.microtask.<anonymous closure> (dart:async/future.dart:184)
-//    #17     _rootRun (dart:async/zone.dart:1146)
-//    #18     _CustomZone.run (dart:async/zone.dart:1026)
-//    #19     _CustomZone.runGuarded (dart:async/zone.dart:924)
-//    #20     _CustomZone.bindCallback.<anonymous closure> (dart:async/zone.dart:951)
-//    #21     _rootRun (dart:async/zone.dart:1150)
-//    #22     _CustomZone.run (dart:async/zone.dart:1026)
-//    #23     _CustomZone.runGuarded (dart:async/zone.dart:924)
-//    #24     _CustomZone.bindCallback.<anonymous closure> (dart:async/zone.dart:951)
-//    #25     _microtaskLoop (dart:async/schedule_microtask.dart:41)
-//    #26     _startMicrotaskLoop (dart:async/schedule_microtask.dart:50)
-//    #27     _Timer._runTimers (dart:isolate-patch/timer_impl.dart:394)
-//    #28     _Timer._handleMessage (dart:isolate-patch/timer_impl.dart:414)
-//    #29     _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:148)
-//    return super.test_part_file2();
-    fail('Throws background exception.');
-  }
-
-  @failingTest
-  @override
-  test_part_file_child() {
-//    expected foo/bar.dart CompletionSuggestionKind.IMPORT null
-//    found
-    return super.test_part_file_child();
-  }
-
-  @failingTest
-  @override
-  test_part_file_parent() {
-//    expected foo/bar.dart CompletionSuggestionKind.IMPORT null
-//    found
-    return super.test_part_file_parent();
-  }
 }
 
 @reflectiveTest
@@ -751,117 +640,6 @@
 class UriContributorWindowsTest_Driver extends UriContributorWindowsTest {
   @override
   bool get enableNewAnalysisDriver => true;
-
-  @failingTest
-  @override
-  test_part_file() {
-//    NoSuchMethodError: The getter 'uri' was called on null.
-//    Receiver: null
-//    Tried calling: uri
-//    dart:core                                                       Object.noSuchMethod
-//    package:analyzer/src/summary/resynthesize.dart 233:40           SummaryResynthesizer.getLibraryElement.<fn>
-//    dart:collection                                                 _HashVMBase&MapMixin&&_LinkedHashMapMixin.putIfAbsent
-//    package:analyzer/src/summary/resynthesize.dart 209:36           SummaryResynthesizer.getLibraryElement
-//    package:analyzer/src/summary/package_bundle_reader.dart 206:27  ResynthesizerResultProvider.compute
-//    package:analyzer/src/context/context.dart 573:52                AnalysisContextImpl.aboutToComputeResult.<fn>
-//    package:analyzer/src/generated/utilities_general.dart 189:15    _PerformanceTagImpl.makeCurrentWhile
-//    package:analyzer/src/context/context.dart 571:42                AnalysisContextImpl.aboutToComputeResult
-//    package:analyzer/src/task/driver.dart 746:21                    WorkItem.gatherInputs
-//    package:analyzer/src/task/driver.dart 879:17                    _WorkOrderDependencyWalker.getNextInput
-//    package:analyzer/src/task/driver.dart 414:35                    CycleAwareDependencyWalker.getNextStronglyConnectedComponent
-//    package:analyzer/src/task/driver.dart 845:31                    WorkOrder.moveNext.<fn>
-//    package:analyzer/src/generated/utilities_general.dart 189:15    _PerformanceTagImpl.makeCurrentWhile
-//    package:analyzer/src/task/driver.dart 837:44                    WorkOrder.moveNext
-//    package:analyzer/src/task/driver.dart 108:30                    AnalysisDriver.computeResult
-//    package:analyzer/src/context/context.dart 723:14                AnalysisContextImpl.computeResult
-//    package:analyzer/src/context/context.dart 1292:12               AnalysisContextImpl.resolveCompilationUnit2
-//    package:analyzer/src/dart/analysis/driver.dart 656:56           AnalysisDriver._computeAnalysisResult.<fn>
-//    package:analyzer/src/dart/analysis/driver.dart 1427:15          PerformanceLog.run
-//    package:analyzer/src/dart/analysis/driver.dart 643:20           AnalysisDriver._computeAnalysisResult
-//    package:analyzer/src/dart/analysis/driver.dart 910:33           AnalysisDriver._performWork.<async>
-    return super.test_part_file();
-  }
-
-  @failingTest
-  @override
-  test_part_file2() {
-//    Task failed: BuildCompilationUnitElementTask for source /
-//    Unexpected exception while performing BuildCompilationUnitElementTask for source /
-//    #0      AnalysisTask._safelyPerform (package:analyzer/task/model.dart:333:7)
-//    #1      AnalysisTask.perform (package:analyzer/task/model.dart:220:7)
-//    #2      AnalysisDriver.performWorkItem (package:analyzer/src/task/driver.dart:284:10)
-//    #3      AnalysisDriver.computeResult (package:analyzer/src/task/driver.dart:109:22)
-//    #4      AnalysisContextImpl.computeResult (package:analyzer/src/context/context.dart:723:14)
-//    #5      AnalysisContextImpl.computeErrors (package:analyzer/src/context/context.dart:665:12)
-//    #6      AnalysisDriver._computeAnalysisResult.<anonymous closure> (package:analyzer/src/dart/analysis/driver.dart:658:54)
-//    #7      PerformanceLog.run (package:analyzer/src/dart/analysis/driver.dart:1427:15)
-//    #8      AnalysisDriver._computeAnalysisResult (package:analyzer/src/dart/analysis/driver.dart:643:20)
-//    #9      AnalysisDriver._performWork.<_performWork_async_body> (package:analyzer/src/dart/analysis/driver.dart:910:33)
-//    #10     Future.Future.microtask.<anonymous closure> (dart:async/future.dart:184)
-//    #11     _rootRun (dart:async/zone.dart:1146)
-//    #12     _CustomZone.run (dart:async/zone.dart:1026)
-//    #13     _CustomZone.runGuarded (dart:async/zone.dart:924)
-//    #14     _CustomZone.bindCallback.<anonymous closure> (dart:async/zone.dart:951)
-//    #15     _rootRun (dart:async/zone.dart:1150)
-//    #16     _CustomZone.run (dart:async/zone.dart:1026)
-//    #17     _CustomZone.runGuarded (dart:async/zone.dart:924)
-//    #18     _CustomZone.bindCallback.<anonymous closure> (dart:async/zone.dart:951)
-//    #19     _microtaskLoop (dart:async/schedule_microtask.dart:41)
-//    #20     _startMicrotaskLoop (dart:async/schedule_microtask.dart:50)
-//    #21     _Timer._runTimers (dart:isolate-patch/timer_impl.dart:394)
-//    #22     _Timer._handleMessage (dart:isolate-patch/timer_impl.dart:414)
-//    #23     _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:148)
-//
-//    Caused by Exception: Unit element not found in summary: file:///proj/completion.dart;file:///
-//    #0      SummaryResynthesizer.getElement (package:analyzer/src/summary/resynthesize.dart:124:9)
-//    #1      ResynthesizerResultProvider.compute (package:analyzer/src/summary/package_bundle_reader.dart:265:53)
-//    #2      AnalysisContextImpl.aboutToComputeResult.<anonymous closure> (package:analyzer/src/context/context.dart:573:52)
-//    #3      _PerformanceTagImpl.makeCurrentWhile (package:analyzer/src/generated/utilities_general.dart:189:15)
-//    #4      AnalysisContextImpl.aboutToComputeResult (package:analyzer/src/context/context.dart:571:42)
-//    #5      BuildCompilationUnitElementTask.internalPerform (package:analyzer/src/task/dart.dart:1071:27)
-//    #6      AnalysisTask._safelyPerform (package:analyzer/task/model.dart:321:9)
-//    #7      AnalysisTask.perform (package:analyzer/task/model.dart:220:7)
-//    #8      AnalysisDriver.performWorkItem (package:analyzer/src/task/driver.dart:284:10)
-//    #9      AnalysisDriver.computeResult (package:analyzer/src/task/driver.dart:109:22)
-//    #10     AnalysisContextImpl.computeResult (package:analyzer/src/context/context.dart:723:14)
-//    #11     AnalysisContextImpl.computeErrors (package:analyzer/src/context/context.dart:665:12)
-//    #12     AnalysisDriver._computeAnalysisResult.<anonymous closure> (package:analyzer/src/dart/analysis/driver.dart:658:54)
-//    #13     PerformanceLog.run (package:analyzer/src/dart/analysis/driver.dart:1427:15)
-//    #14     AnalysisDriver._computeAnalysisResult (package:analyzer/src/dart/analysis/driver.dart:643:20)
-//    #15     AnalysisDriver._performWork.<_performWork_async_body> (package:analyzer/src/dart/analysis/driver.dart:910:33)
-//    #16     Future.Future.microtask.<anonymous closure> (dart:async/future.dart:184)
-//    #17     _rootRun (dart:async/zone.dart:1146)
-//    #18     _CustomZone.run (dart:async/zone.dart:1026)
-//    #19     _CustomZone.runGuarded (dart:async/zone.dart:924)
-//    #20     _CustomZone.bindCallback.<anonymous closure> (dart:async/zone.dart:951)
-//    #21     _rootRun (dart:async/zone.dart:1150)
-//    #22     _CustomZone.run (dart:async/zone.dart:1026)
-//    #23     _CustomZone.runGuarded (dart:async/zone.dart:924)
-//    #24     _CustomZone.bindCallback.<anonymous closure> (dart:async/zone.dart:951)
-//    #25     _microtaskLoop (dart:async/schedule_microtask.dart:41)
-//    #26     _startMicrotaskLoop (dart:async/schedule_microtask.dart:50)
-//    #27     _Timer._runTimers (dart:isolate-patch/timer_impl.dart:394)
-//    #28     _Timer._handleMessage (dart:isolate-patch/timer_impl.dart:414)
-//    #29     _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:148)
-//    return super.test_part_file2();
-    fail('Throws background exception.');
-  }
-
-  @failingTest
-  @override
-  test_part_file_child() {
-//    expected foo/bar.dart CompletionSuggestionKind.IMPORT null
-//    found
-    return super.test_part_file_child();
-  }
-
-  @failingTest
-  @override
-  test_part_file_parent() {
-//    expected foo/bar.dart CompletionSuggestionKind.IMPORT null
-//    found
-    return super.test_part_file_parent();
-  }
 }
 
 class _TestWinResourceProvider extends MemoryResourceProvider {
diff --git a/pkg/analysis_server/test/services/correction/assist_test.dart b/pkg/analysis_server/test/services/correction/assist_test.dart
index 13d40c2..29ce28a 100644
--- a/pkg/analysis_server/test/services/correction/assist_test.dart
+++ b/pkg/analysis_server/test/services/correction/assist_test.dart
@@ -7,10 +7,14 @@
 import 'dart:async';
 
 import 'package:analysis_server/plugin/edit/assist/assist_core.dart';
+import 'package:analysis_server/plugin/edit/assist/assist_dart.dart';
 import 'package:analysis_server/plugin/protocol/protocol.dart';
 import 'package:analysis_server/src/plugin/server_plugin.dart';
 import 'package:analysis_server/src/services/correction/assist.dart';
+import 'package:analysis_server/src/services/correction/assist_internal.dart';
+import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/ast/standard_resolution_map.dart';
+import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:plugin/manager.dart';
@@ -23,6 +27,7 @@
 main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(AssistProcessorTest);
+    defineReflectiveTests(AssistProcessorTest_Driver);
   });
 }
 
@@ -65,12 +70,7 @@
    * Asserts that there is no [Assist] of the given [kind] at [offset].
    */
   assertNoAssist(AssistKind kind) async {
-    List<Assist> assists = await computeAssists(
-        plugin,
-        context,
-        resolutionMap.elementDeclaredByCompilationUnit(testUnit).source,
-        offset,
-        length);
+    List<Assist> assists = await _computeAssists();
     for (Assist assist in assists) {
       if (assist.kind == kind) {
         throw fail('Unexpected assist $kind in\n${assists.join('\n')}');
@@ -132,7 +132,7 @@
 class _B extends A {}
 foo(f(_B p)) {}
 ''');
-    resolveTestUnit('''
+    await resolveTestUnit('''
 import 'my_lib.dart';
 main() {
   foo((test) {});
@@ -150,7 +150,7 @@
 class _B extends A {}
 List<_B> getValues() => [];
 ''');
-    resolveTestUnit('''
+    await resolveTestUnit('''
 import 'my_lib.dart';
 class A<T> {
   main() {
@@ -171,7 +171,7 @@
 class _B extends A {}
 List<_B> getValues() => [];
 ''');
-    resolveTestUnit('''
+    await resolveTestUnit('''
 import 'my_lib.dart';
 main() {
   var v = getValues();
@@ -189,7 +189,7 @@
 class _B extends A {}
 _B getValue() => new _B();
 ''');
-    resolveTestUnit('''
+    await resolveTestUnit('''
 import 'my_lib.dart';
 main() {
   var v = getValue();
@@ -199,7 +199,7 @@
   }
 
   test_addTypeAnnotation_classField_OK_final() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class A {
   final f = 0;
 }
@@ -215,7 +215,7 @@
   }
 
   test_addTypeAnnotation_classField_OK_int() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class A {
   var f = 0;
 }
@@ -231,7 +231,7 @@
   }
 
   test_addTypeAnnotation_declaredIdentifier_BAD_hasTypeAnnotation() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main(List<String> items) {
   for (String item in items) {
   }
@@ -241,7 +241,7 @@
   }
 
   test_addTypeAnnotation_declaredIdentifier_BAD_inForEachBody() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main(List<String> items) {
   for (var item in items) {
     42;
@@ -253,7 +253,7 @@
 
   test_addTypeAnnotation_declaredIdentifier_BAD_unknownType() async {
     verifyNoTestUnitErrors = false;
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   for (var item in unknownList) {
   }
@@ -263,7 +263,7 @@
   }
 
   test_addTypeAnnotation_declaredIdentifier_generic_OK() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class A<T> {
   main(List<List<T>> items) {
     for (var item in items) {
@@ -285,7 +285,7 @@
   }
 
   test_addTypeAnnotation_declaredIdentifier_OK() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main(List<String> items) {
   for (var item in items) {
   }
@@ -320,7 +320,7 @@
 import 'dart:async';
 List<Future<int>> getFutures() => null;
 ''');
-    resolveTestUnit('''
+    await resolveTestUnit('''
 import 'my_lib.dart';
 main() {
   for (var future in getFutures()) {
@@ -341,7 +341,7 @@
   }
 
   test_addTypeAnnotation_declaredIdentifier_OK_final() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main(List<String> items) {
   for (final item in items) {
   }
@@ -359,7 +359,7 @@
   }
 
   test_addTypeAnnotation_local_BAD_hasTypeAnnotation() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   int v = 42;
 }
@@ -368,7 +368,7 @@
   }
 
   test_addTypeAnnotation_local_BAD_multiple() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   var a = 1, b = '';
 }
@@ -378,7 +378,7 @@
 
   test_addTypeAnnotation_local_BAD_noValue() async {
     verifyNoTestUnitErrors = false;
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   var v;
 }
@@ -387,7 +387,7 @@
   }
 
   test_addTypeAnnotation_local_BAD_null() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   var v = null;
 }
@@ -396,7 +396,7 @@
   }
 
   test_addTypeAnnotation_local_BAD_onInitializer() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   var abc = 0;
 }
@@ -406,7 +406,7 @@
 
   test_addTypeAnnotation_local_BAD_unknown() async {
     verifyNoTestUnitErrors = false;
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   var v = unknownVar;
 }
@@ -415,7 +415,7 @@
   }
 
   test_addTypeAnnotation_local_generic_OK_literal() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class A {
   main(List<int> items) {
     var v = items;
@@ -435,7 +435,7 @@
   }
 
   test_addTypeAnnotation_local_generic_OK_local() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class A<T> {
   main(List<T> items) {
     var v = items;
@@ -461,7 +461,7 @@
 import 'dart:async';
 Future<int> getFutureInt() => null;
 ''');
-    resolveTestUnit('''
+    await resolveTestUnit('''
 import 'my_lib.dart';
 main() {
   var v = getFutureInt();
@@ -503,11 +503,14 @@
     Source appSource = addSource('/app.dart', appCode);
     testSource = addSource('/test.dart', testCode);
     // resolve
-    context.resolveCompilationUnit2(appSource, appSource);
-    testUnit = context.resolveCompilationUnit2(testSource, appSource);
-    assertNoErrorsInSource(testSource);
-    testUnitElement = testUnit.element;
-    testLibraryElement = testUnitElement.library;
+    if (enableNewAnalysisDriver) {
+      await resolveTestUnit(testCode);
+    } else {
+      context.resolveCompilationUnit2(appSource, appSource);
+      testUnit = context.resolveCompilationUnit2(testSource, appSource);
+      testUnitElement = testUnit.element;
+      testLibraryElement = testUnitElement.library;
+    }
     // prepare the assist
     offset = findOffset('v = ');
     assist = await _assertHasAssist(DartAssistKind.ADD_TYPE_ANNOTATION);
@@ -551,7 +554,7 @@
 import '../aa/bbb/lib_a.dart';
 MyClass newMyClass() => null;
 ''');
-    resolveTestUnit('''
+    await resolveTestUnit('''
 import 'ccc/lib_b.dart';
 main() {
   var v = newMyClass();
@@ -570,7 +573,7 @@
   }
 
   test_addTypeAnnotation_local_OK_Function() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   var v = () => 1;
 }
@@ -586,7 +589,7 @@
   }
 
   test_addTypeAnnotation_local_OK_int() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   var v = 0;
 }
@@ -602,7 +605,7 @@
   }
 
   test_addTypeAnnotation_local_OK_List() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   var v = <String>[];
 }
@@ -618,7 +621,7 @@
   }
 
   test_addTypeAnnotation_local_OK_localType() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class C {}
 C f() => null;
 main() {
@@ -638,7 +641,7 @@
   }
 
   test_addTypeAnnotation_local_OK_onName() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   var abc = 0;
 }
@@ -654,7 +657,7 @@
   }
 
   test_addTypeAnnotation_local_OK_onVar() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   var v = 0;
 }
@@ -670,7 +673,7 @@
   }
 
   test_addTypeAnnotation_OK_privateType_sameLibrary() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class _A {}
 _A getValue() => new _A();
 main() {
@@ -690,7 +693,7 @@
   }
 
   test_addTypeAnnotation_parameter_BAD_hasExplicitType() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 foo(f(int p)) {}
 main() {
   foo((num test) {});
@@ -700,7 +703,7 @@
   }
 
   test_addTypeAnnotation_parameter_BAD_noPropagatedType() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 foo(f(p)) {}
 main() {
   foo((test) {});
@@ -710,7 +713,7 @@
   }
 
   test_addTypeAnnotation_parameter_OK() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 foo(f(int p)) {}
 main() {
   foo((test) {});
@@ -728,21 +731,21 @@
   }
 
   test_addTypeAnnotation_topLevelField_BAD_multiple() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 var A = 1, V = '';
 ''');
     await assertNoAssistAt('var ', DartAssistKind.ADD_TYPE_ANNOTATION);
   }
 
   test_addTypeAnnotation_topLevelField_BAD_noValue() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 var V;
 ''');
     await assertNoAssistAt('var ', DartAssistKind.ADD_TYPE_ANNOTATION);
   }
 
   test_addTypeAnnotation_topLevelField_OK_int() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 var V = 0;
 ''');
     await assertHasAssistAt(
@@ -754,7 +757,7 @@
   }
 
   test_assignToLocalVariable() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   List<int> bytes;
   readBytes();
@@ -779,7 +782,7 @@
   }
 
   test_assignToLocalVariable_alreadyAssignment() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   var vvv;
   vvv = 42;
@@ -789,7 +792,7 @@
   }
 
   test_assignToLocalVariable_inClosure() async {
-    resolveTestUnit(r'''
+    await resolveTestUnit(r'''
 main() {
   print(() {
     12345;
@@ -809,17 +812,17 @@
   }
 
   test_assignToLocalVariable_invocationArgument() async {
-    resolveTestUnit(r'''
+    await resolveTestUnit(r'''
 main() {
   f(12345);
 }
-int f(p) {}
+void f(p) {}
 ''');
     await assertNoAssistAt('345', DartAssistKind.ASSIGN_TO_LOCAL_VARIABLE);
   }
 
   test_assignToLocalVariable_throw() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   throw 42;
 }
@@ -828,7 +831,7 @@
   }
 
   test_assignToLocalVariable_void() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   f();
 }
@@ -838,7 +841,7 @@
   }
 
   test_convertDocumentationIntoBlock_BAD_alreadyBlock() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 /**
  * AAAAAAA
  */
@@ -849,7 +852,7 @@
   }
 
   test_convertDocumentationIntoBlock_BAD_notDocumentation() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 // AAAA
 class A {}
 ''');
@@ -858,7 +861,7 @@
   }
 
   test_convertDocumentationIntoBlock_OK_noSpaceBeforeText() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class A {
   /// AAAAA
   ///BBBBB
@@ -884,7 +887,7 @@
   }
 
   test_convertDocumentationIntoBlock_OK_onReference() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 /// AAAAAAA [int] AAAAAAA
 class A {}
 ''');
@@ -900,7 +903,7 @@
   }
 
   test_convertDocumentationIntoBlock_OK_onText() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class A {
   /// AAAAAAA [int] AAAAAAA
   /// BBBBBBBB BBBB BBBB
@@ -924,7 +927,7 @@
   }
 
   test_convertDocumentationIntoLine_BAD_alreadyLine() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 /// AAAAAAA
 class A {}
 ''');
@@ -933,7 +936,7 @@
   }
 
   test_convertDocumentationIntoLine_BAD_notDocumentation() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 /* AAAA */
 class A {}
 ''');
@@ -942,7 +945,7 @@
   }
 
   test_convertDocumentationIntoLine_OK_onReference() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 /**
  * AAAAAAA [int] AAAAAAA
  */
@@ -958,7 +961,7 @@
   }
 
   test_convertDocumentationIntoLine_OK_onText() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class A {
   /**
    * AAAAAAA [int] AAAAAAA
@@ -982,7 +985,7 @@
   }
 
   test_convertDocumentationIntoLine_OK_onText_hasFirstLine() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class A {
   /** AAAAAAA [int] AAAAAAA
    * BBBBBBBB BBBB BBBB
@@ -1005,14 +1008,14 @@
   }
 
   test_convertToBlockBody_BAD_noEnclosingFunction() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 var v = 123;
 ''');
     await assertNoAssistAt('v =', DartAssistKind.CONVERT_INTO_BLOCK_BODY);
   }
 
   test_convertToBlockBody_BAD_notExpressionBlock() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 fff() {
   return 123;
 }
@@ -1021,7 +1024,7 @@
   }
 
   test_convertToBlockBody_OK_async() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class A {
   mmm() async => 123;
 }
@@ -1039,7 +1042,7 @@
   }
 
   test_convertToBlockBody_OK_closure() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 setup(x) {}
 main() {
   setup(() => 42);
@@ -1065,7 +1068,7 @@
   }
 
   test_convertToBlockBody_OK_closure_voidExpression() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 setup(x) {}
 main() {
   setup(() => print('done'));
@@ -1091,7 +1094,7 @@
   }
 
   test_convertToBlockBody_OK_constructor() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class A {
   factory A() => null;
 }
@@ -1109,7 +1112,7 @@
   }
 
   test_convertToBlockBody_OK_method() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class A {
   mmm() => 123;
 }
@@ -1127,7 +1130,7 @@
   }
 
   test_convertToBlockBody_OK_onName() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 fff() => 123;
 ''');
     await assertHasAssistAt(
@@ -1141,7 +1144,7 @@
   }
 
   test_convertToBlockBody_OK_onValue() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 fff() => 123;
 ''');
     await assertHasAssistAt(
@@ -1155,7 +1158,7 @@
   }
 
   test_convertToExpressionBody_BAD_already() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 fff() => 42;
 ''');
     await assertNoAssistAt(
@@ -1163,7 +1166,7 @@
   }
 
   test_convertToExpressionBody_BAD_moreThanOneStatement() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 fff() {
   var v = 42;
   return v;
@@ -1174,14 +1177,14 @@
   }
 
   test_convertToExpressionBody_BAD_noEnclosingFunction() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 var V = 42;
 ''');
     await assertNoAssistAt('V = ', DartAssistKind.CONVERT_INTO_EXPRESSION_BODY);
   }
 
   test_convertToExpressionBody_BAD_noReturn() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 fff() {
   var v = 42;
 }
@@ -1191,7 +1194,7 @@
   }
 
   test_convertToExpressionBody_BAD_noReturnValue() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 fff() {
   return;
 }
@@ -1201,7 +1204,7 @@
   }
 
   test_convertToExpressionBody_OK_async() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class A {
   mmm() async {
     return 42;
@@ -1219,7 +1222,7 @@
   }
 
   test_convertToExpressionBody_OK_closure() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 setup(x) {}
 main() {
   setup(() {
@@ -1239,7 +1242,7 @@
   }
 
   test_convertToExpressionBody_OK_closure_voidExpression() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 setup(x) {}
 main() {
   setup(() {
@@ -1259,7 +1262,7 @@
   }
 
   test_convertToExpressionBody_OK_constructor() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class A {
   factory A() {
     return null;
@@ -1277,7 +1280,7 @@
   }
 
   test_convertToExpressionBody_OK_function_onBlock() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 fff() {
   return 42;
 }
@@ -1291,7 +1294,7 @@
   }
 
   test_convertToExpressionBody_OK_function_onName() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 fff() {
   return 42;
 }
@@ -1305,7 +1308,7 @@
   }
 
   test_convertToExpressionBody_OK_method_onBlock() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class A {
   m() { // marker
     return 42;
@@ -1323,7 +1326,7 @@
   }
 
   test_convertToExpressionBody_OK_topFunction_onReturnStatement() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 fff() {
   return 42;
 }
@@ -1337,7 +1340,7 @@
   }
 
   test_convertToFieldParameter_BAD_additionalUse() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class A {
   int aaa2;
   int bbb2;
@@ -1348,7 +1351,7 @@
   }
 
   test_convertToFieldParameter_BAD_notPureAssignment() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class A {
   int aaa2;
   A(int aaa) : aaa2 = aaa * 2;
@@ -1358,9 +1361,9 @@
   }
 
   test_convertToFieldParameter_OK_firstInitializer() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class A {
-  double aaa2;
+  int aaa2;
   int bbb2;
   A(int aaa, int bbb) : aaa2 = aaa, bbb2 = bbb;
 }
@@ -1370,7 +1373,7 @@
         DartAssistKind.CONVERT_TO_FIELD_PARAMETER,
         '''
 class A {
-  double aaa2;
+  int aaa2;
   int bbb2;
   A(this.aaa2, int bbb) : bbb2 = bbb;
 }
@@ -1378,7 +1381,7 @@
   }
 
   test_convertToFieldParameter_OK_onParameterName_inInitializer() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class A {
   int test2;
   A(int test) : test2 = test {
@@ -1398,7 +1401,7 @@
   }
 
   test_convertToFieldParameter_OK_onParameterName_inParameters() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class A {
   int test;
   A(int test) : test = test {
@@ -1418,9 +1421,9 @@
   }
 
   test_convertToFieldParameter_OK_secondInitializer() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class A {
-  double aaa2;
+  int aaa2;
   int bbb2;
   A(int aaa, int bbb) : aaa2 = aaa, bbb2 = bbb;
 }
@@ -1430,7 +1433,7 @@
         DartAssistKind.CONVERT_TO_FIELD_PARAMETER,
         '''
 class A {
-  double aaa2;
+  int aaa2;
   int bbb2;
   A(int aaa, this.bbb2) : aaa2 = aaa;
 }
@@ -1438,7 +1441,7 @@
   }
 
   test_convertToFinalField_BAD_hasSetter_inThisClass() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class A {
   int get foo => null;
   void set foo(_) {}
@@ -1448,7 +1451,7 @@
   }
 
   test_convertToFinalField_BAD_notExpressionBody() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class A {
   int get foo {
     int v = 1 + 2;
@@ -1460,7 +1463,7 @@
   }
 
   test_convertToFinalField_BAD_notGetter() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class A {
   int foo() => 42;
 }
@@ -1469,7 +1472,7 @@
   }
 
   test_convertToFinalField_OK_blockBody_onlyReturnStatement() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class A {
   int get foo {
     return 1 + 2;
@@ -1487,7 +1490,7 @@
   }
 
   test_convertToFinalField_OK_hasOverride() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 const myAnnotation = const Object();
 class A {
   @myAnnotation
@@ -1507,7 +1510,7 @@
   }
 
   test_convertToFinalField_OK_hasSetter_inSuper() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class A {
   void set foo(_) {}
 }
@@ -1529,7 +1532,7 @@
   }
 
   test_convertToFinalField_OK_notNull() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class A {
   int get foo => 1 + 2;
 }
@@ -1545,7 +1548,7 @@
   }
 
   test_convertToFinalField_OK_null() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class A {
   int get foo => null;
 }
@@ -1561,7 +1564,7 @@
   }
 
   test_convertToFinalField_OK_onName() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class A {
   int get foo => 42;
 }
@@ -1577,7 +1580,7 @@
   }
 
   test_convertToFinalField_OK_onReturnType_parameterized() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class A {
   List<int> get foo => null;
 }
@@ -1593,7 +1596,7 @@
   }
 
   test_convertToFinalField_OK_onReturnType_simple() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class A {
   int get foo => 42;
 }
@@ -1609,7 +1612,7 @@
   }
 
   test_convertToForIndex_BAD_bodyNotBlock() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main(List<String> items) {
   for (String item in items) print(item);
 }
@@ -1619,7 +1622,7 @@
   }
 
   test_convertToForIndex_BAD_doesNotDeclareVariable() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main(List<String> items) {
   String item;
   for (item in items) {
@@ -1631,7 +1634,7 @@
   }
 
   test_convertToForIndex_BAD_iterableIsNotVariable() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   for (String item in ['a', 'b', 'c']) {
     print(item);
@@ -1643,7 +1646,7 @@
   }
 
   test_convertToForIndex_BAD_iterableNotList() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main(Iterable<String> items) {
   for (String item in items) {
     print(item);
@@ -1655,7 +1658,7 @@
   }
 
   test_convertToForIndex_BAD_usesIJK() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main(List<String> items) {
   for (String item in items) {
     print(item);
@@ -1668,7 +1671,7 @@
   }
 
   test_convertToForIndex_OK_onDeclaredIdentifier_name() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main(List<String> items) {
   for (String item in items) {
     print(item);
@@ -1689,7 +1692,7 @@
   }
 
   test_convertToForIndex_OK_onDeclaredIdentifier_type() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main(List<String> items) {
   for (String item in items) {
     print(item);
@@ -1710,7 +1713,7 @@
   }
 
   test_convertToForIndex_OK_onFor() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main(List<String> items) {
   for (String item in items) {
     print(item);
@@ -1731,7 +1734,7 @@
   }
 
   test_convertToForIndex_OK_usesI() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main(List<String> items) {
   for (String item in items) {
     int i = 0;
@@ -1752,7 +1755,7 @@
   }
 
   test_convertToForIndex_OK_usesIJ() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main(List<String> items) {
   for (String item in items) {
     print(item);
@@ -1775,7 +1778,8 @@
   }
 
   test_convertToGetter_BAD_noInitializer() async {
-    resolveTestUnit('''
+    verifyNoTestUnitErrors = false;
+    await resolveTestUnit('''
 class A {
   final int foo;
 }
@@ -1784,7 +1788,7 @@
   }
 
   test_convertToGetter_BAD_notFinal() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class A {
   int foo = 1;
 }
@@ -1793,7 +1797,7 @@
   }
 
   test_convertToGetter_BAD_notSingleField() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class A {
   final int foo = 1, bar = 2;
 }
@@ -1802,7 +1806,7 @@
   }
 
   test_convertToGetter_OK() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 const myAnnotation = const Object();
 class A {
   @myAnnotation
@@ -1822,7 +1826,7 @@
   }
 
   test_convertToGetter_OK_noType() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class A {
   final foo = 42;
 }
@@ -1838,7 +1842,7 @@
   }
 
   test_convertToIsNot_BAD_is_alreadyIsNot() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main(p) {
   p is! String;
 }
@@ -1847,7 +1851,7 @@
   }
 
   test_convertToIsNot_BAD_is_noEnclosingParenthesis() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main(p) {
   p is String;
 }
@@ -1856,7 +1860,7 @@
   }
 
   test_convertToIsNot_BAD_is_noPrefix() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main(p) {
   (p is String);
 }
@@ -1865,7 +1869,7 @@
   }
 
   test_convertToIsNot_BAD_is_notIsExpression() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main(p) {
   123 + 456;
 }
@@ -1875,7 +1879,7 @@
 
   test_convertToIsNot_BAD_is_notTheNotOperator() async {
     verifyNoTestUnitErrors = false;
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main(p) {
   ++(p is String);
 }
@@ -1884,7 +1888,7 @@
   }
 
   test_convertToIsNot_BAD_not_alreadyIsNot() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main(p) {
   !(p is! String);
 }
@@ -1893,7 +1897,7 @@
   }
 
   test_convertToIsNot_BAD_not_noEnclosingParenthesis() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main(p) {
   !p;
 }
@@ -1902,7 +1906,7 @@
   }
 
   test_convertToIsNot_BAD_not_notIsExpression() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main(p) {
   !(p == null);
 }
@@ -1912,7 +1916,7 @@
 
   test_convertToIsNot_BAD_not_notTheNotOperator() async {
     verifyNoTestUnitErrors = false;
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main(p) {
   ++(p is String);
 }
@@ -1921,7 +1925,7 @@
   }
 
   test_convertToIsNot_OK_childOfIs_left() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main(p) {
   !(p is String);
 }
@@ -1937,7 +1941,7 @@
   }
 
   test_convertToIsNot_OK_childOfIs_right() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main(p) {
   !(p is String);
 }
@@ -1953,7 +1957,7 @@
   }
 
   test_convertToIsNot_OK_is() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main(p) {
   !(p is String);
 }
@@ -1969,7 +1973,7 @@
   }
 
   test_convertToIsNot_OK_is_higherPrecedencePrefix() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main(p) {
   !!(p is String);
 }
@@ -1985,7 +1989,7 @@
   }
 
   test_convertToIsNot_OK_is_not_higherPrecedencePrefix() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main(p) {
   !!(p is String);
 }
@@ -2001,7 +2005,7 @@
   }
 
   test_convertToIsNot_OK_not() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main(p) {
   !(p is String);
 }
@@ -2017,7 +2021,7 @@
   }
 
   test_convertToIsNot_OK_parentheses() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main(p) {
   !(p is String);
 }
@@ -2034,7 +2038,7 @@
 
   test_convertToIsNotEmpty_BAD_noBang() async {
     verifyNoTestUnitErrors = false;
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main(String str) {
   ~str.isEmpty;
 }
@@ -2044,7 +2048,7 @@
   }
 
   test_convertToIsNotEmpty_BAD_noIsNotEmpty() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class A {
   bool get isEmpty => false;
 }
@@ -2057,7 +2061,7 @@
   }
 
   test_convertToIsNotEmpty_BAD_notInPrefixExpression() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main(String str) {
   str.isEmpty;
 }
@@ -2067,7 +2071,7 @@
   }
 
   test_convertToIsNotEmpty_BAD_notIsEmpty() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main(int p) {
   !p.isEven;
 }
@@ -2076,7 +2080,7 @@
   }
 
   test_convertToIsNotEmpty_OK_on_isEmpty() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main(String str) {
   !str.isEmpty;
 }
@@ -2092,7 +2096,7 @@
   }
 
   test_convertToIsNotEmpty_OK_on_str() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main(String str) {
   !str.isEmpty;
 }
@@ -2108,7 +2112,7 @@
   }
 
   test_convertToIsNotEmpty_OK_propertyAccess() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main(String str) {
   !'text'.isEmpty;
 }
@@ -2124,7 +2128,7 @@
   }
 
   test_convertToNormalParameter_OK_dynamic() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class A {
   var test;
   A(this.test) {
@@ -2144,7 +2148,7 @@
   }
 
   test_convertToNormalParameter_OK_firstInitializer() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class A {
   int test;
   A(this.test) {
@@ -2164,7 +2168,7 @@
   }
 
   test_convertToNormalParameter_OK_secondInitializer() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class A {
   double aaa;
   int bbb;
@@ -2184,7 +2188,7 @@
   }
 
   test_encapsulateField_BAD_alreadyPrivate() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class A {
   int _test = 42;
 }
@@ -2196,7 +2200,7 @@
   }
 
   test_encapsulateField_BAD_final() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class A {
   final int test = 42;
 }
@@ -2205,7 +2209,7 @@
   }
 
   test_encapsulateField_BAD_multipleFields() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class A {
   int aaa, bbb, ccc;
 }
@@ -2217,7 +2221,7 @@
   }
 
   test_encapsulateField_BAD_notOnName() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class A {
   int test = 1 + 2 + 3;
 }
@@ -2227,7 +2231,7 @@
 
   test_encapsulateField_BAD_parseError() async {
     verifyNoTestUnitErrors = false;
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class A {
   int; // marker
 }
@@ -2239,7 +2243,7 @@
   }
 
   test_encapsulateField_BAD_static() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class A {
   static int test = 42;
 }
@@ -2248,7 +2252,7 @@
   }
 
   test_encapsulateField_OK_hasType() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class A {
   int test = 42;
   A(this.test);
@@ -2278,7 +2282,7 @@
   }
 
   test_encapsulateField_OK_noType() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class A {
   var test = 42;
 }
@@ -2306,7 +2310,7 @@
   }
 
   test_exchangeBinaryExpressionArguments_BAD_extraLength() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   111 + 222;
 }
@@ -2316,7 +2320,7 @@
   }
 
   test_exchangeBinaryExpressionArguments_BAD_onOperand() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   111 + 222;
 }
@@ -2326,7 +2330,7 @@
   }
 
   test_exchangeBinaryExpressionArguments_BAD_selectionWithBinary() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   1 + 2 + 3;
 }
@@ -2341,7 +2345,7 @@
     for (int i = 0; i <= 0; i++) {
       String initialOperator = initialOperators[i];
       String resultOperator = resultOperators[i];
-      resolveTestUnit('''
+      await resolveTestUnit('''
 bool main(int a, int b) {
   return a $initialOperator b;
 }
@@ -2358,7 +2362,7 @@
   }
 
   test_exchangeBinaryExpressionArguments_OK_extended_mixOperator_1() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   1 * 2 * 3 + 4;
 }
@@ -2374,7 +2378,7 @@
   }
 
   test_exchangeBinaryExpressionArguments_OK_extended_mixOperator_2() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   1 + 2 - 3 + 4;
 }
@@ -2390,7 +2394,7 @@
   }
 
   test_exchangeBinaryExpressionArguments_OK_extended_sameOperator_afterFirst() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   1 + 2 + 3;
 }
@@ -2406,7 +2410,7 @@
   }
 
   test_exchangeBinaryExpressionArguments_OK_extended_sameOperator_afterSecond() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   1 + 2 + 3;
 }
@@ -2422,7 +2426,7 @@
   }
 
   test_exchangeBinaryExpressionArguments_OK_simple_afterOperator() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   1 + 2;
 }
@@ -2438,7 +2442,7 @@
   }
 
   test_exchangeBinaryExpressionArguments_OK_simple_beforeOperator() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   1 + 2;
 }
@@ -2454,7 +2458,7 @@
   }
 
   test_exchangeBinaryExpressionArguments_OK_simple_fullSelection() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   1 + 2;
 }
@@ -2471,7 +2475,7 @@
   }
 
   test_exchangeBinaryExpressionArguments_OK_simple_withLength() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   1 + 2;
 }
@@ -2488,7 +2492,7 @@
   }
 
   test_importAddShow_BAD_hasShow() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 import 'dart:math' show PI;
 main() {
   PI;
@@ -2498,21 +2502,22 @@
   }
 
   test_importAddShow_BAD_unresolvedUri() async {
-    resolveTestUnit('''
+    verifyNoTestUnitErrors = false;
+    await resolveTestUnit('''
 import '/no/such/lib.dart';
 ''');
     await assertNoAssistAt('import ', DartAssistKind.IMPORT_ADD_SHOW);
   }
 
   test_importAddShow_BAD_unused() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 import 'dart:math';
 ''');
     await assertNoAssistAt('import ', DartAssistKind.IMPORT_ADD_SHOW);
   }
 
   test_importAddShow_OK_hasUnresolvedIdentifier() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 import 'dart:math';
 main(x) {
   PI;
@@ -2532,7 +2537,7 @@
   }
 
   test_importAddShow_OK_onDirective() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 import 'dart:math';
 main() {
   PI;
@@ -2554,7 +2559,7 @@
   }
 
   test_importAddShow_OK_onUri() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 import 'dart:math';
 main() {
   PI;
@@ -2576,7 +2581,7 @@
   }
 
   test_introduceLocalTestedType_BAD_notBlock() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main(p) {
   if (p is String)
     print('not a block');
@@ -2586,7 +2591,7 @@
   }
 
   test_introduceLocalTestedType_BAD_notIsExpression() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main(p) {
   if (p == null) {
   }
@@ -2596,7 +2601,7 @@
   }
 
   test_introduceLocalTestedType_BAD_notStatement() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class C {
   bool b;
   C(v) : b = v is int;
@@ -2605,7 +2610,7 @@
   }
 
   test_introduceLocalTestedType_OK_if_is() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class MyTypeName {}
 main(p) {
   if (p is MyTypeName) {
@@ -2635,7 +2640,7 @@
   }
 
   test_introduceLocalTestedType_OK_if_isNot() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class MyTypeName {}
 main(p) {
   if (p is! MyTypeName) {
@@ -2665,7 +2670,7 @@
   }
 
   test_introduceLocalTestedType_OK_while() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main(p) {
   while (p is String) {
   }
@@ -2687,14 +2692,15 @@
   }
 
   test_invalidSelection() async {
-    resolveTestUnit('');
-    List<Assist> assists = await computeAssists(plugin, context,
-        resolutionMap.elementDeclaredByCompilationUnit(testUnit).source, -1, 0);
+    await resolveTestUnit('');
+    offset = -1;
+    length = 0;
+    List<Assist> assists = await _computeAssists();
     expect(assists, isEmpty);
   }
 
   test_invertIfStatement_blocks() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   if (true) {
     0;
@@ -2718,7 +2724,7 @@
   }
 
   test_invertIfStatement_statements() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   if (true)
     0;
@@ -2740,7 +2746,7 @@
   }
 
   test_joinIfStatementInner_BAD_innerNotIf() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   if (1 == 1) {
     print(0);
@@ -2751,7 +2757,7 @@
   }
 
   test_joinIfStatementInner_BAD_innerWithElse() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   if (1 == 1) {
     if (2 == 2) {
@@ -2766,7 +2772,7 @@
   }
 
   test_joinIfStatementInner_BAD_statementAfterInner() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   if (1 == 1) {
     if (2 == 2) {
@@ -2780,7 +2786,7 @@
   }
 
   test_joinIfStatementInner_BAD_statementBeforeInner() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   if (1 == 1) {
     print(1);
@@ -2794,7 +2800,7 @@
   }
 
   test_joinIfStatementInner_BAD_targetNotIf() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   print(0);
 }
@@ -2803,7 +2809,7 @@
   }
 
   test_joinIfStatementInner_BAD_targetWithElse() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   if (1 == 1) {
     if (2 == 2) {
@@ -2818,7 +2824,7 @@
   }
 
   test_joinIfStatementInner_OK_conditionAndOr() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   if (1 == 1) {
     if (2 == 2 || 3 == 3) {
@@ -2840,7 +2846,7 @@
   }
 
   test_joinIfStatementInner_OK_conditionInvocation() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   if (isCheck()) {
     if (2 == 2) {
@@ -2864,7 +2870,7 @@
   }
 
   test_joinIfStatementInner_OK_conditionOrAnd() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   if (1 == 1 || 2 == 2) {
     if (3 == 3) {
@@ -2886,7 +2892,7 @@
   }
 
   test_joinIfStatementInner_OK_onCondition() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   if (1 == 1) {
     if (2 == 2) {
@@ -2908,7 +2914,7 @@
   }
 
   test_joinIfStatementInner_OK_simpleConditions_block_block() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   if (1 == 1) {
     if (2 == 2) {
@@ -2930,7 +2936,7 @@
   }
 
   test_joinIfStatementInner_OK_simpleConditions_block_single() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   if (1 == 1) {
     if (2 == 2)
@@ -2951,7 +2957,7 @@
   }
 
   test_joinIfStatementInner_OK_simpleConditions_single_blockMulti() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   if (1 == 1) {
     if (2 == 2) {
@@ -2977,7 +2983,7 @@
   }
 
   test_joinIfStatementInner_OK_simpleConditions_single_blockOne() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   if (1 == 1)
     if (2 == 2) {
@@ -2998,7 +3004,7 @@
   }
 
   test_joinIfStatementOuter_BAD_outerNotIf() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   if (1 == 1) {
     print(0);
@@ -3009,7 +3015,7 @@
   }
 
   test_joinIfStatementOuter_BAD_outerWithElse() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   if (1 == 1) {
     if (2 == 2) {
@@ -3024,7 +3030,7 @@
   }
 
   test_joinIfStatementOuter_BAD_statementAfterInner() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   if (1 == 1) {
     if (2 == 2) {
@@ -3038,7 +3044,7 @@
   }
 
   test_joinIfStatementOuter_BAD_statementBeforeInner() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   if (1 == 1) {
     print(1);
@@ -3052,7 +3058,7 @@
   }
 
   test_joinIfStatementOuter_BAD_targetNotIf() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   print(0);
 }
@@ -3061,7 +3067,7 @@
   }
 
   test_joinIfStatementOuter_BAD_targetWithElse() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   if (1 == 1) {
     if (2 == 2) {
@@ -3076,7 +3082,7 @@
   }
 
   test_joinIfStatementOuter_OK_conditionAndOr() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   if (1 == 1) {
     if (2 == 2 || 3 == 3) {
@@ -3098,7 +3104,7 @@
   }
 
   test_joinIfStatementOuter_OK_conditionInvocation() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   if (1 == 1) {
     if (isCheck()) {
@@ -3122,7 +3128,7 @@
   }
 
   test_joinIfStatementOuter_OK_conditionOrAnd() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   if (1 == 1 || 2 == 2) {
     if (3 == 3) {
@@ -3144,7 +3150,7 @@
   }
 
   test_joinIfStatementOuter_OK_onCondition() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   if (1 == 1) {
     if (2 == 2) {
@@ -3166,7 +3172,7 @@
   }
 
   test_joinIfStatementOuter_OK_simpleConditions_block_block() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   if (1 == 1) {
     if (2 == 2) {
@@ -3188,7 +3194,7 @@
   }
 
   test_joinIfStatementOuter_OK_simpleConditions_block_single() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   if (1 == 1) {
     if (2 == 2)
@@ -3209,7 +3215,7 @@
   }
 
   test_joinIfStatementOuter_OK_simpleConditions_single_blockMulti() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   if (1 == 1) {
     if (2 == 2) {
@@ -3235,7 +3241,7 @@
   }
 
   test_joinIfStatementOuter_OK_simpleConditions_single_blockOne() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   if (1 == 1)
     if (2 == 2) {
@@ -3256,7 +3262,7 @@
   }
 
   test_joinVariableDeclaration_onAssignment_BAD_hasInitializer() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   var v = 1;
   v = 2;
@@ -3266,7 +3272,7 @@
   }
 
   test_joinVariableDeclaration_onAssignment_BAD_notAdjacent() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   var v;
   var bar;
@@ -3277,7 +3283,7 @@
   }
 
   test_joinVariableDeclaration_onAssignment_BAD_notAssignment() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   var v;
   v += 1;
@@ -3287,7 +3293,7 @@
   }
 
   test_joinVariableDeclaration_onAssignment_BAD_notDeclaration() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main(var v) {
   v = 1;
 }
@@ -3296,7 +3302,7 @@
   }
 
   test_joinVariableDeclaration_onAssignment_BAD_notLeftArgument() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   var v;
   1 + v; // marker
@@ -3307,7 +3313,7 @@
   }
 
   test_joinVariableDeclaration_onAssignment_BAD_notOneVariable() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   var v, v2;
   v = 1;
@@ -3318,7 +3324,7 @@
 
   test_joinVariableDeclaration_onAssignment_BAD_notResolved() async {
     verifyNoTestUnitErrors = false;
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   var v;
   x = 1;
@@ -3328,7 +3334,7 @@
   }
 
   test_joinVariableDeclaration_onAssignment_BAD_notSameBlock() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   var v;
   {
@@ -3340,7 +3346,7 @@
   }
 
   test_joinVariableDeclaration_onAssignment_OK() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   var v;
   v = 1;
@@ -3357,7 +3363,7 @@
   }
 
   test_joinVariableDeclaration_onDeclaration_BAD_hasInitializer() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   var v = 1;
   v = 2;
@@ -3367,7 +3373,7 @@
   }
 
   test_joinVariableDeclaration_onDeclaration_BAD_lastStatement() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   if (true)
     var v;
@@ -3377,7 +3383,7 @@
   }
 
   test_joinVariableDeclaration_onDeclaration_BAD_nextNotAssignmentExpression() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   var v;
   42;
@@ -3387,7 +3393,7 @@
   }
 
   test_joinVariableDeclaration_onDeclaration_BAD_nextNotExpressionStatement() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   var v;
   if (true) return;
@@ -3397,7 +3403,7 @@
   }
 
   test_joinVariableDeclaration_onDeclaration_BAD_nextNotPureAssignment() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   var v;
   v += 1;
@@ -3407,7 +3413,7 @@
   }
 
   test_joinVariableDeclaration_onDeclaration_BAD_notOneVariable() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   var v, v2;
   v = 1;
@@ -3417,7 +3423,7 @@
   }
 
   test_joinVariableDeclaration_onDeclaration_OK_onName() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   var v;
   v = 1;
@@ -3434,7 +3440,7 @@
   }
 
   test_joinVariableDeclaration_onDeclaration_OK_onType() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   int v;
   v = 1;
@@ -3451,7 +3457,7 @@
   }
 
   test_joinVariableDeclaration_onDeclaration_OK_onVar() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   var v;
   v = 1;
@@ -3468,7 +3474,7 @@
   }
 
   test_removeTypeAnnotation_classField_OK() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class A {
   int v = 1;
 }
@@ -3484,7 +3490,7 @@
   }
 
   test_removeTypeAnnotation_classField_OK_final() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class A {
   final int v = 1;
 }
@@ -3500,7 +3506,7 @@
   }
 
   test_removeTypeAnnotation_localVariable_BAD_onInitializer() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   final int v = 1;
 }
@@ -3509,7 +3515,7 @@
   }
 
   test_removeTypeAnnotation_localVariable_OK() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   int a = 1, b = 2;
 }
@@ -3525,7 +3531,7 @@
   }
 
   test_removeTypeAnnotation_localVariable_OK_const() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   const int v = 1;
 }
@@ -3541,7 +3547,7 @@
   }
 
   test_removeTypeAnnotation_localVariable_OK_final() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   final int v = 1;
 }
@@ -3558,14 +3564,14 @@
 
   test_removeTypeAnnotation_topLevelVariable_BAD_syntheticName() async {
     verifyNoTestUnitErrors = false;
-    resolveTestUnit('''
+    await resolveTestUnit('''
 MyType
 ''');
     await assertNoAssistAt('MyType', DartAssistKind.REMOVE_TYPE_ANNOTATION);
   }
 
   test_removeTypeAnnotation_topLevelVariable_OK() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 int V = 1;
 ''');
     await assertHasAssistAt(
@@ -3577,7 +3583,7 @@
   }
 
   test_removeTypeAnnotation_topLevelVariable_OK_final() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 final int V = 1;
 ''');
     await assertHasAssistAt(
@@ -3589,7 +3595,7 @@
   }
 
   test_replaceConditionalWithIfElse_BAD_noEnclosingStatement() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 var v = true ? 111 : 222;
 ''');
     await assertNoAssistAt(
@@ -3597,7 +3603,7 @@
   }
 
   test_replaceConditionalWithIfElse_BAD_notConditional() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   var v = 42;
 }
@@ -3607,7 +3613,7 @@
   }
 
   test_replaceConditionalWithIfElse_OK_assignment() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   var v;
   v = true ? 111 : 222;
@@ -3644,7 +3650,7 @@
   }
 
   test_replaceConditionalWithIfElse_OK_return() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   return true ? 111 : 222;
 }
@@ -3664,7 +3670,7 @@
   }
 
   test_replaceConditionalWithIfElse_OK_variableDeclaration() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   int a = 1, vvv = true ? 111 : 222, b = 2;
 }
@@ -3685,7 +3691,7 @@
   }
 
   test_replaceIfElseWithConditional_BAD_expressionVsReturn() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   if (true) {
     print(42);
@@ -3699,7 +3705,7 @@
   }
 
   test_replaceIfElseWithConditional_BAD_notIfStatement() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   print(0);
 }
@@ -3709,7 +3715,7 @@
   }
 
   test_replaceIfElseWithConditional_BAD_notSingleStatement() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   int vvv;
   if (true) {
@@ -3726,7 +3732,7 @@
   }
 
   test_replaceIfElseWithConditional_OK_assignment() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   int vvv;
   if (true) {
@@ -3748,7 +3754,7 @@
   }
 
   test_replaceIfElseWithConditional_OK_return() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   if (true) {
     return 111;
@@ -3768,7 +3774,7 @@
   }
 
   test_splitAndCondition_BAD_hasElse() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   if (1 == 1 && 2 == 2) {
     print(1);
@@ -3781,7 +3787,7 @@
   }
 
   test_splitAndCondition_BAD_notAnd() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   if (1 == 1 || 2 == 2) {
     print(0);
@@ -3792,7 +3798,7 @@
   }
 
   test_splitAndCondition_BAD_notPartOfIf() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   print(1 == 1 && 2 == 2);
 }
@@ -3801,7 +3807,7 @@
   }
 
   test_splitAndCondition_BAD_notTopLevelAnd() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   if (true || (1 == 1 && 2 == 2)) {
     print(0);
@@ -3816,7 +3822,7 @@
   }
 
   test_splitAndCondition_OK_innerAndExpression() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   if (1 == 1 && 2 == 2 && 3 == 3) {
     print(0);
@@ -3838,7 +3844,7 @@
   }
 
   test_splitAndCondition_OK_thenBlock() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   if (true && false) {
     print(0);
@@ -3866,7 +3872,7 @@
   }
 
   test_splitAndCondition_OK_thenStatement() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   if (true && false)
     print(0);
@@ -3885,7 +3891,7 @@
   }
 
   test_splitAndCondition_wrong() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   if (1 == 1 && 2 == 2) {
     print(0);
@@ -3903,7 +3909,7 @@
   }
 
   test_splitVariableDeclaration_BAD_notOneVariable() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   var v = 1, v2;
 }
@@ -3912,7 +3918,7 @@
   }
 
   test_splitVariableDeclaration_OK_onName() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   var v = 1;
 }
@@ -3929,7 +3935,7 @@
   }
 
   test_splitVariableDeclaration_OK_onType() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   int v = 1;
 }
@@ -3946,7 +3952,7 @@
   }
 
   test_splitVariableDeclaration_OK_onVar() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   var v = 1;
 }
@@ -3963,7 +3969,7 @@
   }
 
   test_surroundWith_block() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
 // start
   print(0);
@@ -3987,7 +3993,7 @@
   }
 
   test_surroundWith_doWhile() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
 // start
   print(0);
@@ -4011,7 +4017,7 @@
   }
 
   test_surroundWith_for() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
 // start
   print(0);
@@ -4035,7 +4041,7 @@
   }
 
   test_surroundWith_forIn() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
 // start
   print(0);
@@ -4059,7 +4065,7 @@
   }
 
   test_surroundWith_if() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
 // start
   print(0);
@@ -4083,7 +4089,7 @@
   }
 
   test_surroundWith_tryCatch() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
 // start
   print(0);
@@ -4109,7 +4115,7 @@
   }
 
   test_surroundWith_tryFinally() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
 // start
   print(0);
@@ -4135,7 +4141,7 @@
   }
 
   test_surroundWith_while() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
 // start
   print(0);
@@ -4162,12 +4168,7 @@
    * Computes assists and verifies that there is an assist of the given kind.
    */
   Future<Assist> _assertHasAssist(AssistKind kind) async {
-    List<Assist> assists = await computeAssists(
-        plugin,
-        context,
-        resolutionMap.elementDeclaredByCompilationUnit(testUnit).source,
-        offset,
-        length);
+    List<Assist> assists = await _computeAssists();
     for (Assist assist in assists) {
       if (assist.kind == kind) {
         return assist;
@@ -4185,6 +4186,19 @@
     }
   }
 
+  Future<List<Assist>> _computeAssists() async {
+    CompilationUnitElement testUnitElement =
+        resolutionMap.elementDeclaredByCompilationUnit(testUnit);
+    DartAssistContext assistContext = new _DartAssistContextForValues(
+        testUnitElement.source,
+        offset,
+        length,
+        testUnitElement.context,
+        testUnit);
+    AssistProcessor processor = new AssistProcessor(assistContext);
+    return await processor.compute();
+  }
+
   List<Position> _findResultPositions(List<String> searchStrings) {
     List<Position> positions = <Position>[];
     for (String search in searchStrings) {
@@ -4199,3 +4213,29 @@
     length = findOffset('// end') - offset;
   }
 }
+
+@reflectiveTest
+class AssistProcessorTest_Driver extends AssistProcessorTest {
+  @override
+  bool get enableNewAnalysisDriver => true;
+}
+
+class _DartAssistContextForValues implements DartAssistContext {
+  @override
+  final Source source;
+
+  @override
+  final int selectionOffset;
+
+  @override
+  final int selectionLength;
+
+  @override
+  final AnalysisContext analysisContext;
+
+  @override
+  final CompilationUnit unit;
+
+  _DartAssistContextForValues(this.source, this.selectionOffset,
+      this.selectionLength, this.analysisContext, this.unit);
+}
diff --git a/pkg/analysis_server/test/services/correction/fix_test.dart b/pkg/analysis_server/test/services/correction/fix_test.dart
index b079561..ff17fe1 100644
--- a/pkg/analysis_server/test/services/correction/fix_test.dart
+++ b/pkg/analysis_server/test/services/correction/fix_test.dart
@@ -7,15 +7,18 @@
 import 'dart:async';
 
 import 'package:analysis_server/plugin/edit/fix/fix_core.dart';
+import 'package:analysis_server/plugin/edit/fix/fix_dart.dart';
 import 'package:analysis_server/plugin/protocol/protocol.dart'
     hide AnalysisError;
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analysis_server/src/services/correction/fix_internal.dart';
+import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/ast/standard_resolution_map.dart';
 import 'package:analyzer/error/error.dart';
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/source/package_map_resolver.dart';
 import 'package:analyzer/src/error/codes.dart';
+import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/parser.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:test/test.dart';
@@ -28,6 +31,8 @@
   defineReflectiveSuite(() {
     defineReflectiveTests(FixProcessorTest);
     defineReflectiveTests(LintFixTest);
+    defineReflectiveTests(FixProcessorTest_Driver);
+    defineReflectiveTests(LintFixTest_Driver);
   });
 }
 
@@ -52,7 +57,7 @@
   String resultCode;
 
   assert_undefinedFunction_create_returnType_bool(String lineWithTest) async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   bool b = true;
   $lineWithTest
@@ -72,7 +77,7 @@
   }
 
   assertHasFix(FixKind kind, String expected) async {
-    AnalysisError error = _findErrorToFix();
+    AnalysisError error = await _findErrorToFix();
     fix = await _assertHasFix(kind, error);
     change = fix.change;
     // apply to "file"
@@ -84,7 +89,7 @@
   }
 
   assertNoFix(FixKind kind) async {
-    AnalysisError error = _findErrorToFix();
+    AnalysisError error = await _findErrorToFix();
     List<Fix> fixes = await _computeFixes(error);
     for (Fix fix in fixes) {
       if (fix.kind == kind) {
@@ -140,13 +145,31 @@
     }
   }
 
+  Future<List<AnalysisError>> _computeErrors() async {
+    if (enableNewAnalysisDriver) {
+      return (await driver.getResult(testFile)).errors;
+    } else {
+      return context.computeErrors(testSource);
+    }
+  }
+
   /**
    * Computes fixes for the given [error] in [testUnit].
    */
   Future<List<Fix>> _computeFixes(AnalysisError error) async {
-    FixContextImpl fixContext = new FixContextImpl(provider, context, error);
-    DefaultFixContributor contributor = new DefaultFixContributor();
-    return contributor.computeFixes(fixContext);
+    if (enableNewAnalysisDriver) {
+      DartFixContext fixContext = new _DartFixContextImpl(
+          provider,
+          driver.getTopLevelNameDeclarations,
+          resolutionMap.elementDeclaredByCompilationUnit(testUnit).context,
+          testUnit,
+          error);
+      return await new DefaultFixContributor().internalComputeFixes(fixContext);
+    } else {
+      FixContextImpl fixContext = new FixContextImpl(provider, context, error);
+      DefaultFixContributor contributor = new DefaultFixContributor();
+      return contributor.computeFixes(fixContext);
+    }
   }
 
   /**
@@ -162,8 +185,13 @@
     UriResolver pkgResolver = new PackageMapUriResolver(provider, {
       'my_pkg': [myPkgFolder]
     });
-    context.sourceFactory = new SourceFactory(
+    SourceFactory sourceFactory = new SourceFactory(
         [AbstractContextTest.SDK_RESOLVER, pkgResolver, resourceResolver]);
+    if (enableNewAnalysisDriver) {
+      driver.configure(sourceFactory: sourceFactory);
+    } else {
+      context.sourceFactory = sourceFactory;
+    }
     // force 'my_pkg' resolution
     addSource(
         '/tmp/other.dart',
@@ -172,8 +200,8 @@
             .join('\n'));
   }
 
-  AnalysisError _findErrorToFix() {
-    List<AnalysisError> errors = context.computeErrors(testSource);
+  Future<AnalysisError> _findErrorToFix() async {
+    List<AnalysisError> errors = await _computeErrors();
     if (errorFilter != null) {
       errors = errors.where(errorFilter).toList();
     }
@@ -189,16 +217,12 @@
     }
     return positions;
   }
-
-  void _performAnalysis() {
-    while (context.performAnalysisTask().hasMoreWork);
-  }
 }
 
 @reflectiveTest
 class FixProcessorTest extends BaseFixProcessorTest {
   test_addFieldFormalParameters_hasRequiredParameter() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class Test {
   final int a;
   final int b;
@@ -219,7 +243,7 @@
   }
 
   test_addFieldFormalParameters_noParameters() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class Test {
   final int a;
   final int b;
@@ -240,7 +264,7 @@
   }
 
   test_addFieldFormalParameters_noRequiredParameter() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class Test {
   final int a;
   final int b;
@@ -261,7 +285,7 @@
   }
 
   test_addMissingParameter_function_positional_hasNamed() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 test({int a}) {}
 main() {
   test(1);
@@ -271,7 +295,7 @@
   }
 
   test_addMissingParameter_function_positional_hasZero() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 test() {}
 main() {
   test(1);
@@ -288,7 +312,7 @@
   }
 
   test_addMissingParameter_function_required_hasNamed() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 test({int a}) {}
 main() {
   test(1);
@@ -305,7 +329,7 @@
   }
 
   test_addMissingParameter_function_required_hasOne() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 test(int a) {}
 main() {
   test(1, 2.0);
@@ -322,7 +346,7 @@
   }
 
   test_addMissingParameter_function_required_hasZero() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 test() {}
 main() {
   test(1);
@@ -339,7 +363,7 @@
   }
 
   test_addMissingParameter_method_positional_hasOne() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class A {
   test(int a) {}
   main() {
@@ -360,7 +384,7 @@
   }
 
   test_addMissingParameter_method_required_hasOne() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class A {
   test(int a) {}
   main() {
@@ -381,7 +405,7 @@
   }
 
   test_addMissingParameter_method_required_hasZero() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class A {
   test() {}
   main() {
@@ -401,41 +425,8 @@
 ''');
   }
 
-  test_addPartOfDirective() async {
-    String partCode = r'''
-// Comment first.
-// Comment second.
-
-class A {}
-''';
-    addSource('/part.dart', partCode);
-    resolveTestUnit('''
-library my.lib;
-part 'part.dart';
-''');
-    _performAnalysis();
-    AnalysisError error = _findErrorToFix();
-    fix = await _assertHasFix(DartFixKind.ADD_PART_OF, error);
-    change = fix.change;
-    // apply to "file"
-    List<SourceFileEdit> fileEdits = change.edits;
-    expect(fileEdits, hasLength(1));
-    SourceFileEdit fileEdit = change.edits[0];
-    expect(fileEdit.file, '/part.dart');
-    expect(
-        SourceEdit.applySequence(partCode, fileEdit.edits),
-        r'''
-// Comment first.
-// Comment second.
-
-part of my.lib;
-
-class A {}
-''');
-  }
-
   test_addSync_asyncFor() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 import 'dart:async';
 void main(Stream<String> names) {
   await for (String name in names) {
@@ -456,20 +447,20 @@
   }
 
   test_addSync_BAD_nullFunctionBody() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 var F = await;
 ''');
     await assertNoFix(DartFixKind.ADD_ASYNC);
   }
 
   test_addSync_blockFunctionBody() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 foo() {}
 main() {
   await foo();
 }
 ''');
-    List<AnalysisError> errors = context.computeErrors(testSource);
+    List<AnalysisError> errors = await _computeErrors();
     expect(errors, hasLength(2));
     errors.sort((a, b) => a.message.compareTo(b.message));
     // No fix for ";".
@@ -508,7 +499,7 @@
     errorFilter = (AnalysisError error) {
       return error.errorCode == StaticWarningCode.UNDEFINED_IDENTIFIER_AWAIT;
     };
-    resolveTestUnit('''
+    await resolveTestUnit('''
 foo() {}
 main() => await foo();
 ''');
@@ -524,7 +515,7 @@
     errorFilter = (AnalysisError error) {
       return error.errorCode == StaticWarningCode.UNDEFINED_IDENTIFIER_AWAIT;
     };
-    resolveTestUnit('''
+    await resolveTestUnit('''
 foo() {}
 int main() {
   await foo();
@@ -548,7 +539,7 @@
     errorFilter = (AnalysisError error) {
       return error.errorCode == StaticWarningCode.UNDEFINED_IDENTIFIER_AWAIT;
     };
-    resolveTestUnit('''
+    await resolveTestUnit('''
 import 'dart:async';
 foo() {}
 Future<int> main() {
@@ -572,7 +563,7 @@
     errorFilter = (AnalysisError error) {
       return error.errorCode == StaticWarningCode.UNDEFINED_IDENTIFIER_AWAIT;
     };
-    resolveTestUnit('''
+    await resolveTestUnit('''
 foo() {}
 dynamic main() {
   await foo();
@@ -594,7 +585,7 @@
     errorFilter = (AnalysisError error) {
       return error.errorCode == StaticWarningCode.UNDEFINED_IDENTIFIER_AWAIT;
     };
-    resolveTestUnit('''
+    await resolveTestUnit('''
 foo() {}
 main() {
   await foo();
@@ -613,7 +604,7 @@
   }
 
   test_boolean() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   boolean v;
 }
@@ -628,7 +619,7 @@
   }
 
   test_canBeNullAfterNullAware_chain() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main(x) {
   x?.a.b.c;
 }
@@ -643,7 +634,7 @@
   }
 
   test_canBeNullAfterNullAware_methodInvocation() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main(x) {
   x?.a.b();
 }
@@ -658,7 +649,7 @@
   }
 
   test_canBeNullAfterNullAware_propertyAccess() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main(x) {
   x?.a().b;
 }
@@ -673,7 +664,7 @@
   }
 
   test_changeToStaticAccess_method() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class A {
   static foo() {}
 }
@@ -709,7 +700,7 @@
 import 'libA.dart';
 class B extends A {}
 ''');
-    resolveTestUnit('''
+    await resolveTestUnit('''
 import 'libB.dart';
 main(B b) {
   b.foo();
@@ -727,7 +718,7 @@
   }
 
   test_changeToStaticAccess_method_prefixLibrary() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 import 'dart:async' as pref;
 main(pref.Future f) {
   f.wait([]);
@@ -744,7 +735,7 @@
   }
 
   test_changeToStaticAccess_property() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class A {
   static get foo => 42;
 }
@@ -780,7 +771,7 @@
 import 'libA.dart';
 class B extends A {}
 ''');
-    resolveTestUnit('''
+    await resolveTestUnit('''
 import 'libB.dart';
 main(B b) {
   b.foo;
@@ -798,7 +789,7 @@
   }
 
   test_changeTypeAnnotation_BAD_multipleVariables() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   String a, b = 42;
 }
@@ -807,7 +798,7 @@
   }
 
   test_changeTypeAnnotation_BAD_notVariableDeclaration() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   String v;
   v = 42;
@@ -817,7 +808,7 @@
   }
 
   test_changeTypeAnnotation_OK_generic() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   String v = <int>[];
 }
@@ -832,7 +823,7 @@
   }
 
   test_changeTypeAnnotation_OK_simple() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   String v = 'abc'.length;
 }
@@ -847,7 +838,7 @@
   }
 
   test_createClass() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   Test v = null;
 }
@@ -866,7 +857,7 @@
   }
 
   test_createClass_BAD_hasUnresolvedPrefix() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   prefix.Test v = null;
 }
@@ -881,7 +872,7 @@
 class A {}
 ''';
     addSource('/lib.dart', libCode);
-    resolveTestUnit('''
+    await resolveTestUnit('''
 import 'lib.dart' as lib;
 
 main() {
@@ -889,7 +880,7 @@
   lib.Test t = null;
 }
 ''');
-    AnalysisError error = _findErrorToFix();
+    AnalysisError error = await _findErrorToFix();
     fix = await _assertHasFix(DartFixKind.CREATE_CLASS, error);
     change = fix.change;
     // apply to "lib.dart"
@@ -911,7 +902,7 @@
   }
 
   test_createClass_innerLocalFunction() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 f() {
   g() {
     Test v = null;
@@ -934,7 +925,7 @@
   }
 
   test_createClass_itemOfList() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   var a = [Test];
 }
@@ -956,7 +947,7 @@
     errorFilter = (AnalysisError error) {
       return error.errorCode == StaticWarningCode.UNDEFINED_IDENTIFIER;
     };
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class MyAnnotation {
   const MyAnnotation(a, b);
 }
@@ -982,7 +973,7 @@
     errorFilter = (AnalysisError error) {
       return error.message.contains("'a'");
     };
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class Test {
   final int a;
   final int b = 2;
@@ -1003,7 +994,7 @@
   }
 
   test_createConstructor_insteadOfSyntheticDefault() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class A {
   int field;
 
@@ -1030,7 +1021,7 @@
   }
 
   test_createConstructor_named() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class A {
   method() {}
 }
@@ -1054,7 +1045,7 @@
   }
 
   test_createConstructor_named_emptyClassBody() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class A {}
 main() {
   new A.named(1);
@@ -1074,7 +1065,7 @@
   }
 
   test_createConstructorForFinalFields_inTopLevelMethod() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   final int v;
 }
@@ -1083,14 +1074,14 @@
   }
 
   test_createConstructorForFinalFields_topLevelField() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 final int v;
 ''');
     await assertNoFix(DartFixKind.CREATE_CONSTRUCTOR_FOR_FINAL_FIELDS);
   }
 
   test_createConstructorSuperExplicit() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class A {
   A(bool p1, int p2, double p3, String p4, {p5});
 }
@@ -1111,7 +1102,7 @@
   }
 
   test_createConstructorSuperExplicit_hasInitializers() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class A {
   A(int p);
 }
@@ -1134,7 +1125,7 @@
   }
 
   test_createConstructorSuperExplicit_named() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class A {
   A.named(int p);
 }
@@ -1155,7 +1146,7 @@
   }
 
   test_createConstructorSuperExplicit_named_private() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class A {
   A._named(int p);
 }
@@ -1167,7 +1158,7 @@
   }
 
   test_createConstructorSuperExplicit_typeArgument() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class A<T> {
   A(T p);
 }
@@ -1188,7 +1179,7 @@
   }
 
   test_createConstructorSuperImplicit() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class A {
   A(p1, int p2, List<String> p3, [int p4]);
 }
@@ -1215,7 +1206,7 @@
   }
 
   test_createConstructorSuperImplicit_fieldInitializer() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class A {
   int _field;
   A(this._field);
@@ -1259,7 +1250,7 @@
   B(A a);
 }
 ''');
-    resolveTestUnit('''
+    await resolveTestUnit('''
 import 'libB.dart';
 class C extends B {
 }
@@ -1276,7 +1267,7 @@
   }
 
   test_createConstructorSuperImplicit_named() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class A {
   A.named(p1, int p2);
 }
@@ -1303,7 +1294,7 @@
   }
 
   test_createConstructorSuperImplicit_private() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class A {
   A._named(p);
 }
@@ -1314,7 +1305,7 @@
   }
 
   test_createConstructorSuperImplicit_typeArgument() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class C<T> {
   final T x;
   C(this.x);
@@ -1334,7 +1325,7 @@
   }
 
   test_createField_BAD_inEnum() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 enum MyEnum {
   AAA, BBB
 }
@@ -1346,7 +1337,7 @@
   }
 
   test_createField_BAD_inSDK() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main(List p) {
   p.foo = 1;
 }
@@ -1355,7 +1346,7 @@
   }
 
   test_createField_getter_multiLevel() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class A {
 }
 class B {
@@ -1387,7 +1378,7 @@
   }
 
   test_createField_getter_qualified_instance() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class A {
 }
 main(A a) {
@@ -1407,7 +1398,7 @@
   }
 
   test_createField_getter_qualified_instance_dynamicType() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class A {
   B b;
   void f(Object p) {
@@ -1433,7 +1424,7 @@
   }
 
   test_createField_getter_qualified_propagatedType() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class A {
   A get self => this;
 }
@@ -1458,7 +1449,7 @@
   }
 
   test_createField_getter_unqualified_instance_asInvocationArgument() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class A {
   main() {
     f(test);
@@ -1481,7 +1472,7 @@
   }
 
   test_createField_getter_unqualified_instance_assignmentRhs() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class A {
   main() {
     int v = test;
@@ -1502,7 +1493,7 @@
   }
 
   test_createField_getter_unqualified_instance_asStatement() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class A {
   main() {
     test;
@@ -1523,7 +1514,7 @@
   }
 
   test_createField_hint() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class A {
 }
 main(A a) {
@@ -1545,7 +1536,7 @@
   }
 
   test_createField_hint_setter() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class A {
 }
 main(A a) {
@@ -1580,7 +1571,7 @@
 import 'libA.dart';
 A getA() => null;
 ''');
-    resolveTestUnit('''
+    await resolveTestUnit('''
 import 'libB.dart';
 class C {
 }
@@ -1603,7 +1594,7 @@
   }
 
   test_createField_setter_generic_BAD() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class A {
 }
 class B<T> {
@@ -1629,7 +1620,7 @@
   }
 
   test_createField_setter_generic_OK_local() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class A<T> {
   List<T> items;
 
@@ -1654,7 +1645,7 @@
   }
 
   test_createField_setter_qualified_instance_hasField() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class A {
   int aaa;
   int zzz;
@@ -1683,7 +1674,7 @@
   }
 
   test_createField_setter_qualified_instance_hasMethod() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class A {
   existingMethod() {}
 }
@@ -1706,7 +1697,7 @@
   }
 
   test_createField_setter_qualified_static() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class A {
 }
 main() {
@@ -1726,7 +1717,7 @@
   }
 
   test_createField_setter_unqualified_instance() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class A {
   main() {
     test = 5;
@@ -1747,7 +1738,7 @@
   }
 
   test_createField_setter_unqualified_static() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class A {
   static main() {
     test = 5;
@@ -1769,10 +1760,10 @@
 
   test_createFile_forImport() async {
     testFile = '/my/project/bin/test.dart';
-    resolveTestUnit('''
+    await resolveTestUnit('''
 import 'my_file.dart';
 ''');
-    AnalysisError error = _findErrorToFix();
+    AnalysisError error = await _findErrorToFix();
     fix = await _assertHasFix(DartFixKind.CREATE_FILE, error);
     change = fix.change;
     // validate change
@@ -1788,7 +1779,7 @@
   test_createFile_forImport_BAD_inPackage_lib_justLib() async {
     provider.newFile('/projects/my_package/pubspec.yaml', 'name: my_package');
     testFile = '/projects/my_package/test.dart';
-    resolveTestUnit('''
+    await resolveTestUnit('''
 import 'lib';
 ''');
     await assertNoFix(DartFixKind.CREATE_FILE);
@@ -1796,7 +1787,7 @@
 
   test_createFile_forImport_BAD_notDart() async {
     testFile = '/my/project/bin/test.dart';
-    resolveTestUnit('''
+    await resolveTestUnit('''
 import 'my_file.txt';
 ''');
     await assertNoFix(DartFixKind.CREATE_FILE);
@@ -1806,10 +1797,10 @@
     provider.newFile('/projects/my_package/pubspec.yaml', 'name: my_package');
     testFile = '/projects/my_package/lib/test.dart';
     provider.newFolder('/projects/my_package/lib');
-    resolveTestUnit('''
+    await resolveTestUnit('''
 import 'a/bb/c_cc/my_lib.dart';
 ''');
-    AnalysisError error = _findErrorToFix();
+    AnalysisError error = await _findErrorToFix();
     fix = await _assertHasFix(DartFixKind.CREATE_FILE, error);
     change = fix.change;
     // validate change
@@ -1826,10 +1817,10 @@
   test_createFile_forImport_inPackage_test() async {
     provider.newFile('/projects/my_package/pubspec.yaml', 'name: my_package');
     testFile = '/projects/my_package/test/misc/test_all.dart';
-    resolveTestUnit('''
+    await resolveTestUnit('''
 import 'a/bb/my_lib.dart';
 ''');
-    AnalysisError error = _findErrorToFix();
+    AnalysisError error = await _findErrorToFix();
     fix = await _assertHasFix(DartFixKind.CREATE_FILE, error);
     change = fix.change;
     // validate change
@@ -1845,11 +1836,11 @@
 
   test_createFile_forPart() async {
     testFile = '/my/project/bin/test.dart';
-    resolveTestUnit('''
+    await resolveTestUnit('''
 library my.lib;
 part 'my_part.dart';
 ''');
-    AnalysisError error = _findErrorToFix();
+    AnalysisError error = await _findErrorToFix();
     fix = await _assertHasFix(DartFixKind.CREATE_FILE, error);
     change = fix.change;
     // validate change
@@ -1879,11 +1870,17 @@
     UriResolver pkgResolver = new PackageMapUriResolver(provider, {
       'my': <Folder>[provider.getResource('/my/lib')],
     });
-    context.sourceFactory = new SourceFactory(
+    SourceFactory sourceFactory = new SourceFactory(
         [AbstractContextTest.SDK_RESOLVER, pkgResolver, resourceResolver]);
+    if (enableNewAnalysisDriver) {
+      driver.configure(sourceFactory: sourceFactory);
+      testUnit = (await driver.getResult(testFile)).unit;
+    } else {
+      context.sourceFactory = sourceFactory;
+      testUnit = await resolveLibraryUnit(testSource);
+    }
     // prepare fix
-    testUnit = resolveLibraryUnit(testSource);
-    AnalysisError error = _findErrorToFix();
+    AnalysisError error = await _findErrorToFix();
     fix = await _assertHasFix(DartFixKind.CREATE_FILE, error);
     change = fix.change;
     // validate change
@@ -1897,7 +1894,7 @@
   }
 
   test_createGetter_BAD_inSDK() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main(List p) {
   int v = p.foo;
 }
@@ -1906,7 +1903,7 @@
   }
 
   test_createGetter_hint_getter() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class A {
 }
 main(A a) {
@@ -1928,7 +1925,7 @@
   }
 
   test_createGetter_location_afterLastGetter() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class A {
   int existingField;
 
@@ -1959,7 +1956,7 @@
   }
 
   test_createGetter_multiLevel() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class A {
 }
 class B {
@@ -1991,7 +1988,7 @@
   }
 
   test_createGetter_qualified_instance() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class A {
 }
 main(A a) {
@@ -2011,7 +2008,7 @@
   }
 
   test_createGetter_qualified_instance_dynamicType() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class A {
   B b;
   void f(Object p) {
@@ -2037,7 +2034,7 @@
   }
 
   test_createGetter_qualified_propagatedType() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class A {
   A get self => this;
 }
@@ -2062,7 +2059,7 @@
   }
 
   test_createGetter_setterContext() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class A {
 }
 main(A a) {
@@ -2073,7 +2070,7 @@
   }
 
   test_createGetter_unqualified_instance_asInvocationArgument() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class A {
   main() {
     f(test);
@@ -2096,7 +2093,7 @@
   }
 
   test_createGetter_unqualified_instance_assignmentLhs() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class A {
   main() {
     test = 42;
@@ -2107,7 +2104,7 @@
   }
 
   test_createGetter_unqualified_instance_assignmentRhs() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class A {
   main() {
     int v = test;
@@ -2128,7 +2125,7 @@
   }
 
   test_createGetter_unqualified_instance_asStatement() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class A {
   main() {
     test;
@@ -2149,7 +2146,7 @@
   }
 
   test_createLocalVariable_functionType_named() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 typedef MY_FUNCTION(int p);
 foo(MY_FUNCTION f) {}
 main() {
@@ -2169,7 +2166,7 @@
   }
 
   test_createLocalVariable_functionType_synthetic() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 foo(f(int p)) {}
 main() {
   foo(bar);
@@ -2179,7 +2176,7 @@
   }
 
   test_createLocalVariable_read_typeAssignment() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   int a = test;
 }
@@ -2195,7 +2192,7 @@
   }
 
   test_createLocalVariable_read_typeCondition() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   if (!test) {
     print(42);
@@ -2215,7 +2212,7 @@
   }
 
   test_createLocalVariable_read_typeInvocationArgument() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   f(test);
 }
@@ -2235,7 +2232,7 @@
   }
 
   test_createLocalVariable_read_typeInvocationTarget() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   test.add('hello');
 }
@@ -2252,7 +2249,7 @@
   }
 
   test_createLocalVariable_write_assignment() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   test = 42;
 }
@@ -2267,7 +2264,7 @@
   }
 
   test_createLocalVariable_write_assignment_compound() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   test += 42;
 }
@@ -2283,7 +2280,7 @@
   }
 
   test_createMissingMethodCall() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class C implements Function {
 }
 ''');
@@ -2299,7 +2296,7 @@
   }
 
   test_createMissingOverrides_field_untyped() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class A {
   var f;
 }
@@ -2322,7 +2319,7 @@
   }
 
   test_createMissingOverrides_functionTypeAlias() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 typedef int Binary(int left, int right);
 
 abstract class Emulator {
@@ -2351,7 +2348,7 @@
   }
 
   test_createMissingOverrides_functionTypedParameter() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 abstract class A {
   forEach(int f(double p1, String p2));
 }
@@ -2376,7 +2373,7 @@
   }
 
   test_createMissingOverrides_generics_typeArguments() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class Iterator<T> {
 }
 
@@ -2406,7 +2403,7 @@
   }
 
   test_createMissingOverrides_generics_typeParameters() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 abstract class ItemProvider<T> {
   List<T> getItems();
 }
@@ -2431,7 +2428,7 @@
   }
 
   test_createMissingOverrides_getter() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 abstract class A {
   get g1;
   int get g2;
@@ -2461,7 +2458,7 @@
   }
 
   test_createMissingOverrides_importPrefix() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 import 'dart:async' as aaa;
 abstract class A {
   Map<aaa.Future, List<aaa.Future>> g(aaa.Future p);
@@ -2488,7 +2485,7 @@
   }
 
   test_createMissingOverrides_mergeToField_getterSetter() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class A {
   int ma;
   void mb() {}
@@ -2523,7 +2520,7 @@
   }
 
   test_createMissingOverrides_method() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 abstract class A {
   m1();
   int m2();
@@ -2596,7 +2593,7 @@
   }
 
   test_createMissingOverrides_method_emptyClassBody() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 abstract class A {
   void foo();
 }
@@ -2619,8 +2616,39 @@
 ''');
   }
 
+  test_createMissingOverrides_method_generic() async {
+    await resolveTestUnit('''
+class C<T> {}
+class V<E> {}
+
+abstract class A {
+  E1 foo<E1, E2 extends C<int>>(V<E2> v);
+}
+
+class B implements A {
+}
+''');
+    await assertHasFix(
+        DartFixKind.CREATE_MISSING_OVERRIDES,
+        '''
+class C<T> {}
+class V<E> {}
+
+abstract class A {
+  E1 foo<E1, E2 extends C<int>>(V<E2> v);
+}
+
+class B implements A {
+  @override
+  E1 foo<E1, E2 extends C<int>>(V<E2> v) {
+    // TODO: implement foo
+  }
+}
+''');
+  }
+
   test_createMissingOverrides_operator() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 abstract class A {
   int operator [](int index);
   void operator []=(int index, String value);
@@ -2652,7 +2680,7 @@
   }
 
   test_createMissingOverrides_setter() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 abstract class A {
   set s1(x);
   set s2(int x);
@@ -2691,7 +2719,7 @@
   }
 
   test_createNoSuchMethod() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 abstract class A {
   m1();
   int m2();
@@ -2718,7 +2746,7 @@
   }
 
   test_creationFunction_forFunctionType_cascadeSecond() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class A {
   B ma() => null;
 }
@@ -2752,7 +2780,7 @@
   }
 
   test_creationFunction_forFunctionType_coreFunction() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   useFunction(g: test);
 }
@@ -2772,7 +2800,7 @@
   }
 
   test_creationFunction_forFunctionType_dynamicArgument() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   useFunction(test);
 }
@@ -2792,7 +2820,7 @@
   }
 
   test_creationFunction_forFunctionType_function() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   useFunction(test);
 }
@@ -2812,7 +2840,7 @@
   }
 
   test_creationFunction_forFunctionType_function_namedArgument() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   useFunction(g: test);
 }
@@ -2845,7 +2873,7 @@
 import 'libA.dart';
 useFunction(int g(A a)) {}
 ''');
-    resolveTestUnit('''
+    await resolveTestUnit('''
 import 'libB.dart';
 main() {
   useFunction(test);
@@ -2866,7 +2894,7 @@
   }
 
   test_creationFunction_forFunctionType_method_enclosingClass_static() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class A {
   static foo() {
     useFunction(test);
@@ -2890,7 +2918,7 @@
   }
 
   test_creationFunction_forFunctionType_method_enclosingClass_static2() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class A {
   var f;
   A() : f = useFunction(test);
@@ -2912,7 +2940,7 @@
   }
 
   test_creationFunction_forFunctionType_method_targetClass() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main(A a) {
   useFunction(a.test);
 }
@@ -2935,7 +2963,7 @@
   }
 
   test_creationFunction_forFunctionType_method_targetClass_hasOtherMember() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main(A a) {
   useFunction(a.test);
 }
@@ -2961,7 +2989,7 @@
   }
 
   test_creationFunction_forFunctionType_notFunctionType() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main(A a) {
   useFunction(a.test);
 }
@@ -2973,7 +3001,7 @@
   }
 
   test_creationFunction_forFunctionType_unknownTarget() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main(A a) {
   useFunction(a.test);
 }
@@ -2985,7 +3013,7 @@
   }
 
   test_expectedToken_semicolon() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   print(0)
 }
@@ -3003,7 +3031,7 @@
     errorFilter = (AnalysisError error) {
       return error.errorCode == StaticTypeWarningCode.ILLEGAL_ASYNC_RETURN_TYPE;
     };
-    resolveTestUnit('''
+    await resolveTestUnit('''
 import 'dart:async';
 var v;int main() async => 0;
 ''');
@@ -3019,7 +3047,7 @@
     errorFilter = (AnalysisError error) {
       return error.errorCode == StaticTypeWarningCode.ILLEGAL_ASYNC_RETURN_TYPE;
     };
-    resolveTestUnit('''
+    await resolveTestUnit('''
 library main;
 int main() async {
 }
@@ -3039,7 +3067,7 @@
     errorFilter = (AnalysisError error) {
       return error.errorCode == StaticTypeWarningCode.ILLEGAL_ASYNC_RETURN_TYPE;
     };
-    resolveTestUnit('''
+    await resolveTestUnit('''
 import 'dart:async' as al;
 int main() async {
 }
@@ -3057,7 +3085,7 @@
     errorFilter = (AnalysisError error) {
       return error.errorCode == StaticTypeWarningCode.ILLEGAL_ASYNC_RETURN_TYPE;
     };
-    resolveTestUnit('''
+    await resolveTestUnit('''
 import 'dart:async';
 List<int> main() async {
 }
@@ -3075,7 +3103,7 @@
     errorFilter = (AnalysisError error) {
       return error.errorCode == StaticTypeWarningCode.ILLEGAL_ASYNC_RETURN_TYPE;
     };
-    resolveTestUnit('''
+    await resolveTestUnit('''
 import 'dart:async';
 void main() async {
 }
@@ -3091,7 +3119,7 @@
 
   test_importLibraryPackage_preferDirectOverExport() async {
     _configureMyPkg({'b.dart': 'class Test {}', 'a.dart': "export 'b.dart';"});
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   Test test = null;
 }
@@ -3120,7 +3148,7 @@
   test_importLibraryPackage_preferDirectOverExport_src() async {
     myPkgLibPath = '/my/src/packages/my_pkg/lib';
     _configureMyPkg({'b.dart': 'class Test {}', 'a.dart': "export 'b.dart';"});
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   Test test = null;
 }
@@ -3149,7 +3177,7 @@
   test_importLibraryPackage_preferPublicOverPrivate() async {
     _configureMyPkg(
         {'src/a.dart': 'class Test {}', 'b.dart': "export 'src/a.dart';"});
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   Test test = null;
 }
@@ -3184,7 +3212,7 @@
   const Test(int p);
 }
 ''');
-    resolveTestUnit('''
+    await resolveTestUnit('''
 @Test(0)
 main() {
 }
@@ -3209,7 +3237,7 @@
   const Test();
 }
 ''');
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   const Test();
 }
@@ -3241,7 +3269,7 @@
 class One {}
 class Two {}
 ''');
-    resolveTestUnit('''
+    await resolveTestUnit('''
 import 'b.dart' show Two;
 main () {
   new Two();
@@ -3269,7 +3297,7 @@
 library lib;
 class Test {}
 ''');
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   Test t = null;
 }
@@ -3294,7 +3322,7 @@
 library lib;
 class Test {}
 ''');
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   Test t = null;
 }
@@ -3319,7 +3347,7 @@
 library lib;
 class Test {}
 ''');
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   Test t = null;
 }
@@ -3343,7 +3371,7 @@
 library lib;
 myFunction() {}
 ''');
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   myFunction();
 }
@@ -3367,7 +3395,7 @@
 library lib;
 myFunction() {}
 ''');
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class A {
   main() {
     myFunction();
@@ -3396,7 +3424,7 @@
 library lib;
 typedef MyFunction();
 ''');
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   MyFunction t = null;
 }
@@ -3420,7 +3448,7 @@
 library lib;
 int MY_VAR = 42;
 ''');
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   print(MY_VAR);
 }
@@ -3438,7 +3466,7 @@
   }
 
   test_importLibrarySdk_withClass_AsExpression() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main(p) {
   p as Future;
 }
@@ -3455,7 +3483,7 @@
   }
 
   test_importLibrarySdk_withClass_invocationTarget() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   Future.wait(null);
 }
@@ -3472,7 +3500,7 @@
   }
 
   test_importLibrarySdk_withClass_IsExpression() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main(p) {
   p is Future;
 }
@@ -3489,7 +3517,7 @@
   }
 
   test_importLibrarySdk_withClass_itemOfList() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   var a = [Future];
 }
@@ -3510,7 +3538,7 @@
     errorFilter = (AnalysisError error) {
       return error.errorCode == StaticWarningCode.UNDEFINED_IDENTIFIER;
     };
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class MyAnnotation {
   const MyAnnotation(a, b);
 }
@@ -3531,7 +3559,7 @@
   }
 
   test_importLibrarySdk_withClass_typeAnnotation() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   Future f = null;
 }
@@ -3548,7 +3576,7 @@
   }
 
   test_importLibrarySdk_withClass_typeAnnotation_PrefixedIdentifier() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   Future.wait;
 }
@@ -3565,7 +3593,7 @@
   }
 
   test_importLibrarySdk_withClass_typeArgument() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   List<Future> futures = [];
 }
@@ -3582,7 +3610,7 @@
   }
 
   test_importLibrarySdk_withTopLevelVariable() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   print(PI);
 }
@@ -3600,7 +3628,7 @@
   }
 
   test_importLibrarySdk_withTopLevelVariable_annotation() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 @PI
 main() {
 }
@@ -3625,7 +3653,7 @@
 class A {}
 class B {}
 ''');
-    resolveTestUnit('''
+    await resolveTestUnit('''
 import 'lib.dart' show A;
 main() {
   A a;
@@ -3646,7 +3674,7 @@
   }
 
   test_importLibraryShow_sdk() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 import 'dart:async' show Stream;
 main() {
   Stream s = null;
@@ -3666,7 +3694,7 @@
   }
 
   test_isNotNull() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main(p) {
   p is! Null;
 }
@@ -3681,7 +3709,7 @@
   }
 
   test_isNull() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main(p) {
   p is Null;
 }
@@ -3696,7 +3724,7 @@
   }
 
   test_makeEnclosingClassAbstract_declaresAbstractMethod() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class A {
   m();
 }
@@ -3711,7 +3739,7 @@
   }
 
   test_makeEnclosingClassAbstract_inheritsAbstractMethod() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 abstract class A {
   m();
 }
@@ -3730,7 +3758,7 @@
   }
 
   test_makeFieldNotFinal_hasType() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class A {
   final int fff = 1;
   main() {
@@ -3751,7 +3779,7 @@
   }
 
   test_makeFieldNotFinal_noType() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class A {
   final fff = 1;
   main() {
@@ -3772,18 +3800,18 @@
   }
 
   test_noException_1() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main(p) {
   p i s Null;
 }''');
-    List<AnalysisError> errors = context.computeErrors(testSource);
+    List<AnalysisError> errors = await _computeErrors();
     for (var error in errors) {
       await _computeFixes(error);
     }
   }
 
   test_nonBoolCondition_addNotNull() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main(String p) {
   if (p) {
     print(p);
@@ -3802,7 +3830,7 @@
   }
 
   test_removeDeadCode_condition() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main(int p) {
   if (true || p > 5) {
     print(1);
@@ -3821,7 +3849,7 @@
   }
 
   test_removeDeadCode_statements_one() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 int main() {
   print(0);
   return 42;
@@ -3839,7 +3867,7 @@
   }
 
   test_removeDeadCode_statements_two() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 int main() {
   print(0);
   return 42;
@@ -3858,7 +3886,7 @@
   }
 
   test_removeParentheses_inGetterDeclaration() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class A {
   int get foo() => 0;
 }
@@ -3873,7 +3901,7 @@
   }
 
   test_removeParentheses_inGetterInvocation() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class A {
   int get foo => 0;
 }
@@ -3894,7 +3922,7 @@
   }
 
   test_removeUnnecessaryCast_assignment() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main(Object p) {
   if (p is String) {
     String v = ((p as String));
@@ -3914,7 +3942,7 @@
 
   test_removeUnusedCatchClause() async {
     errorFilter = (AnalysisError error) => true;
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   try {
     throw 42;
@@ -3936,7 +3964,7 @@
 
   test_removeUnusedCatchStack() async {
     errorFilter = (AnalysisError error) => true;
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   try {
     throw 42;
@@ -3957,7 +3985,7 @@
   }
 
   test_removeUnusedImport() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 import 'dart:math';
 main() {
 }
@@ -3971,7 +3999,7 @@
   }
 
   test_removeUnusedImport_anotherImportOnLine() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 import 'dart:math'; import 'dart:async';
 
 main() {
@@ -3990,7 +4018,7 @@
   }
 
   test_removeUnusedImport_severalLines() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 import
   'dart:math';
 main() {
@@ -4004,38 +4032,11 @@
 ''');
   }
 
-  test_replaceImportUri_inProject() async {
-    testFile = '/project/bin/test.dart';
-    addSource('/project/foo/bar/lib.dart', '');
-    resolveTestUnit('''
-import 'no/matter/lib.dart';
-''');
-    performAllAnalysisTasks();
-    await assertHasFix(
-        DartFixKind.REPLACE_IMPORT_URI,
-        '''
-import '../foo/bar/lib.dart';
-''');
-  }
-
-  test_replaceImportUri_package() async {
-    _configureMyPkg({'my_lib.dart': ''});
-    resolveTestUnit('''
-import 'no/matter/my_lib.dart';
-''');
-    performAllAnalysisTasks();
-    await assertHasFix(
-        DartFixKind.REPLACE_IMPORT_URI,
-        '''
-import 'package:my_pkg/my_lib.dart';
-''');
-  }
-
   test_replaceVarWithDynamic() async {
     errorFilter = (AnalysisError error) {
       return error.errorCode == ParserErrorCode.VAR_AS_TYPE_NAME;
     };
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class A {
   Map<String, var> m;
 }
@@ -4050,7 +4051,7 @@
   }
 
   test_replaceWithConstInstanceCreation() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class A {
   const A();
 }
@@ -4067,7 +4068,7 @@
   }
 
   test_undefinedClass_useSimilar_BAD_prefixed() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 import 'dart:async' as c;
 main() {
   c.Fture v = null;
@@ -4084,7 +4085,7 @@
   }
 
   test_undefinedClass_useSimilar_fromImport() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   Stirng s = 'abc';
 }
@@ -4099,7 +4100,7 @@
   }
 
   test_undefinedClass_useSimilar_fromThisLibrary() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class MyClass {}
 main() {
   MyCalss v = null;
@@ -4116,7 +4117,7 @@
   }
 
   test_undefinedFunction_create_duplicateArgumentNames() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class C {
   int x;
 }
@@ -4142,7 +4143,7 @@
   }
 
   test_undefinedFunction_create_dynamicArgument() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   dynamic v;
   test(v);
@@ -4162,7 +4163,7 @@
   }
 
   test_undefinedFunction_create_dynamicReturnType() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   dynamic v = test();
 }
@@ -4180,7 +4181,7 @@
   }
 
   test_undefinedFunction_create_fromFunction() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   int v = myUndefinedFunction(1, 2.0, '3');
 }
@@ -4198,7 +4199,7 @@
   }
 
   test_undefinedFunction_create_fromMethod() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class A {
   main() {
     int v = myUndefinedFunction(1, 2.0, '3');
@@ -4220,7 +4221,7 @@
   }
 
   test_undefinedFunction_create_generic_BAD() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class A<T> {
   Map<int, T> items;
   main() {
@@ -4244,7 +4245,7 @@
   }
 
   test_undefinedFunction_create_generic_OK() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class A {
   List<int> items;
   main() {
@@ -4284,7 +4285,7 @@
 import 'dart:async';
 Future getFuture() => null;
 ''');
-    resolveTestUnit('''
+    await resolveTestUnit('''
 import 'lib.dart';
 main() {
   test(getFuture());
@@ -4305,7 +4306,7 @@
   }
 
   test_undefinedFunction_create_nullArgument() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   test(null);
 }
@@ -4340,7 +4341,7 @@
   }
 
   test_undefinedFunction_create_returnType_fromAssignment_eq() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   int v;
   v = myUndefinedFunction();
@@ -4360,7 +4361,7 @@
   }
 
   test_undefinedFunction_create_returnType_fromAssignment_plusEq() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   int v;
   v += myUndefinedFunction();
@@ -4380,7 +4381,7 @@
   }
 
   test_undefinedFunction_create_returnType_fromBinary_right() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   0 + myUndefinedFunction();
 }
@@ -4398,7 +4399,7 @@
   }
 
   test_undefinedFunction_create_returnType_fromInitializer() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   int v = myUndefinedFunction();
 }
@@ -4416,7 +4417,7 @@
   }
 
   test_undefinedFunction_create_returnType_fromInvocationArgument() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 foo(int p) {}
 main() {
   foo( myUndefinedFunction() );
@@ -4436,7 +4437,7 @@
   }
 
   test_undefinedFunction_create_returnType_fromReturn() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 int main() {
   return myUndefinedFunction();
 }
@@ -4454,7 +4455,7 @@
   }
 
   test_undefinedFunction_create_returnType_void() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   myUndefinedFunction();
 }
@@ -4472,7 +4473,7 @@
   }
 
   test_undefinedFunction_useSimilar_fromImport() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   pritn(0);
 }
@@ -4487,7 +4488,7 @@
   }
 
   test_undefinedFunction_useSimilar_prefixed_fromImport() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 import 'dart:core' as c;
 main() {
   c.prnt(42);
@@ -4504,7 +4505,7 @@
   }
 
   test_undefinedFunction_useSimilar_prefixed_ignoreLocal() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 import 'dart:async' as c;
 main() {
   c.main();
@@ -4514,7 +4515,7 @@
   }
 
   test_undefinedFunction_useSimilar_thisLibrary() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 myFunction() {}
 main() {
   myFuntcion();
@@ -4531,7 +4532,7 @@
   }
 
   test_undefinedGetter_useSimilar_hint() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class A {
   int myField;
 }
@@ -4554,7 +4555,7 @@
   }
 
   test_undefinedGetter_useSimilar_qualified() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class A {
   int myField;
 }
@@ -4575,7 +4576,7 @@
   }
 
   test_undefinedGetter_useSimilar_qualified_static() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class A {
   static int MY_NAME = 1;
 }
@@ -4596,7 +4597,7 @@
   }
 
   test_undefinedGetter_useSimilar_unqualified() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class A {
   int myField;
   main() {
@@ -4617,7 +4618,7 @@
   }
 
   test_undefinedMethod_create_BAD_inSDK() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   List.foo();
 }
@@ -4626,7 +4627,7 @@
   }
 
   test_undefinedMethod_create_BAD_targetIsEnum() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 enum MyEnum {A, B}
 main() {
   MyEnum.foo();
@@ -4636,7 +4637,7 @@
   }
 
   test_undefinedMethod_create_generic_BAD_argumentType() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class A<T> {
   B b;
   Map<int, T> items;
@@ -4666,7 +4667,7 @@
   }
 
   test_undefinedMethod_create_generic_BAD_returnType() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class A<T> {
   main() {
     T t = new B().compute();
@@ -4692,7 +4693,7 @@
   }
 
   test_undefinedMethod_create_generic_OK_literal() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class A {
   B b;
   List<int> items;
@@ -4721,7 +4722,7 @@
   }
 
   test_undefinedMethod_create_generic_OK_local() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class A<T> {
   List<T> items;
   main() {
@@ -4744,7 +4745,7 @@
   }
 
   test_undefinedMethod_createQualified_emptyClassBody() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class A {}
 main() {
   A.myUndefinedMethod();
@@ -4763,7 +4764,7 @@
   }
 
   test_undefinedMethod_createQualified_fromClass() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class A {
 }
 main() {
@@ -4783,7 +4784,7 @@
   }
 
   test_undefinedMethod_createQualified_fromClass_hasOtherMember() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class A {
   foo() {}
 }
@@ -4806,7 +4807,7 @@
   }
 
   test_undefinedMethod_createQualified_fromInstance() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class A {
 }
 main(A a) {
@@ -4826,7 +4827,7 @@
   }
 
   test_undefinedMethod_createQualified_targetIsFunctionType() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 typedef A();
 main() {
   A.myUndefinedMethod();
@@ -4836,7 +4837,7 @@
   }
 
   test_undefinedMethod_createQualified_targetIsUnresolved() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   NoSuchClass.myUndefinedMethod();
 }
@@ -4845,7 +4846,7 @@
   }
 
   test_undefinedMethod_createUnqualified_duplicateArgumentNames() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class C {
   int x;
 }
@@ -4872,7 +4873,7 @@
   }
 
   test_undefinedMethod_createUnqualified_parameters() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class A {
   main() {
     myUndefinedMethod(0, 1.0, '3');
@@ -4917,7 +4918,7 @@
   }
 
   test_undefinedMethod_createUnqualified_parameters_named() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class A {
   main() {
     myUndefinedMethod(0, bbb: 1.0, ccc: '2');
@@ -4960,7 +4961,7 @@
   }
 
   test_undefinedMethod_createUnqualified_returnType() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class A {
   main() {
     int v = myUndefinedMethod();
@@ -4985,7 +4986,7 @@
   }
 
   test_undefinedMethod_createUnqualified_staticFromField() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class A {
   static var f = myUndefinedMethod();
 }
@@ -5002,7 +5003,7 @@
   }
 
   test_undefinedMethod_createUnqualified_staticFromMethod() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class A {
   static main() {
     myUndefinedMethod();
@@ -5023,7 +5024,7 @@
   }
 
   test_undefinedMethod_hint_createQualified_fromInstance() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class A {
 }
 main() {
@@ -5059,14 +5060,14 @@
 library test3;
 class E {}
 ''');
-    resolveTestUnit('''
+    await resolveTestUnit('''
 library test;
 import 'test2.dart' as aaa;
 main(aaa.D d, aaa.E e) {
   d.foo(e);
 }
 ''');
-    AnalysisError error = _findErrorToFix();
+    AnalysisError error = await _findErrorToFix();
     fix = await _assertHasFix(DartFixKind.CREATE_METHOD, error);
     change = fix.change;
     // apply to "test2.dart"
@@ -5094,14 +5095,14 @@
 class E {}
 ''';
     addSource('/test2.dart', code2);
-    resolveTestUnit('''
+    await resolveTestUnit('''
 library test;
 import 'test2.dart' as test2;
 main(test2.D d, test2.E e) {
   d.foo(e);
 }
 ''');
-    AnalysisError error = _findErrorToFix();
+    AnalysisError error = await _findErrorToFix();
     fix = await _assertHasFix(DartFixKind.CREATE_METHOD, error);
     change = fix.change;
     // apply to "test2.dart"
@@ -5121,7 +5122,7 @@
   }
 
   test_undefinedMethod_useSimilar_ignoreOperators() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main(Object object) {
   object.then();
 }
@@ -5130,7 +5131,7 @@
   }
 
   test_undefinedMethod_useSimilar_qualified() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class A {
   myMethod() {}
 }
@@ -5153,7 +5154,7 @@
   }
 
   test_undefinedMethod_useSimilar_unqualified_superClass() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class A {
   myMethod() {}
 }
@@ -5178,7 +5179,7 @@
   }
 
   test_undefinedMethod_useSimilar_unqualified_thisClass() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class A {
   myMethod() {}
   main() {
@@ -5199,7 +5200,7 @@
   }
 
   test_undefinedSetter_useSimilar_hint() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class A {
   int myField;
 }
@@ -5222,7 +5223,7 @@
   }
 
   test_undefinedSetter_useSimilar_qualified() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class A {
   int myField;
 }
@@ -5243,7 +5244,7 @@
   }
 
   test_undefinedSetter_useSimilar_unqualified() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 class A {
   int myField;
   main() {
@@ -5264,7 +5265,7 @@
   }
 
   test_useEffectiveIntegerDivision() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 main() {
   var a = 5;
   var b = 2;
@@ -5283,7 +5284,7 @@
   }
 
   test_useImportPrefix_withClass() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 import 'dart:async' as pref;
 main() {
   pref.Stream s = null;
@@ -5302,7 +5303,7 @@
   }
 
   test_useImportPrefix_withTopLevelVariable() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 import 'dart:math' as pref;
 main() {
   print(pref.E);
@@ -5322,6 +5323,12 @@
 }
 
 @reflectiveTest
+class FixProcessorTest_Driver extends FixProcessorTest {
+  @override
+  bool get enableNewAnalysisDriver => true;
+}
+
+@reflectiveTest
 class LintFixTest extends BaseFixProcessorTest {
   AnalysisError error;
 
@@ -5334,9 +5341,9 @@
     resultCode = SourceEdit.applySequence(testCode, change.edits[0].edits);
   }
 
-  void findLint(String src, String lintCode, {int length: 1}) {
+  Future<Null> findLint(String src, String lintCode, {int length: 1}) async {
     int errorOffset = src.indexOf('/*LINT*/');
-    resolveTestUnit(src.replaceAll('/*LINT*/', ''));
+    await resolveTestUnit(src.replaceAll('/*LINT*/', ''));
     error = new AnalysisError(
         resolutionMap.elementDeclaredByCompilationUnit(testUnit).source,
         errorOffset,
@@ -5353,7 +5360,7 @@
   int /*LINT*/t = 42;
 }
 ''';
-    findLint(src, LintNames.annotate_overrides);
+    await findLint(src, LintNames.annotate_overrides);
 
     await applyFix(DartFixKind.LINT_ADD_OVERRIDE);
 
@@ -5377,7 +5384,7 @@
   int get /*LINT*/t => null;
 }
 ''';
-    findLint(src, LintNames.annotate_overrides);
+    await findLint(src, LintNames.annotate_overrides);
 
     await applyFix(DartFixKind.LINT_ADD_OVERRIDE);
 
@@ -5401,7 +5408,7 @@
   void /*LINT*/t() { }
 }
 ''';
-    findLint(src, LintNames.annotate_overrides);
+    await findLint(src, LintNames.annotate_overrides);
 
     await applyFix(DartFixKind.LINT_ADD_OVERRIDE);
 
@@ -5426,7 +5433,7 @@
   void /*LINT*/t() { }
 }
 ''';
-    findLint(src, LintNames.annotate_overrides);
+    await findLint(src, LintNames.annotate_overrides);
 
     await applyFix(DartFixKind.LINT_ADD_OVERRIDE);
 
@@ -5454,7 +5461,7 @@
   void /*LINT*/t() { }
 }
 ''';
-    findLint(src, LintNames.annotate_overrides);
+    await findLint(src, LintNames.annotate_overrides);
 
     await applyFix(DartFixKind.LINT_ADD_OVERRIDE);
 
@@ -5483,7 +5490,7 @@
   void /*LINT*/t() { }
 }
 ''';
-    findLint(src, LintNames.annotate_overrides);
+    await findLint(src, LintNames.annotate_overrides);
 
     await applyFix(DartFixKind.LINT_ADD_OVERRIDE);
 
@@ -5510,7 +5517,7 @@
   void /*LINT*/t() { }
 }
 ''';
-    findLint(src, LintNames.annotate_overrides);
+    await findLint(src, LintNames.annotate_overrides);
 
     await applyFix(DartFixKind.LINT_ADD_OVERRIDE);
 
@@ -5533,7 +5540,8 @@
   print('v: /*LINT*/${ v}');
 }
 ''';
-    findLint(src, LintNames.unnecessary_brace_in_string_interp, length: 4);
+    await findLint(src, LintNames.unnecessary_brace_in_string_interp,
+        length: 4);
     await applyFix(DartFixKind.LINT_REMOVE_INTERPOLATION_BRACES);
     verifyResult(r'''
 main() {
@@ -5547,3 +5555,29 @@
     expect(resultCode, expectedResult);
   }
 }
+
+@reflectiveTest
+class LintFixTest_Driver extends LintFixTest {
+  @override
+  bool get enableNewAnalysisDriver => true;
+}
+
+class _DartFixContextImpl implements DartFixContext {
+  @override
+  final ResourceProvider resourceProvider;
+
+  @override
+  final GetTopLevelDeclarations getTopLevelDeclarations;
+
+  @override
+  final AnalysisContext analysisContext;
+
+  @override
+  final CompilationUnit unit;
+
+  @override
+  final AnalysisError error;
+
+  _DartFixContextImpl(this.resourceProvider, this.getTopLevelDeclarations,
+      this.analysisContext, this.unit, this.error);
+}
diff --git a/pkg/analysis_server/test/services/correction/name_suggestion_test.dart b/pkg/analysis_server/test/services/correction/name_suggestion_test.dart
index fdd914e..c33dc66 100644
--- a/pkg/analysis_server/test/services/correction/name_suggestion_test.dart
+++ b/pkg/analysis_server/test/services/correction/name_suggestion_test.dart
@@ -21,8 +21,8 @@
 
 @reflectiveTest
 class VariableNameSuggestionTest extends AbstractSingleUnitTest {
-  void test_forExpression_cast() {
-    resolveTestUnit('''
+  test_forExpression_cast() async {
+    await resolveTestUnit('''
 main() {
   var sortedNodes;
   var res = sortedNodes as String;
@@ -34,8 +34,8 @@
         unorderedEquals(['sortedNodes', 'nodes']));
   }
 
-  void test_forExpression_expectedType() {
-    resolveTestUnit('''
+  test_forExpression_expectedType() async {
+    await resolveTestUnit('''
 class TreeNode {}
 main() {
   TreeNode node = null;
@@ -50,8 +50,8 @@
     expect(suggestions, unorderedEquals(['treeNode', 'node']));
   }
 
-  void test_forExpression_expectedType_double() {
-    resolveTestUnit('''
+  test_forExpression_expectedType_double() async {
+    await resolveTestUnit('''
 main() {
   double res = 0.0;
 }
@@ -70,8 +70,8 @@
         unorderedEquals(['f']));
   }
 
-  void test_forExpression_expectedType_int() {
-    resolveTestUnit('''
+  test_forExpression_expectedType_int() async {
+    await resolveTestUnit('''
 main() {
   int res = 0;
 }
@@ -90,8 +90,8 @@
         unorderedEquals(['k']));
   }
 
-  void test_forExpression_expectedType_String() {
-    resolveTestUnit('''
+  test_forExpression_expectedType_String() async {
+    await resolveTestUnit('''
 main() {
   String res = 'abc';
 }
@@ -105,9 +105,9 @@
         unorderedEquals(['s']));
   }
 
-  void test_forExpression_instanceCreation() {
+  test_forExpression_instanceCreation() async {
     verifyNoTestUnitErrors = false;
-    resolveTestUnit('''
+    await resolveTestUnit('''
 import 'dart:math' as p;
 main(p) {
   new NoSuchClass();
@@ -134,8 +134,8 @@
 //        unorderedEquals(['noSuchClass', 'suchClass', 'class']));
   }
 
-  void test_forExpression_invocationArgument_named() {
-    resolveTestUnit('''
+  test_forExpression_invocationArgument_named() async {
+    await resolveTestUnit('''
 foo({a, b, c}) {}
 main() {
   foo(a: 111, c: 333, b: 222);
@@ -159,8 +159,8 @@
     }
   }
 
-  void test_forExpression_invocationArgument_optional() {
-    resolveTestUnit('''
+  test_forExpression_invocationArgument_optional() async {
+    await resolveTestUnit('''
 foo(a, [b = 2, c = 3]) {}
 main() {
   foo(111, 222, 333);
@@ -184,8 +184,8 @@
     }
   }
 
-  void test_forExpression_invocationArgument_positional() {
-    resolveTestUnit('''
+  test_forExpression_invocationArgument_positional() async {
+    await resolveTestUnit('''
 foo(a, b) {}
 main() {
   foo(111, 222);
@@ -204,8 +204,8 @@
     }
   }
 
-  void test_forExpression_methodInvocation() {
-    resolveTestUnit('''
+  test_forExpression_methodInvocation() async {
+    await resolveTestUnit('''
 main(p) {
   var res = p.getSortedNodes();
 }
@@ -216,8 +216,8 @@
         unorderedEquals(['sortedNodes', 'nodes']));
   }
 
-  void test_forExpression_methodInvocation_noPrefix() {
-    resolveTestUnit('''
+  test_forExpression_methodInvocation_noPrefix() async {
+    await resolveTestUnit('''
 main(p) {
   var res = p.sortedNodes();
 }
@@ -228,8 +228,8 @@
         unorderedEquals(['sortedNodes', 'nodes']));
   }
 
-  void test_forExpression_name_get() {
-    resolveTestUnit('''
+  test_forExpression_name_get() async {
+    await resolveTestUnit('''
 main(p) {
   var res = p.get();
 }
@@ -240,8 +240,8 @@
         unorderedEquals([]));
   }
 
-  void test_forExpression_prefixedIdentifier() {
-    resolveTestUnit('''
+  test_forExpression_prefixedIdentifier() async {
+    await resolveTestUnit('''
 main(p) {
   var res = p.sortedNodes;
 }
@@ -255,8 +255,8 @@
         unorderedEquals(['sortedNodes', 'nodes']));
   }
 
-  void test_forExpression_privateName() {
-    resolveTestUnit('''
+  test_forExpression_privateName() async {
+    await resolveTestUnit('''
 main(p) {
   p._name;
   p._computeSuffix();
@@ -277,8 +277,8 @@
         unorderedEquals(['computeSuffix', 'suffix']));
   }
 
-  void test_forExpression_propertyAccess() {
-    resolveTestUnit('''
+  test_forExpression_propertyAccess() async {
+    await resolveTestUnit('''
 main(p) {
   var res = p.q.sortedNodes;
 }
@@ -290,8 +290,8 @@
         unorderedEquals(['sortedNodes', 'nodes']));
   }
 
-  void test_forExpression_simpleName() {
-    resolveTestUnit('''
+  test_forExpression_simpleName() async {
+    await resolveTestUnit('''
 main(p) {
   var sortedNodes = null;
   var res = sortedNodes;
@@ -303,8 +303,8 @@
         unorderedEquals(['sortedNodes', 'nodes']));
   }
 
-  void test_forExpression_unqualifiedInvocation() {
-    resolveTestUnit('''
+  test_forExpression_unqualifiedInvocation() async {
+    await resolveTestUnit('''
 getSortedNodes() => [];
 main(p) {
   var res = getSortedNodes();
diff --git a/pkg/analysis_server/test/services/correction/source_range_test.dart b/pkg/analysis_server/test/services/correction/source_range_test.dart
index 28779ac..86ca72d 100644
--- a/pkg/analysis_server/test/services/correction/source_range_test.dart
+++ b/pkg/analysis_server/test/services/correction/source_range_test.dart
@@ -23,22 +23,22 @@
 
 @reflectiveTest
 class SourceRangesTest extends AbstractSingleUnitTest {
-  void test_rangeElementName() {
-    resolveTestUnit('class ABC {}');
+  test_rangeElementName() async {
+    await resolveTestUnit('class ABC {}');
     Element element = findElement('ABC');
     expect(rangeElementName(element), new SourceRange(6, 3));
   }
 
-  void test_rangeEndEnd_nodeNode() {
-    resolveTestUnit('main() {}');
+  test_rangeEndEnd_nodeNode() async {
+    await resolveTestUnit('main() {}');
     FunctionDeclaration mainFunction = testUnit.declarations[0];
     SimpleIdentifier mainName = mainFunction.name;
     FunctionBody mainBody = mainFunction.functionExpression.body;
     expect(rangeEndEnd(mainName, mainBody), new SourceRange(4, 5));
   }
 
-  void test_rangeEndStart_nodeNode() {
-    resolveTestUnit('main() {}');
+  test_rangeEndStart_nodeNode() async {
+    await resolveTestUnit('main() {}');
     FunctionDeclaration mainFunction = testUnit.declarations[0];
     SimpleIdentifier mainName = mainFunction.name;
     FunctionBody mainBody = mainFunction.functionExpression.body;
@@ -51,23 +51,23 @@
     expect(rangeError(error), new SourceRange(10, 5));
   }
 
-  void test_rangeNode() {
-    resolveTestUnit('main() {}');
+  test_rangeNode() async {
+    await resolveTestUnit('main() {}');
     FunctionDeclaration mainFunction = testUnit.declarations[0];
     SimpleIdentifier mainName = mainFunction.name;
     expect(rangeNode(mainName), new SourceRange(0, 4));
   }
 
-  void test_rangeNodes() {
-    resolveTestUnit(' main() {}');
+  test_rangeNodes() async {
+    await resolveTestUnit(' main() {}');
     FunctionDeclaration mainFunction = testUnit.declarations[0];
     SimpleIdentifier mainName = mainFunction.name;
     FunctionBody mainBody = mainFunction.functionExpression.body;
     expect(rangeNodes([mainName, mainBody]), new SourceRange(1, 9));
   }
 
-  void test_rangeNodes_empty() {
-    resolveTestUnit('main() {}');
+  test_rangeNodes_empty() async {
+    await resolveTestUnit('main() {}');
     expect(rangeNodes([]), new SourceRange(0, 0));
   }
 
@@ -75,8 +75,8 @@
     expect(rangeStartEnd(10, 25), new SourceRange(10, 15));
   }
 
-  void test_rangeStartEnd_nodeNode() {
-    resolveTestUnit(' main() {}');
+  test_rangeStartEnd_nodeNode() async {
+    await resolveTestUnit(' main() {}');
     FunctionDeclaration mainFunction = testUnit.declarations[0];
     SimpleIdentifier mainName = mainFunction.name;
     FunctionBody mainBody = mainFunction.functionExpression.body;
@@ -87,8 +87,8 @@
     expect(rangeStartLength(5, 10), new SourceRange(5, 10));
   }
 
-  void test_rangeStartLength_node() {
-    resolveTestUnit(' main() {}');
+  test_rangeStartLength_node() async {
+    await resolveTestUnit(' main() {}');
     FunctionDeclaration mainFunction = testUnit.declarations[0];
     SimpleIdentifier mainName = mainFunction.name;
     expect(rangeStartLength(mainName, 10), new SourceRange(1, 10));
@@ -98,16 +98,16 @@
     expect(rangeStartStart(10, 25), new SourceRange(10, 15));
   }
 
-  void test_rangeStartStart_nodeNode() {
-    resolveTestUnit('main() {}');
+  test_rangeStartStart_nodeNode() async {
+    await resolveTestUnit('main() {}');
     FunctionDeclaration mainFunction = testUnit.declarations[0];
     SimpleIdentifier mainName = mainFunction.name;
     FunctionBody mainBody = mainFunction.functionExpression.body;
     expect(rangeStartStart(mainName, mainBody), new SourceRange(0, 7));
   }
 
-  void test_rangeToken() {
-    resolveTestUnit(' main() {}');
+  test_rangeToken() async {
+    await resolveTestUnit(' main() {}');
     FunctionDeclaration mainFunction = testUnit.declarations[0];
     SimpleIdentifier mainName = mainFunction.name;
     expect(rangeToken(mainName.beginToken), new SourceRange(1, 4));
diff --git a/pkg/analysis_server/test/services/correction/status_test.dart b/pkg/analysis_server/test/services/correction/status_test.dart
index 9c9169e..1775987 100644
--- a/pkg/analysis_server/test/services/correction/status_test.dart
+++ b/pkg/analysis_server/test/services/correction/status_test.dart
@@ -26,8 +26,8 @@
 
 @reflectiveTest
 class RefactoringLocationTest extends AbstractSingleUnitTest {
-  void test_createLocation_forElement() {
-    resolveTestUnit('class MyClass {}');
+  test_createLocation_forElement() async {
+    await resolveTestUnit('class MyClass {}');
     Element element = findElement('MyClass');
     // check
     Location location = newLocation_fromElement(element);
@@ -38,8 +38,8 @@
     expect(location.startColumn, 7);
   }
 
-  void test_createLocation_forMatch() {
-    resolveTestUnit('class MyClass {}');
+  test_createLocation_forMatch() async {
+    await resolveTestUnit('class MyClass {}');
     Element element = findElement('MyClass');
     SourceRange range = rangeElementName(element);
     SearchMatch match = new SearchMatchImpl(
@@ -57,8 +57,8 @@
     expect(location.length, range.length);
   }
 
-  void test_createLocation_forNode() {
-    resolveTestUnit('''
+  test_createLocation_forNode() async {
+    await resolveTestUnit('''
 main() {
 }
 ''');
@@ -70,8 +70,8 @@
     expect(location.length, node.length);
   }
 
-  void test_createLocation_forUnit() {
-    resolveTestUnit('');
+  test_createLocation_forUnit() async {
+    await resolveTestUnit('');
     SourceRange range = rangeStartLength(10, 20);
     // check
     Location location = newLocation_fromUnit(testUnit, range);
diff --git a/pkg/analysis_server/test/services/correction/util_test.dart b/pkg/analysis_server/test/services/correction/util_test.dart
index ee3089e..8639a6b 100644
--- a/pkg/analysis_server/test/services/correction/util_test.dart
+++ b/pkg/analysis_server/test/services/correction/util_test.dart
@@ -21,8 +21,8 @@
 
 @reflectiveTest
 class UtilTest extends AbstractSingleUnitTest {
-  test_addLibraryImports_dart_hasImports_between() {
-    resolveTestUnit('''
+  test_addLibraryImports_dart_hasImports_between() async {
+    await resolveTestUnit('''
 import 'dart:async';
 import 'dart:math';
 ''');
@@ -36,8 +36,8 @@
 ''');
   }
 
-  test_addLibraryImports_dart_hasImports_first() {
-    resolveTestUnit('''
+  test_addLibraryImports_dart_hasImports_first() async {
+    await resolveTestUnit('''
 import 'dart:collection';
 import 'dart:math';
 ''');
@@ -51,8 +51,8 @@
 ''');
   }
 
-  test_addLibraryImports_dart_hasImports_last() {
-    resolveTestUnit('''
+  test_addLibraryImports_dart_hasImports_last() async {
+    await resolveTestUnit('''
 import 'dart:async';
 import 'dart:collection';
 ''');
@@ -66,8 +66,8 @@
 ''');
   }
 
-  test_addLibraryImports_dart_hasImports_multiple() {
-    resolveTestUnit('''
+  test_addLibraryImports_dart_hasImports_multiple() async {
+    await resolveTestUnit('''
 import 'dart:collection';
 import 'dart:math';
 ''');
@@ -83,8 +83,8 @@
 ''');
   }
 
-  test_addLibraryImports_dart_hasImports_multiple_first() {
-    resolveTestUnit('''
+  test_addLibraryImports_dart_hasImports_multiple_first() async {
+    await resolveTestUnit('''
 import 'dart:html';
 import 'dart:math';
 ''');
@@ -100,8 +100,8 @@
 ''');
   }
 
-  test_addLibraryImports_dart_hasImports_multiple_last() {
-    resolveTestUnit('''
+  test_addLibraryImports_dart_hasImports_multiple_last() async {
+    await resolveTestUnit('''
 import 'dart:async';
 import 'dart:collection';
 ''');
@@ -117,8 +117,8 @@
 ''');
   }
 
-  test_addLibraryImports_dart_hasLibraryDirective() {
-    resolveTestUnit('''
+  test_addLibraryImports_dart_hasLibraryDirective() async {
+    await resolveTestUnit('''
 library test;
 
 class A {}
@@ -137,8 +137,8 @@
 ''');
   }
 
-  test_addLibraryImports_dart_noDirectives_hasComment() {
-    resolveTestUnit('''
+  test_addLibraryImports_dart_noDirectives_hasComment() async {
+    await resolveTestUnit('''
 /// Comment.
 
 class A {}
@@ -157,8 +157,8 @@
 ''');
   }
 
-  test_addLibraryImports_dart_noDirectives_hasShebang() {
-    resolveTestUnit('''
+  test_addLibraryImports_dart_noDirectives_hasShebang() async {
+    await resolveTestUnit('''
 #!/bin/dart
 
 class A {}
@@ -177,8 +177,8 @@
 ''');
   }
 
-  test_addLibraryImports_dart_noDirectives_noShebang() {
-    resolveTestUnit('''
+  test_addLibraryImports_dart_noDirectives_noShebang() async {
+    await resolveTestUnit('''
 class A {}
 ''');
     Source newLibrary1 = _getDartSource('dart:math');
@@ -193,8 +193,8 @@
 ''');
   }
 
-  test_addLibraryImports_package_hasDart_hasPackages_insertAfter() {
-    resolveTestUnit('''
+  test_addLibraryImports_package_hasDart_hasPackages_insertAfter() async {
+    await resolveTestUnit('''
 import 'dart:async';
 
 import 'package:aaa/aaa.dart';
@@ -210,8 +210,8 @@
 ''');
   }
 
-  test_addLibraryImports_package_hasDart_hasPackages_insertBefore() {
-    resolveTestUnit('''
+  test_addLibraryImports_package_hasDart_hasPackages_insertBefore() async {
+    await resolveTestUnit('''
 import 'dart:async';
 
 import 'package:bbb/bbb.dart';
@@ -227,8 +227,8 @@
 ''');
   }
 
-  test_addLibraryImports_package_hasImports_between() {
-    resolveTestUnit('''
+  test_addLibraryImports_package_hasImports_between() async {
+    await resolveTestUnit('''
 import 'package:aaa/aaa.dart';
 import 'package:ddd/ddd.dart';
 ''');
diff --git a/pkg/analysis_server/test/services/dependencies/reachable_source_collector_test.dart b/pkg/analysis_server/test/services/dependencies/reachable_source_collector_test.dart
index 94874f9..0b2be14 100644
--- a/pkg/analysis_server/test/services/dependencies/reachable_source_collector_test.dart
+++ b/pkg/analysis_server/test/services/dependencies/reachable_source_collector_test.dart
@@ -5,7 +5,6 @@
 library test.services.dependencies.import_collector;
 
 import 'package:analysis_server/src/services/dependencies/reachable_source_collector.dart';
-import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -20,9 +19,6 @@
 
 @reflectiveTest
 class ReachableSourceCollectorTest extends AbstractContextTest {
-  CompilationUnit addLibrary(String path, String contents) =>
-      resolveLibraryUnit(addSource(path, contents));
-
   Map<String, List<String>> importsFor(Source source) =>
       new ReachableSourceCollector(source, context).collectSources();
 
diff --git a/pkg/analysis_server/test/services/index/index_test.dart b/pkg/analysis_server/test/services/index/index_test.dart
index 2d78865..14aae6d 100644
--- a/pkg/analysis_server/test/services/index/index_test.dart
+++ b/pkg/analysis_server/test/services/index/index_test.dart
@@ -2,6 +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:analysis_server/src/services/index/index.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/element/element.dart';
@@ -79,7 +81,7 @@
   }
 
   test_getDefinedNames_classMember() async {
-    _indexTestUnit('''
+    await _indexTestUnit('''
 class A {
   test() {}
 }
@@ -100,7 +102,7 @@
   }
 
   test_getDefinedNames_topLevel() async {
-    _indexTestUnit('''
+    await _indexTestUnit('''
 class A {} // A
 class B = Object with A;
 typedef C();
@@ -124,7 +126,7 @@
   }
 
   test_getDefinedNames_topLevel2() async {
-    _indexTestUnit(
+    await _indexTestUnit(
         '''
 class A {} // A
 class B = Object with A;
@@ -141,11 +143,11 @@
   }
 
   test_getRelations_isExtendedBy() async {
-    _indexTestUnit(r'''
+    await _indexTestUnit(r'''
 class A {}
 class B extends A {} // B
 ''');
-    Source source2 = _indexUnit(
+    Source source2 = await _indexUnit(
         '/test2.dart',
         r'''
 import 'test.dart';
@@ -159,7 +161,7 @@
   }
 
   test_getRelations_isReferencedBy() async {
-    _indexTestUnit(r'''
+    await _indexTestUnit(r'''
 main(int a, int b) {
 }
 ''');
@@ -171,7 +173,7 @@
   }
 
   test_getUnresolvedMemberReferences_qualified_resolved() async {
-    _indexTestUnit('''
+    await _indexTestUnit('''
 class A {
   var test; // A
 }
@@ -188,7 +190,7 @@
   }
 
   test_getUnresolvedMemberReferences_qualified_unresolved() async {
-    _indexTestUnit('''
+    await _indexTestUnit('''
 class A {
   var test; // A
 }
@@ -210,7 +212,7 @@
   }
 
   test_getUnresolvedMemberReferences_unqualified_resolved() async {
-    _indexTestUnit('''
+    await _indexTestUnit('''
 class A {
   var test;
   m() {
@@ -228,7 +230,7 @@
 
   test_getUnresolvedMemberReferences_unqualified_unresolved() async {
     verifyNoTestUnitErrors = false;
-    _indexTestUnit('''
+    await _indexTestUnit('''
 class A {
   m() {
     print(test);
@@ -249,7 +251,7 @@
   }
 
   test_indexDeclarations_afterIndexUnit() async {
-    resolveTestUnit('''
+    await resolveTestUnit('''
 var a = 0;
 var b = a + 1;
 ''');
@@ -275,13 +277,13 @@
   }
 
   test_indexDeclarations_nullUnitElement() async {
-    resolveTestUnit('');
+    await resolveTestUnit('');
     testUnit.element = null;
     index.indexDeclarations(testUnit);
   }
 
   test_indexUnit_nullLibraryElement() async {
-    resolveTestUnit('');
+    await resolveTestUnit('');
     CompilationUnitElement unitElement = new _CompilationUnitElementMock();
     expect(unitElement.library, isNull);
     testUnit.element = unitElement;
@@ -293,13 +295,13 @@
   }
 
   test_indexUnit_nullUnitElement() async {
-    resolveTestUnit('');
+    await resolveTestUnit('');
     testUnit.element = null;
     index.indexUnit(testUnit);
   }
 
   test_removeContext() async {
-    _indexTestUnit('''
+    await _indexTestUnit('''
 class A {}
 ''');
     RegExp regExp = new RegExp(r'^A$');
@@ -315,8 +317,8 @@
     RegExp regExp = new RegExp(r'^[AB]$');
     Source sourceA = addSource('/a.dart', 'class A {}');
     Source sourceB = addSource('/b.dart', 'class B {}');
-    CompilationUnit unitA = resolveLibraryUnit(sourceA);
-    CompilationUnit unitB = resolveLibraryUnit(sourceB);
+    CompilationUnit unitA = await resolveLibraryUnit(sourceA);
+    CompilationUnit unitB = await resolveLibraryUnit(sourceB);
     index.indexUnit(unitA);
     index.indexUnit(unitB);
     {
@@ -356,8 +358,8 @@
         '${locations.join('\n')}');
   }
 
-  void _indexTestUnit(String code, {bool declOnly: false}) {
-    resolveTestUnit(code);
+  Future<Null> _indexTestUnit(String code, {bool declOnly: false}) async {
+    await resolveTestUnit(code);
     if (declOnly) {
       index.indexDeclarations(testUnit);
     } else {
@@ -365,9 +367,9 @@
     }
   }
 
-  Source _indexUnit(String path, String code) {
+  Future<Source> _indexUnit(String path, String code) async {
     Source source = addSource(path, code);
-    CompilationUnit unit = resolveLibraryUnit(source);
+    CompilationUnit unit = await resolveLibraryUnit(source);
     index.indexUnit(unit);
     return source;
   }
diff --git a/pkg/analysis_server/test/services/index/index_unit_test.dart b/pkg/analysis_server/test/services/index/index_unit_test.dart
index 046bdfa..c225411 100644
--- a/pkg/analysis_server/test/services/index/index_unit_test.dart
+++ b/pkg/analysis_server/test/services/index/index_unit_test.dart
@@ -2,6 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+import 'dart:async';
 import 'dart:convert';
 
 import 'package:analysis_server/src/services/index/index_unit.dart';
@@ -55,99 +56,99 @@
     return imports[index].importedLibrary.definingCompilationUnit;
   }
 
-  void test_definedName_classMember_field() {
-    _indexTestUnit('''
+  test_definedName_classMember_field() async {
+    await _indexTestUnit('''
 class A {
   int f;
 }''');
     _assertDefinedName('f', IndexNameKind.classMember, 'f;');
   }
 
-  void test_definedName_classMember_getter() {
-    _indexTestUnit('''
+  test_definedName_classMember_getter() async {
+    await _indexTestUnit('''
 class A {
   int get g => 0;
 }''');
     _assertDefinedName('g', IndexNameKind.classMember, 'g => 0;');
   }
 
-  void test_definedName_classMember_method() {
-    _indexTestUnit('''
+  test_definedName_classMember_method() async {
+    await _indexTestUnit('''
 class A {
   m() {}
 }''');
     _assertDefinedName('m', IndexNameKind.classMember, 'm() {}');
   }
 
-  void test_definedName_classMember_operator() {
-    _indexTestUnit('''
+  test_definedName_classMember_operator() async {
+    await _indexTestUnit('''
 class A {
   operator +(o) {}
 }''');
     _assertDefinedName('+', IndexNameKind.classMember, '+(o) {}');
   }
 
-  void test_definedName_classMember_setter() {
-    _indexTestUnit('''
+  test_definedName_classMember_setter() async {
+    await _indexTestUnit('''
 class A {
   int set s (_) {}
 }''');
     _assertDefinedName('s', IndexNameKind.classMember, 's (_) {}');
   }
 
-  void test_definedName_topLevel_class() {
-    _indexTestUnit('class A {}');
+  test_definedName_topLevel_class() async {
+    await _indexTestUnit('class A {}');
     _assertDefinedName('A', IndexNameKind.topLevel, 'A {}');
   }
 
-  void test_definedName_topLevel_class2() {
-    _indexTestUnit('class A {}', declOnly: true);
+  test_definedName_topLevel_class2() async {
+    await _indexTestUnit('class A {}', declOnly: true);
     _assertDefinedName('A', IndexNameKind.topLevel, 'A {}');
   }
 
-  void test_definedName_topLevel_classAlias() {
-    _indexTestUnit('''
+  test_definedName_topLevel_classAlias() async {
+    await _indexTestUnit('''
 class M {}
 class C = Object with M;''');
     _assertDefinedName('C', IndexNameKind.topLevel, 'C =');
   }
 
-  void test_definedName_topLevel_enum() {
-    _indexTestUnit('enum E {a, b, c}');
+  test_definedName_topLevel_enum() async {
+    await _indexTestUnit('enum E {a, b, c}');
     _assertDefinedName('E', IndexNameKind.topLevel, 'E {');
   }
 
-  void test_definedName_topLevel_function() {
-    _indexTestUnit('foo() {}');
+  test_definedName_topLevel_function() async {
+    await _indexTestUnit('foo() {}');
     _assertDefinedName('foo', IndexNameKind.topLevel, 'foo() {}');
   }
 
-  void test_definedName_topLevel_functionTypeAlias() {
-    _indexTestUnit('typedef F(int p);');
+  test_definedName_topLevel_functionTypeAlias() async {
+    await _indexTestUnit('typedef F(int p);');
     _assertDefinedName('F', IndexNameKind.topLevel, 'F(int p);');
   }
 
-  void test_definedName_topLevel_getter() {
-    _indexTestUnit('''
+  test_definedName_topLevel_getter() async {
+    await _indexTestUnit('''
 int get g => 0;
 ''');
     _assertDefinedName('g', IndexNameKind.topLevel, 'g => 0;');
   }
 
-  void test_definedName_topLevel_setter() {
-    _indexTestUnit('''
+  test_definedName_topLevel_setter() async {
+    await _indexTestUnit('''
 int set s (_) {}
 ''');
     _assertDefinedName('s', IndexNameKind.topLevel, 's (_) {}');
   }
 
-  void test_definedName_topLevel_topLevelVariable() {
-    _indexTestUnit('var V = 42;');
+  test_definedName_topLevel_topLevelVariable() async {
+    await _indexTestUnit('var V = 42;');
     _assertDefinedName('V', IndexNameKind.topLevel, 'V = 42;');
   }
 
-  void test_hasAncestor_ClassDeclaration() {
-    _indexTestUnit('''
+  test_hasAncestor_ClassDeclaration() async {
+    await _indexTestUnit('''
 class A {}
 class B1 extends A {}
 class B2 implements A {}
@@ -168,8 +169,8 @@
       ..isAncestorOf('M extends Object with A');
   }
 
-  void test_hasAncestor_ClassTypeAlias() {
-    _indexTestUnit('''
+  test_hasAncestor_ClassTypeAlias() async {
+    await _indexTestUnit('''
 class A {}
 class B extends A {}
 class C1 = Object with A;
@@ -183,8 +184,8 @@
     assertThat(classElementB)..isAncestorOf('C2 = Object with B');
   }
 
-  void test_isExtendedBy_ClassDeclaration() {
-    _indexTestUnit('''
+  test_isExtendedBy_ClassDeclaration() async {
+    await _indexTestUnit('''
 class A {} // 1
 class B extends A {} // 2
 ''');
@@ -194,13 +195,13 @@
       ..isReferencedAt('A {} // 2', false);
   }
 
-  void test_isExtendedBy_ClassDeclaration_isQualified() {
+  test_isExtendedBy_ClassDeclaration_isQualified() async {
     addSource(
         '/lib.dart',
         '''
 class A {}
 ''');
-    _indexTestUnit('''
+    await _indexTestUnit('''
 import 'lib.dart' as p;
 class B extends p.A {} // 2
 ''');
@@ -208,8 +209,8 @@
     assertThat(elementA).isExtendedAt('A {} // 2', true);
   }
 
-  void test_isExtendedBy_ClassDeclaration_Object() {
-    _indexTestUnit('''
+  test_isExtendedBy_ClassDeclaration_Object() async {
+    await _indexTestUnit('''
 class A {}
 ''');
     ClassElement elementA = findElement('A');
@@ -217,8 +218,8 @@
     assertThat(elementObject).isExtendedAt('A {}', true, length: 0);
   }
 
-  void test_isExtendedBy_ClassTypeAlias() {
-    _indexTestUnit('''
+  test_isExtendedBy_ClassTypeAlias() async {
+    await _indexTestUnit('''
 class A {}
 class B {}
 class C = A with B;
@@ -229,13 +230,13 @@
       ..isReferencedAt('A with', false);
   }
 
-  void test_isExtendedBy_ClassTypeAlias_isQualified() {
+  test_isExtendedBy_ClassTypeAlias_isQualified() async {
     addSource(
         '/lib.dart',
         '''
 class A {}
 ''');
-    _indexTestUnit('''
+    await _indexTestUnit('''
 import 'lib.dart' as p;
 class B {}
 class C = p.A with B;
@@ -246,8 +247,8 @@
       ..isReferencedAt('A with', true);
   }
 
-  void test_isImplementedBy_ClassDeclaration() {
-    _indexTestUnit('''
+  test_isImplementedBy_ClassDeclaration() async {
+    await _indexTestUnit('''
 class A {} // 1
 class B implements A {} // 2
 ''');
@@ -257,13 +258,13 @@
       ..isReferencedAt('A {} // 2', false);
   }
 
-  void test_isImplementedBy_ClassDeclaration_isQualified() {
+  test_isImplementedBy_ClassDeclaration_isQualified() async {
     addSource(
         '/lib.dart',
         '''
 class A {}
 ''');
-    _indexTestUnit('''
+    await _indexTestUnit('''
 import 'lib.dart' as p;
 class B implements p.A {} // 2
 ''');
@@ -273,8 +274,8 @@
       ..isReferencedAt('A {} // 2', true);
   }
 
-  void test_isImplementedBy_ClassTypeAlias() {
-    _indexTestUnit('''
+  test_isImplementedBy_ClassTypeAlias() async {
+    await _indexTestUnit('''
 class A {} // 1
 class B {} // 2
 class C = Object with A implements B; // 3
@@ -285,8 +286,8 @@
       ..isReferencedAt('B; // 3', false);
   }
 
-  void test_isInvokedBy_FieldElement() {
-    _indexTestUnit('''
+  test_isInvokedBy_FieldElement() async {
+    await _indexTestUnit('''
 class A {
   var field;
   main() {
@@ -300,14 +301,14 @@
       ..isInvokedAt('field(); // nq', false);
   }
 
-  void test_isInvokedBy_FunctionElement() {
+  test_isInvokedBy_FunctionElement() async {
     addSource(
         '/lib.dart',
         '''
 library lib;
 foo() {}
 ''');
-    _indexTestUnit('''
+    await _indexTestUnit('''
 import 'lib.dart';
 import 'lib.dart' as pref;
 main() {
@@ -320,9 +321,9 @@
       ..isInvokedAt('foo(); // nq', false);
   }
 
-  void test_isInvokedBy_FunctionElement_synthetic_loadLibrary() {
+  test_isInvokedBy_FunctionElement_synthetic_loadLibrary() async {
     verifyNoTestUnitErrors = false;
-    _indexTestUnit('''
+    await _indexTestUnit('''
 import 'dart:math' deferred as math;
 main() {
   math.loadLibrary(); // 1
@@ -335,8 +336,8 @@
     assertThat(element).isInvokedAt('loadLibrary(); // 2', true);
   }
 
-  void test_isInvokedBy_MethodElement() {
-    _indexTestUnit('''
+  test_isInvokedBy_MethodElement() async {
+    await _indexTestUnit('''
 class A {
   foo() {}
   main() {
@@ -350,8 +351,8 @@
       ..isInvokedAt('foo(); // nq', false);
   }
 
-  void test_isInvokedBy_MethodElement_propagatedType() {
-    _indexTestUnit('''
+  test_isInvokedBy_MethodElement_propagatedType() async {
+    await _indexTestUnit('''
 class A {
   foo() {}
 }
@@ -364,8 +365,8 @@
     assertThat(element).isInvokedAt('foo();', true);
   }
 
-  void test_isInvokedBy_operator_binary() {
-    _indexTestUnit('''
+  test_isInvokedBy_operator_binary() async {
+    await _indexTestUnit('''
 class A {
   operator +(other) => this;
 }
@@ -384,8 +385,8 @@
       ..isInvokedAt('++;', true, length: 2);
   }
 
-  void test_isInvokedBy_operator_index() {
-    _indexTestUnit('''
+  test_isInvokedBy_operator_index() async {
+    await _indexTestUnit('''
 class A {
   operator [](i) => null;
   operator []=(i, v) {}
@@ -401,8 +402,8 @@
     assertThat(writeElement).isInvokedAt('[1]', true, length: 1);
   }
 
-  void test_isInvokedBy_operator_prefix() {
-    _indexTestUnit('''
+  test_isInvokedBy_operator_prefix() async {
+    await _indexTestUnit('''
 class A {
   A operator ~() => this;
 }
@@ -414,8 +415,8 @@
     assertThat(element).isInvokedAt('~a', true, length: 1);
   }
 
-  void test_isInvokedBy_PropertyAccessorElement_getter() {
-    _indexTestUnit('''
+  test_isInvokedBy_PropertyAccessorElement_getter() async {
+    await _indexTestUnit('''
 class A {
   get ggg => null;
   main() {
@@ -429,8 +430,8 @@
       ..isInvokedAt('ggg(); // nq', false);
   }
 
-  void test_isMixedInBy_ClassDeclaration() {
-    _indexTestUnit('''
+  test_isMixedInBy_ClassDeclaration() async {
+    await _indexTestUnit('''
 class A {} // 1
 class B extends Object with A {} // 2
 ''');
@@ -440,13 +441,13 @@
       ..isReferencedAt('A {} // 2', false);
   }
 
-  void test_isMixedInBy_ClassDeclaration_isQualified() {
+  test_isMixedInBy_ClassDeclaration_isQualified() async {
     addSource(
         '/lib.dart',
         '''
 class A {}
 ''');
-    _indexTestUnit('''
+    await _indexTestUnit('''
 import 'lib.dart' as p;
 class B extends Object with p.A {} // 2
 ''');
@@ -454,8 +455,8 @@
     assertThat(elementA).isMixedInAt('A {} // 2', true);
   }
 
-  void test_isMixedInBy_ClassTypeAlias() {
-    _indexTestUnit('''
+  test_isMixedInBy_ClassTypeAlias() async {
+    await _indexTestUnit('''
 class A {} // 1
 class B = Object with A; // 2
 ''');
@@ -463,8 +464,8 @@
     assertThat(elementA).isMixedInAt('A; // 2', false);
   }
 
-  void test_isReferencedBy_ClassElement() {
-    _indexTestUnit('''
+  test_isReferencedBy_ClassElement() async {
+    await _indexTestUnit('''
 class A {
   static var field;
 }
@@ -484,9 +485,9 @@
       ..isReferencedAt('A.field); // 3', false);
   }
 
-  void test_isReferencedBy_ClassElement_invocation() {
+  test_isReferencedBy_ClassElement_invocation() async {
     verifyNoTestUnitErrors = false;
-    _indexTestUnit('''
+    await _indexTestUnit('''
 class A {}
 main() {
   A(); // invalid code, but still a reference
@@ -495,14 +496,14 @@
     assertThat(element).isReferencedAt('A();', false);
   }
 
-  void test_isReferencedBy_ClassElement_invocation_isQualified() {
+  test_isReferencedBy_ClassElement_invocation_isQualified() async {
     verifyNoTestUnitErrors = false;
     addSource(
         '/lib.dart',
         '''
 class A {}
 ''');
-    _indexTestUnit('''
+    await _indexTestUnit('''
 import 'lib.dart' as p;
 main() {
   p.A(); // invalid code, but still a reference
@@ -511,8 +512,8 @@
     assertThat(element).isReferencedAt('A();', true);
   }
 
-  void test_isReferencedBy_ClassTypeAlias() {
-    _indexTestUnit('''
+  test_isReferencedBy_ClassTypeAlias() async {
+    await _indexTestUnit('''
 class A {}
 class B = Object with A;
 main(B p) {
@@ -525,35 +526,35 @@
       ..isReferencedAt('B v;', false);
   }
 
-  void test_isReferencedBy_CompilationUnitElement_export() {
+  test_isReferencedBy_CompilationUnitElement_export() async {
     addSource(
         '/lib.dart',
         '''
 library lib;
 ''');
-    _indexTestUnit('''
+    await _indexTestUnit('''
 export 'lib.dart';
 ''');
     LibraryElement element = testLibraryElement.exports[0].exportedLibrary;
     assertThat(element)..isReferencedAt("'lib.dart'", true, length: 10);
   }
 
-  void test_isReferencedBy_CompilationUnitElement_import() {
+  test_isReferencedBy_CompilationUnitElement_import() async {
     addSource(
         '/lib.dart',
         '''
 library lib;
 ''');
-    _indexTestUnit('''
+    await _indexTestUnit('''
 import 'lib.dart';
 ''');
     LibraryElement element = testLibraryElement.imports[0].importedLibrary;
     assertThat(element)..isReferencedAt("'lib.dart'", true, length: 10);
   }
 
-  void test_isReferencedBy_CompilationUnitElement_part() {
+  test_isReferencedBy_CompilationUnitElement_part() async {
     addSource('/my_unit.dart', 'part of my_lib;');
-    _indexTestUnit('''
+    await _indexTestUnit('''
 library my_lib;
 part 'my_unit.dart';
 ''');
@@ -561,8 +562,8 @@
     assertThat(element)..isReferencedAt("'my_unit.dart';", true, length: 14);
   }
 
-  void test_isReferencedBy_ConstructorElement() {
-    _indexTestUnit('''
+  test_isReferencedBy_ConstructorElement() async {
+    await _indexTestUnit('''
 class A implements B {
   A() {}
   A.foo() {}
@@ -593,8 +594,8 @@
       ..isReferencedAt('.foo(); // 5', true, length: 4);
   }
 
-  void test_isReferencedBy_ConstructorElement_classTypeAlias() {
-    _indexTestUnit('''
+  test_isReferencedBy_ConstructorElement_classTypeAlias() async {
+    await _indexTestUnit('''
 class M {}
 class A implements B {
   A() {}
@@ -620,8 +621,8 @@
       ..isReferencedAt('.named(); // C2', true, length: 6);
   }
 
-  void test_isReferencedBy_ConstructorElement_classTypeAlias_cycle() {
-    _indexTestUnit('''
+  test_isReferencedBy_ConstructorElement_classTypeAlias_cycle() async {
+    await _indexTestUnit('''
 class M {}
 class A = B with M;
 class B = A with M;
@@ -633,8 +634,8 @@
     // No additional validation, but it should not fail with stack overflow.
   }
 
-  void test_isReferencedBy_ConstructorElement_namedOnlyWithDot() {
-    _indexTestUnit('''
+  test_isReferencedBy_ConstructorElement_namedOnlyWithDot() async {
+    await _indexTestUnit('''
 class A {
   A.named() {}
 }
@@ -649,8 +650,8 @@
     expect(unitIndex.usedElementOffsets, contains(offsetWithDot));
   }
 
-  void test_isReferencedBy_ConstructorElement_redirection() {
-    _indexTestUnit('''
+  test_isReferencedBy_ConstructorElement_redirection() async {
+    await _indexTestUnit('''
 class A {
   A() : this.bar(); // 1
   A.foo() : this(); // 2
@@ -664,8 +665,8 @@
     assertThat(constA_bar).isReferencedAt('.bar(); // 1', true, length: 4);
   }
 
-  void test_isReferencedBy_ConstructorElement_synthetic() {
-    _indexTestUnit('''
+  test_isReferencedBy_ConstructorElement_synthetic() async {
+    await _indexTestUnit('''
 class A {}
 main() {
   new A(); // 1
@@ -677,15 +678,15 @@
     assertThat(constA)..isReferencedAt('(); // 1', true, length: 0);
   }
 
-  void test_isReferencedBy_DynamicElement() {
-    _indexTestUnit('''
+  test_isReferencedBy_DynamicElement() async {
+    await _indexTestUnit('''
 dynamic f() {
 }''');
     expect(unitIndex.usedElementOffsets, isEmpty);
   }
 
-  void test_isReferencedBy_FieldElement() {
-    _indexTestUnit('''
+  test_isReferencedBy_FieldElement() async {
+    await _indexTestUnit('''
 class A {
   var field;
   A({this.field});
@@ -714,8 +715,8 @@
     assertThat(field)..isReferencedAt('field: 4', true);
   }
 
-  void test_isReferencedBy_FieldElement_multiple() {
-    _indexTestUnit('''
+  test_isReferencedBy_FieldElement_multiple() async {
+    await _indexTestUnit('''
 class A {
   var aaa;
   var bbb;
@@ -748,9 +749,9 @@
     }
   }
 
-  void test_isReferencedBy_FieldElement_ofEnum() {
+  test_isReferencedBy_FieldElement_ofEnum() async {
     verifyNoTestUnitErrors = false;
-    _indexTestUnit('''
+    await _indexTestUnit('''
 enum MyEnum {
   A, B, C
 }
@@ -769,9 +770,9 @@
     assertThat(enumElement.getGetter('B'))..isReferencedAt('B);', true);
   }
 
-  void test_isReferencedBy_FieldElement_synthetic_hasGetter() {
+  test_isReferencedBy_FieldElement_synthetic_hasGetter() async {
     verifyNoTestUnitErrors = false;
-    _indexTestUnit('''
+    await _indexTestUnit('''
 class A {
   A() : f = 42;
   int get f => 0;
@@ -781,9 +782,9 @@
     assertThat(element2.getField('f')).isWrittenAt('f = 42', true);
   }
 
-  void test_isReferencedBy_FieldElement_synthetic_hasGetterSetter() {
+  test_isReferencedBy_FieldElement_synthetic_hasGetterSetter() async {
     verifyNoTestUnitErrors = false;
-    _indexTestUnit('''
+    await _indexTestUnit('''
 class A {
   A() : f = 42;
   int get f => 0;
@@ -794,9 +795,9 @@
     assertThat(element2.getField('f')).isWrittenAt('f = 42', true);
   }
 
-  void test_isReferencedBy_FieldElement_synthetic_hasSetter() {
+  test_isReferencedBy_FieldElement_synthetic_hasSetter() async {
     verifyNoTestUnitErrors = false;
-    _indexTestUnit('''
+    await _indexTestUnit('''
 class A {
   A() : f = 42;
   set f(_) {}
@@ -806,8 +807,8 @@
     assertThat(element2.getField('f')).isWrittenAt('f = 42', true);
   }
 
-  void test_isReferencedBy_FunctionElement() {
-    _indexTestUnit('''
+  test_isReferencedBy_FunctionElement() async {
+    await _indexTestUnit('''
 foo() {}
 main() {
   print(foo);
@@ -820,13 +821,13 @@
       ..isInvokedAt('foo());', false);
   }
 
-  void test_isReferencedBy_FunctionElement_with_LibraryElement() {
+  test_isReferencedBy_FunctionElement_with_LibraryElement() async {
     addSource(
         '/foo.dart',
         r'''
 bar() {}
 ''');
-    _indexTestUnit('''
+    await _indexTestUnit('''
 import "foo.dart";
 main() {
   bar();
@@ -840,8 +841,8 @@
     }
   }
 
-  void test_isReferencedBy_FunctionTypeAliasElement() {
-    _indexTestUnit('''
+  test_isReferencedBy_FunctionTypeAliasElement() async {
+    await _indexTestUnit('''
 typedef A();
 main(A p) {
 }
@@ -857,8 +858,8 @@
    * This caused duplicate indexing.
    * Here we test that the problem is fixed one way or another.
    */
-  void test_isReferencedBy_identifierInComment() {
-    _indexTestUnit('''
+  test_isReferencedBy_identifierInComment() async {
+    await _indexTestUnit('''
 class A {}
 /// [A] text
 var myVariable = null;
@@ -867,8 +868,8 @@
     assertThat(element)..isReferencedAt('A] text', false);
   }
 
-  void test_isReferencedBy_MethodElement() {
-    _indexTestUnit('''
+  test_isReferencedBy_MethodElement() async {
+    await _indexTestUnit('''
 class A {
   method() {}
   main() {
@@ -882,8 +883,8 @@
       ..isReferencedAt('method); // nq', false);
   }
 
-  void test_isReferencedBy_ParameterElement() {
-    _indexTestUnit('''
+  test_isReferencedBy_ParameterElement() async {
+    await _indexTestUnit('''
 foo({var p}) {}
 main() {
   foo(p: 1);
@@ -893,14 +894,14 @@
     assertThat(element)..isReferencedAt('p: 1', true);
   }
 
-  void test_isReferencedBy_TopLevelVariableElement() {
+  test_isReferencedBy_TopLevelVariableElement() async {
     addSource(
         '/lib.dart',
         '''
 library lib;
 var V;
 ''');
-    _indexTestUnit('''
+    await _indexTestUnit('''
 import 'lib.dart' show V; // imp
 import 'lib.dart' as pref;
 main() {
@@ -919,7 +920,7 @@
       ..isReferencedAt('V = 5; // nq', false);
   }
 
-  void test_isReferencedBy_TopLevelVariableElement_synthetic_hasGetterSetter() {
+  test_isReferencedBy_TopLevelVariableElement_synthetic_hasGetterSetter() async {
     verifyNoTestUnitErrors = false;
     addSource(
         '/lib.dart',
@@ -927,29 +928,29 @@
 int get V => 0;
 void set V(_) {}
 ''');
-    _indexTestUnit('''
+    await _indexTestUnit('''
 import 'lib.dart' show V;
 ''');
     TopLevelVariableElement element = importedUnit().topLevelVariables[0];
     assertThat(element).isReferencedAt('V;', true);
   }
 
-  void test_isReferencedBy_TopLevelVariableElement_synthetic_hasSetter() {
+  test_isReferencedBy_TopLevelVariableElement_synthetic_hasSetter() async {
     verifyNoTestUnitErrors = false;
     addSource(
         '/lib.dart',
         '''
 void set V(_) {}
 ''');
-    _indexTestUnit('''
+    await _indexTestUnit('''
 import 'lib.dart' show V;
 ''');
     TopLevelVariableElement element = importedUnit().topLevelVariables[0];
     assertThat(element).isReferencedAt('V;', true);
   }
 
-  void test_isReferencedBy_typeInVariableList() {
-    _indexTestUnit('''
+  test_isReferencedBy_typeInVariableList() async {
+    await _indexTestUnit('''
 class A {}
 A myVariable = null;
 ''');
@@ -957,8 +958,8 @@
     assertThat(element).isReferencedAt('A myVariable', false);
   }
 
-  void test_isWrittenBy_FieldElement() {
-    _indexTestUnit('''
+  test_isWrittenBy_FieldElement() async {
+    await _indexTestUnit('''
 class A {
   int field;
   A.foo({this.field});
@@ -971,9 +972,9 @@
       ..isWrittenAt('field = 5', true);
   }
 
-  void test_usedName_inLibraryIdentifier() {
+  test_usedName_inLibraryIdentifier() async {
     verifyNoTestUnitErrors = false;
-    _indexTestUnit('''
+    await _indexTestUnit('''
 library aaa.bbb.ccc;
 class C {
   var bbb;
@@ -987,9 +988,9 @@
       ..isUsedQ('bbb = 1;', IndexRelationKind.IS_WRITTEN_BY);
   }
 
-  void test_usedName_qualified_resolved() {
+  test_usedName_qualified_resolved() async {
     verifyNoTestUnitErrors = false;
-    _indexTestUnit('''
+    await _indexTestUnit('''
 class C {
   var x;
 }
@@ -1007,9 +1008,9 @@
       ..isNotUsedQ('x();', IndexRelationKind.IS_INVOKED_BY);
   }
 
-  void test_usedName_qualified_unresolved() {
+  test_usedName_qualified_unresolved() async {
     verifyNoTestUnitErrors = false;
-    _indexTestUnit('''
+    await _indexTestUnit('''
 main(p) {
   p.x;
   p.x = 1;
@@ -1024,9 +1025,9 @@
       ..isUsedQ('x();', IndexRelationKind.IS_INVOKED_BY);
   }
 
-  void test_usedName_unqualified_resolved() {
+  test_usedName_unqualified_resolved() async {
     verifyNoTestUnitErrors = false;
-    _indexTestUnit('''
+    await _indexTestUnit('''
 class C {
   var x;
   m() {
@@ -1044,9 +1045,9 @@
       ..isNotUsedQ('x();', IndexRelationKind.IS_INVOKED_BY);
   }
 
-  void test_usedName_unqualified_unresolved() {
+  test_usedName_unqualified_unresolved() async {
     verifyNoTestUnitErrors = false;
-    _indexTestUnit('''
+    await _indexTestUnit('''
 main() {
   x;
   x = 1;
@@ -1217,8 +1218,8 @@
     return _getStringId(str);
   }
 
-  void _indexTestUnit(String code, {bool declOnly: false}) {
-    resolveTestUnit(code);
+  Future<Null> _indexTestUnit(String code, {bool declOnly: false}) async {
+    await resolveTestUnit(code);
     PackageIndexAssembler assembler = new PackageIndexAssembler();
     if (declOnly) {
       assembler.indexDeclarations(testUnit);
diff --git a/pkg/analysis_server/test/services/refactoring/abstract_refactoring.dart b/pkg/analysis_server/test/services/refactoring/abstract_refactoring.dart
index 793a1ec..a57c988 100644
--- a/pkg/analysis_server/test/services/refactoring/abstract_refactoring.dart
+++ b/pkg/analysis_server/test/services/refactoring/abstract_refactoring.dart
@@ -16,7 +16,9 @@
 import 'package:analysis_server/src/services/correction/status.dart';
 import 'package:analysis_server/src/services/index/index.dart';
 import 'package:analysis_server/src/services/refactoring/refactoring.dart';
+import 'package:analysis_server/src/services/search/search_engine.dart';
 import 'package:analysis_server/src/services/search/search_engine_internal.dart';
+import 'package:analysis_server/src/services/search/search_engine_internal2.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/element/element.dart' show Element;
 import 'package:analyzer/file_system/file_system.dart';
@@ -44,7 +46,7 @@
  */
 abstract class RefactoringTest extends AbstractSingleUnitTest {
   Index index;
-  SearchEngineImpl searchEngine;
+  SearchEngine searchEngine;
 
   SourceChange refactoringChange;
 
@@ -60,8 +62,7 @@
     expect(fileEdit, isNotNull, reason: 'No file edit for $path');
     // validate resulting code
     File file = provider.getResource(path);
-    Source source = file.createSource();
-    String ini = context.getContents(source).data;
+    String ini = file.readAsStringSync();
     String actualCode = SourceEdit.applySequence(ini, fileEdit.edits);
     expect(actualCode, expectedCode);
   }
@@ -160,20 +161,28 @@
         .resolveCompilationUnit(element.source, element.library);
   }
 
-  void indexTestUnit(String code) {
-    resolveTestUnit(code);
-    index.indexUnit(testUnit);
+  Future<Null> indexTestUnit(String code) async {
+    await resolveTestUnit(code);
+    if (!enableNewAnalysisDriver) {
+      index.indexUnit(testUnit);
+    }
   }
 
-  void indexUnit(String file, String code) {
+  Future<Null> indexUnit(String file, String code) async {
     Source source = addSource(file, code);
-    CompilationUnit unit = resolveLibraryUnit(source);
-    index.indexUnit(unit);
+    if (!enableNewAnalysisDriver) {
+      CompilationUnit unit = await resolveLibraryUnit(source);
+      index.indexUnit(unit);
+    }
   }
 
   void setUp() {
     super.setUp();
-    index = createMemoryIndex();
-    searchEngine = new SearchEngineImpl(index);
+    if (enableNewAnalysisDriver) {
+      searchEngine = new SearchEngineImpl2([driver]);
+    } else {
+      index = createMemoryIndex();
+      searchEngine = new SearchEngineImpl(index);
+    }
   }
 }
diff --git a/pkg/analysis_server/test/services/refactoring/convert_getter_to_method_test.dart b/pkg/analysis_server/test/services/refactoring/convert_getter_to_method_test.dart
index 9b74f44..9fb67da 100644
--- a/pkg/analysis_server/test/services/refactoring/convert_getter_to_method_test.dart
+++ b/pkg/analysis_server/test/services/refactoring/convert_getter_to_method_test.dart
@@ -17,6 +17,7 @@
 main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(ConvertGetterToMethodTest);
+    defineReflectiveTests(ConvertGetterToMethodTest_Driver);
   });
 }
 
@@ -24,8 +25,8 @@
 class ConvertGetterToMethodTest extends RefactoringTest {
   ConvertGetterToMethodRefactoring refactoring;
 
-  test_change_function() {
-    indexTestUnit('''
+  test_change_function() async {
+    await indexTestUnit('''
 int get test => 42;
 main() {
   var a = test;
@@ -43,8 +44,8 @@
 ''');
   }
 
-  test_change_method() {
-    indexTestUnit('''
+  test_change_method() async {
+    await indexTestUnit('''
 class A {
   int get test => 1;
 }
@@ -88,15 +89,15 @@
 ''');
   }
 
-  test_change_multipleFiles() {
-    indexUnit(
+  test_change_multipleFiles() async {
+    await indexUnit(
         '/other.dart',
         r'''
 class A {
   int get test => 1;
 }
 ''');
-    indexTestUnit('''
+    await indexTestUnit('''
 import 'other.dart';
 class B extends A {
   int get test => 2;
@@ -120,8 +121,8 @@
 ''');
   }
 
-  test_checkInitialConditions_syntheticGetter() {
-    indexTestUnit('''
+  test_checkInitialConditions_syntheticGetter() async {
+    await indexTestUnit('''
 int test = 42;
 main() {
 }
@@ -164,3 +165,9 @@
     _createRefactoringForElement(element);
   }
 }
+
+@reflectiveTest
+class ConvertGetterToMethodTest_Driver extends ConvertGetterToMethodTest {
+  @override
+  bool get enableNewAnalysisDriver => true;
+}
diff --git a/pkg/analysis_server/test/services/refactoring/convert_method_to_getter_test.dart b/pkg/analysis_server/test/services/refactoring/convert_method_to_getter_test.dart
index 30bbb5b..313fe30 100644
--- a/pkg/analysis_server/test/services/refactoring/convert_method_to_getter_test.dart
+++ b/pkg/analysis_server/test/services/refactoring/convert_method_to_getter_test.dart
@@ -18,6 +18,7 @@
 main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(ConvertMethodToGetterTest);
+    defineReflectiveTests(ConvertMethodToGetterTest_Driver);
   });
 }
 
@@ -25,8 +26,8 @@
 class ConvertMethodToGetterTest extends RefactoringTest {
   ConvertMethodToGetterRefactoring refactoring;
 
-  test_change_function() {
-    indexTestUnit('''
+  test_change_function() async {
+    await indexTestUnit('''
 int test() => 42;
 main() {
   var a = test();
@@ -44,8 +45,8 @@
 ''');
   }
 
-  test_change_method() {
-    indexTestUnit('''
+  test_change_method() async {
+    await indexTestUnit('''
 class A {
   int test() => 1;
 }
@@ -89,15 +90,15 @@
 ''');
   }
 
-  test_change_multipleFiles() {
-    indexUnit(
+  test_change_multipleFiles() async {
+    await indexUnit(
         '/other.dart',
         r'''
 class A {
   int test() => 1;
 }
 ''');
-    indexTestUnit('''
+    await indexTestUnit('''
 import 'other.dart';
 class B extends A {
   int test() => 2;
@@ -121,8 +122,8 @@
 ''');
   }
 
-  test_checkInitialConditions_alreadyGetter() {
-    indexTestUnit('''
+  test_checkInitialConditions_alreadyGetter() async {
+    await indexTestUnit('''
 int get test => 42;
 main() {
   var a = test;
@@ -136,8 +137,8 @@
         'Only class methods or top-level functions can be converted to getters.');
   }
 
-  test_checkInitialConditions_hasParameters() {
-    indexTestUnit('''
+  test_checkInitialConditions_hasParameters() async {
+    await indexTestUnit('''
 int test(x) => x * 2;
 main() {
   var v = test(1);
@@ -149,8 +150,8 @@
         'Only methods without parameters can be converted to getters.');
   }
 
-  test_checkInitialConditions_localFunction() {
-    indexTestUnit('''
+  test_checkInitialConditions_localFunction() async {
+    await indexTestUnit('''
 main() {
   test() {}
   var v = test();
@@ -162,8 +163,8 @@
         'Only top-level functions can be converted to getters.');
   }
 
-  test_checkInitialConditions_notFunctionOrMethod() {
-    indexTestUnit('''
+  test_checkInitialConditions_notFunctionOrMethod() async {
+    await indexTestUnit('''
 class A {
   A.test();
 }
@@ -174,8 +175,8 @@
         'Only class methods or top-level functions can be converted to getters.');
   }
 
-  test_checkInitialConditions_returnTypeVoid() {
-    indexTestUnit('''
+  test_checkInitialConditions_returnTypeVoid() async {
+    await indexTestUnit('''
 void test() {}
 ''');
     _createRefactoring('test');
@@ -215,3 +216,9 @@
     _createRefactoringForElement(element);
   }
 }
+
+@reflectiveTest
+class ConvertMethodToGetterTest_Driver extends ConvertMethodToGetterTest {
+  @override
+  bool get enableNewAnalysisDriver => true;
+}
diff --git a/pkg/analysis_server/test/services/refactoring/extract_local_test.dart b/pkg/analysis_server/test/services/refactoring/extract_local_test.dart
index 976e77d..9658c09 100644
--- a/pkg/analysis_server/test/services/refactoring/extract_local_test.dart
+++ b/pkg/analysis_server/test/services/refactoring/extract_local_test.dart
@@ -19,6 +19,7 @@
 main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(ExtractLocalTest);
+    defineReflectiveTests(ExtractLocalTest_Driver);
   });
 }
 
@@ -27,7 +28,7 @@
   ExtractLocalRefactoringImpl refactoring;
 
   test_checkFinalConditions_sameVariable_after() async {
-    indexTestUnit('''
+    await indexTestUnit('''
 main() {
   int a = 1 + 2;
   var res;
@@ -41,7 +42,7 @@
   }
 
   test_checkFinalConditions_sameVariable_before() async {
-    indexTestUnit('''
+    await indexTestUnit('''
 main() {
   var res;
   int a = 1 + 2;
@@ -55,7 +56,7 @@
   }
 
   test_checkInitialConditions_assignmentLeftHandSize() async {
-    indexTestUnit('''
+    await indexTestUnit('''
 main() {
   var v = 0;
   v = 1;
@@ -69,7 +70,7 @@
   }
 
   test_checkInitialConditions_namePartOfDeclaration_function() async {
-    indexTestUnit('''
+    await indexTestUnit('''
 main() {
 }
 ''');
@@ -81,7 +82,7 @@
   }
 
   test_checkInitialConditions_namePartOfDeclaration_variable() async {
-    indexTestUnit('''
+    await indexTestUnit('''
 main() {
   int vvv = 0;
 }
@@ -94,7 +95,7 @@
   }
 
   test_checkInitialConditions_noExpression() async {
-    indexTestUnit('''
+    await indexTestUnit('''
 main() {
   // abc
 }
@@ -105,7 +106,7 @@
   }
 
   test_checkInitialConditions_notPartOfFunction() async {
-    indexTestUnit('''
+    await indexTestUnit('''
 int a = 1 + 2;
 ''');
     _createRefactoringForString('1 + 2');
@@ -117,7 +118,7 @@
   }
 
   test_checkInitialConditions_stringSelection_leadingQuote() async {
-    indexTestUnit('''
+    await indexTestUnit('''
 main() {
   var vvv = 'abc';
 }
@@ -133,7 +134,7 @@
   }
 
   test_checkInitialConditions_stringSelection_trailingQuote() async {
-    indexTestUnit('''
+    await indexTestUnit('''
 main() {
   var vvv = 'abc';
 }
@@ -149,7 +150,7 @@
   }
 
   test_checkInitialConditions_voidExpression() async {
-    indexTestUnit('''
+    await indexTestUnit('''
 main() {
   print(42);
 }
@@ -161,8 +162,8 @@
         expectedMessage: 'Cannot extract the void expression.');
   }
 
-  test_checkName() {
-    indexTestUnit('''
+  test_checkName() async {
+    await indexTestUnit('''
 main() {
   int a = 1 + 2;
 }
@@ -185,7 +186,7 @@
   }
 
   test_checkName_conflict_withInvokedFunction() async {
-    indexTestUnit('''
+    await indexTestUnit('''
 main() {
   int a = 1 + 2;
   res();
@@ -202,7 +203,7 @@
   }
 
   test_checkName_conflict_withOtherLocal() async {
-    indexTestUnit('''
+    await indexTestUnit('''
 main() {
   var res;
   int a = 1 + 2;
@@ -217,7 +218,7 @@
   }
 
   test_checkName_conflict_withTypeName() async {
-    indexTestUnit('''
+    await indexTestUnit('''
 main() {
   int a = 1 + 2;
   Res b = null;
@@ -233,8 +234,8 @@
         expectedMessage: "The name 'Res' is already used in the scope.");
   }
 
-  test_completeStatementExpression() {
-    indexTestUnit('''
+  test_completeStatementExpression() async {
+    await indexTestUnit('''
 main(p) {
   p.toString();
 }
@@ -248,8 +249,8 @@
 ''');
   }
 
-  test_const_argument_inConstInstanceCreation() {
-    indexTestUnit('''
+  test_const_argument_inConstInstanceCreation() async {
+    await indexTestUnit('''
 class A {
   const A(int a, int b);
 }
@@ -270,8 +271,8 @@
 ''');
   }
 
-  test_const_inList() {
-    indexTestUnit('''
+  test_const_inList() async {
+    await indexTestUnit('''
 main() {
   const [1, 2];
 }
@@ -286,8 +287,8 @@
 ''');
   }
 
-  test_const_inList_inBinaryExpression() {
-    indexTestUnit('''
+  test_const_inList_inBinaryExpression() async {
+    await indexTestUnit('''
 main() {
   const [1 + 2, 3];
 }
@@ -302,8 +303,8 @@
 ''');
   }
 
-  test_const_inList_inConditionalExpression() {
-    indexTestUnit('''
+  test_const_inList_inConditionalExpression() async {
+    await indexTestUnit('''
 main() {
   const [true ? 1 : 2, 3];
 }
@@ -318,8 +319,8 @@
 ''');
   }
 
-  test_const_inList_inParenthesis() {
-    indexTestUnit('''
+  test_const_inList_inParenthesis() async {
+    await indexTestUnit('''
 main() {
   const [(1), 2];
 }
@@ -334,8 +335,8 @@
 ''');
   }
 
-  test_const_inList_inPrefixExpression() {
-    indexTestUnit('''
+  test_const_inList_inPrefixExpression() async {
+    await indexTestUnit('''
 main() {
   const [!true, 2];
 }
@@ -350,8 +351,8 @@
 ''');
   }
 
-  test_const_inMap_key() {
-    indexTestUnit('''
+  test_const_inMap_key() async {
+    await indexTestUnit('''
 main() {
   const {1: 2};
 }
@@ -366,8 +367,8 @@
 ''');
   }
 
-  test_const_inMap_value() {
-    indexTestUnit('''
+  test_const_inMap_value() async {
+    await indexTestUnit('''
 main() {
   const {1: 2};
 }
@@ -383,7 +384,7 @@
   }
 
   test_coveringExpressions() async {
-    indexTestUnit('''
+    await indexTestUnit('''
 main() {
   int aaa = 1;
   int bbb = 2;
@@ -399,7 +400,7 @@
   }
 
   test_coveringExpressions_inArgumentList() async {
-    indexTestUnit('''
+    await indexTestUnit('''
 main() {
   foo(111 + 222);
 }
@@ -413,7 +414,7 @@
   }
 
   test_coveringExpressions_inInvocationOfVoidFunction() async {
-    indexTestUnit('''
+    await indexTestUnit('''
 main() {
   foo(111 + 222);
 }
@@ -427,7 +428,7 @@
   }
 
   test_coveringExpressions_namedExpression_value() async {
-    indexTestUnit('''
+    await indexTestUnit('''
 main() {
   foo(ppp: 42);
 }
@@ -441,7 +442,7 @@
   }
 
   test_coveringExpressions_skip_assignment() async {
-    indexTestUnit('''
+    await indexTestUnit('''
 main() {
   int v;
   foo(v = 111 + 222);
@@ -456,12 +457,12 @@
   }
 
   test_coveringExpressions_skip_constructorName() async {
-    indexTestUnit('''
+    await indexTestUnit('''
 class AAA {
   AAA.name() {}
 }
 main() {
-  int v = new AAA.name();
+  var v = new AAA.name();
 }
 ''');
     _createRefactoring(testCode.indexOf('AA.name();'), 5);
@@ -472,12 +473,12 @@
   }
 
   test_coveringExpressions_skip_constructorName_name() async {
-    indexTestUnit('''
+    await indexTestUnit('''
 class A {
   A.name() {}
 }
 main() {
-  int v = new A.name();
+  var v = new A.name();
 }
 ''');
     _createRefactoring(testCode.indexOf('ame();'), 0);
@@ -488,10 +489,10 @@
   }
 
   test_coveringExpressions_skip_constructorName_type() async {
-    indexTestUnit('''
+    await indexTestUnit('''
 class A {}
 main() {
-  int v = new A();
+  var v = new A();
 }
 ''');
     _createRefactoring(testCode.indexOf('A();'), 0);
@@ -502,10 +503,10 @@
   }
 
   test_coveringExpressions_skip_constructorName_typeArgument() async {
-    indexTestUnit('''
+    await indexTestUnit('''
 class A<T> {}
 main() {
-  int v = new A<String>();
+  var v = new A<String>();
 }
 ''');
     _createRefactoring(testCode.indexOf('ring>'), 0);
@@ -516,7 +517,7 @@
   }
 
   test_coveringExpressions_skip_namedExpression() async {
-    indexTestUnit('''
+    await indexTestUnit('''
 main() {
   foo(ppp: 42);
 }
@@ -529,8 +530,8 @@
     expect(subExpressions, ['foo(ppp: 42)']);
   }
 
-  test_fragmentExpression() {
-    indexTestUnit('''
+  test_fragmentExpression() async {
+    await indexTestUnit('''
 main() {
   int a = 1 + 2 + 3 + 4;
 }
@@ -545,8 +546,8 @@
 ''');
   }
 
-  test_fragmentExpression_leadingNotWhitespace() {
-    indexTestUnit('''
+  test_fragmentExpression_leadingNotWhitespace() async {
+    await indexTestUnit('''
 main() {
   int a = 1 + 2 + 3 + 4;
 }
@@ -561,8 +562,8 @@
 ''');
   }
 
-  test_fragmentExpression_leadingPartialSelection() {
-    indexTestUnit('''
+  test_fragmentExpression_leadingPartialSelection() async {
+    await indexTestUnit('''
 main() {
   int a = 111 + 2 + 3 + 4;
 }
@@ -577,8 +578,8 @@
 ''');
   }
 
-  test_fragmentExpression_leadingWhitespace() {
-    indexTestUnit('''
+  test_fragmentExpression_leadingWhitespace() async {
+    await indexTestUnit('''
 main() {
   int a = 1 + 2 + 3 + 4;
 }
@@ -593,8 +594,8 @@
 ''');
   }
 
-  test_fragmentExpression_notAssociativeOperator() {
-    indexTestUnit('''
+  test_fragmentExpression_notAssociativeOperator() async {
+    await indexTestUnit('''
 main() {
   int a = 1 - 2 - 3 - 4;
 }
@@ -609,8 +610,8 @@
 ''');
   }
 
-  test_fragmentExpression_trailingNotWhitespace() {
-    indexTestUnit('''
+  test_fragmentExpression_trailingNotWhitespace() async {
+    await indexTestUnit('''
 main() {
   int a = 1 + 2 + 3 + 4;
 }
@@ -625,8 +626,8 @@
 ''');
   }
 
-  test_fragmentExpression_trailingPartialSelection() {
-    indexTestUnit('''
+  test_fragmentExpression_trailingPartialSelection() async {
+    await indexTestUnit('''
 main() {
   int a = 1 + 2 + 333 + 4;
 }
@@ -641,8 +642,8 @@
 ''');
   }
 
-  test_fragmentExpression_trailingWhitespace() {
-    indexTestUnit('''
+  test_fragmentExpression_trailingWhitespace() async {
+    await indexTestUnit('''
 main() {
   int a = 1 + 2 + 3 + 4;
 }
@@ -658,7 +659,7 @@
   }
 
   test_guessNames_fragmentExpression() async {
-    indexTestUnit('''
+    await indexTestUnit('''
 main() {
   var a = 111 + 222 + 333 + 444;
 }
@@ -670,7 +671,7 @@
   }
 
   test_guessNames_singleExpression() async {
-    indexTestUnit('''
+    await indexTestUnit('''
 class TreeItem {}
 TreeItem getSelectedItem() => null;
 process(my) {}
@@ -686,7 +687,7 @@
   }
 
   test_guessNames_stringPart() async {
-    indexTestUnit('''
+    await indexTestUnit('''
 main() {
   var s = 'Hello Bob... welcome to Dart!';
 }
@@ -698,7 +699,7 @@
   }
 
   test_occurrences_differentVariable() async {
-    indexTestUnit('''
+    await indexTestUnit('''
 main() {
   {
     int v = 1;
@@ -731,8 +732,8 @@
         length: 3, offsets: [36, 59, 85], names: ['object', 'i']);
   }
 
-  test_occurrences_disableOccurrences() {
-    indexTestUnit('''
+  test_occurrences_disableOccurrences() async {
+    await indexTestUnit('''
 int foo() => 42;
 main() {
   int a = 1 + foo();
@@ -752,8 +753,8 @@
 ''');
   }
 
-  test_occurrences_ignore_assignmentLeftHandSize() {
-    indexTestUnit('''
+  test_occurrences_ignore_assignmentLeftHandSize() async {
+    await indexTestUnit('''
 main() {
   int v = 1;
   v = 2;
@@ -776,8 +777,8 @@
 ''');
   }
 
-  test_occurrences_ignore_nameOfVariableDeclaration() {
-    indexTestUnit('''
+  test_occurrences_ignore_nameOfVariableDeclaration() async {
+    await indexTestUnit('''
 main() {
   int v = 1;
   print(v); // marker
@@ -794,8 +795,8 @@
 ''');
   }
 
-  test_occurrences_singleExpression() {
-    indexTestUnit('''
+  test_occurrences_singleExpression() async {
+    await indexTestUnit('''
 int foo() => 42;
 main() {
   int a = 1 + foo();
@@ -814,8 +815,8 @@
 ''');
   }
 
-  test_occurrences_useDominator() {
-    indexTestUnit('''
+  test_occurrences_useDominator() async {
+    await indexTestUnit('''
 main() {
   if (true) {
     print(42);
@@ -838,8 +839,8 @@
 ''');
   }
 
-  test_occurrences_whenComment() {
-    indexTestUnit('''
+  test_occurrences_whenComment() async {
+    await indexTestUnit('''
 int foo() => 42;
 main() {
   /*int a = 1 + foo();*/
@@ -858,8 +859,8 @@
 ''');
   }
 
-  test_occurrences_withSpace() {
-    indexTestUnit('''
+  test_occurrences_withSpace() async {
+    await indexTestUnit('''
 int foo(String s) => 42;
 main() {
   int a = 1 + foo('has space');
@@ -879,7 +880,7 @@
   }
 
   test_offsets_lengths() async {
-    indexTestUnit('''
+    await indexTestUnit('''
 int foo() => 42;
 main() {
   int a = 1 + foo(); // marker
@@ -894,8 +895,8 @@
     expect(refactoring.lengths, unorderedEquals([5, 6]));
   }
 
-  test_singleExpression() {
-    indexTestUnit('''
+  test_singleExpression() async {
+    await indexTestUnit('''
 main() {
   int a = 1 + 2;
 }
@@ -910,8 +911,8 @@
 ''');
   }
 
-  test_singleExpression_getter() {
-    indexTestUnit('''
+  test_singleExpression_getter() async {
+    await indexTestUnit('''
 class A {
   int get foo => 42;
 }
@@ -934,9 +935,9 @@
 ''');
   }
 
-  test_singleExpression_hasParseError_expectedSemicolon() {
+  test_singleExpression_hasParseError_expectedSemicolon() async {
     verifyNoTestUnitErrors = false;
-    indexTestUnit('''
+    await indexTestUnit('''
 main(p) {
   foo
   p.bar.baz;
@@ -954,7 +955,7 @@
   }
 
   test_singleExpression_inExpressionBody_ofClosure() async {
-    indexTestUnit('''
+    await indexTestUnit('''
 main() {
   print((x) => x.y * x.y + 1);
 }
@@ -974,7 +975,7 @@
   }
 
   test_singleExpression_inExpressionBody_ofFunction() async {
-    indexTestUnit('''
+    await indexTestUnit('''
 foo(Point p) => p.x * p.x + p.y * p.y;
 class Point {int x; int y;}
 ''');
@@ -992,7 +993,7 @@
   }
 
   test_singleExpression_inExpressionBody_ofMethod() async {
-    indexTestUnit('''
+    await indexTestUnit('''
 class A {
   foo(Point p) => p.x * p.x + p.y * p.y;
 }
@@ -1013,8 +1014,8 @@
         length: 3, offsets: [35, 57, 63], names: ['x', 'i']);
   }
 
-  test_singleExpression_inIfElseIf() {
-    indexTestUnit('''
+  test_singleExpression_inIfElseIf() async {
+    await indexTestUnit('''
 main(int p) {
   if (p == 1) {
     print(1);
@@ -1037,8 +1038,8 @@
 ''');
   }
 
-  test_singleExpression_inMethod() {
-    indexTestUnit('''
+  test_singleExpression_inMethod() async {
+    await indexTestUnit('''
 class A {
   main() {
     print(1 + 2);
@@ -1057,8 +1058,8 @@
 ''');
   }
 
-  test_singleExpression_leadingNotWhitespace() {
-    indexTestUnit('''
+  test_singleExpression_leadingNotWhitespace() async {
+    await indexTestUnit('''
 main() {
   int a = 12 + 345;
 }
@@ -1073,8 +1074,8 @@
 ''');
   }
 
-  test_singleExpression_leadingWhitespace() {
-    indexTestUnit('''
+  test_singleExpression_leadingWhitespace() async {
+    await indexTestUnit('''
 main() {
   int a = 1 /*abc*/ + 2 + 345;
 }
@@ -1090,7 +1091,7 @@
   }
 
   test_singleExpression_methodName_reference() async {
-    indexTestUnit('''
+    await indexTestUnit('''
 main() {
   var v = foo().length;
 }
@@ -1108,7 +1109,7 @@
   }
 
   test_singleExpression_nameOfProperty_prefixedIdentifier() async {
-    indexTestUnit('''
+    await indexTestUnit('''
 main(p) {
   var v = p.value; // marker
 }
@@ -1124,7 +1125,7 @@
   }
 
   test_singleExpression_nameOfProperty_propertyAccess() async {
-    indexTestUnit('''
+    await indexTestUnit('''
 main() {
   var v = foo().length; // marker
 }
@@ -1146,8 +1147,8 @@
    * `1 + 2` will be a separate and complete binary expression, so it can be
    * handled as a single expression.
    */
-  test_singleExpression_partOfBinaryExpression() {
-    indexTestUnit('''
+  test_singleExpression_partOfBinaryExpression() async {
+    await indexTestUnit('''
 main() {
   int a = 1 + 2 + 3 + 4;
 }
@@ -1162,8 +1163,8 @@
 ''');
   }
 
-  test_singleExpression_string() {
-    indexTestUnit('''
+  test_singleExpression_string() async {
+    await indexTestUnit('''
 void main() {
   print("1234");
 }
@@ -1178,8 +1179,8 @@
 ''');
   }
 
-  test_singleExpression_trailingNotWhitespace() {
-    indexTestUnit('''
+  test_singleExpression_trailingNotWhitespace() async {
+    await indexTestUnit('''
 main() {
   int a = 12 + 345;
 }
@@ -1194,8 +1195,8 @@
 ''');
   }
 
-  test_singleExpression_trailingWhitespace() {
-    indexTestUnit('''
+  test_singleExpression_trailingWhitespace() async {
+    await indexTestUnit('''
 main() {
   int a = 1 + 2 ;
 }
@@ -1211,7 +1212,7 @@
   }
 
   test_stringLiteral_part() async {
-    indexTestUnit('''
+    await indexTestUnit('''
 main() {
   print('abcdefgh');
 }
@@ -1228,7 +1229,7 @@
   }
 
   test_stringLiteral_whole() async {
-    indexTestUnit('''
+    await indexTestUnit('''
 main() {
   print('abc');
 }
@@ -1246,7 +1247,7 @@
   }
 
   test_stringLiteralPart() async {
-    indexTestUnit(r'''
+    await indexTestUnit(r'''
 main() {
   int x = 1;
   int y = 2;
@@ -1346,3 +1347,9 @@
     return subExpressions;
   }
 }
+
+@reflectiveTest
+class ExtractLocalTest_Driver extends ExtractLocalTest {
+  @override
+  bool get enableNewAnalysisDriver => true;
+}
diff --git a/pkg/analysis_server/test/services/refactoring/extract_method_test.dart b/pkg/analysis_server/test/services/refactoring/extract_method_test.dart
index 6154170..55dfe5e 100644
--- a/pkg/analysis_server/test/services/refactoring/extract_method_test.dart
+++ b/pkg/analysis_server/test/services/refactoring/extract_method_test.dart
@@ -18,6 +18,7 @@
 main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(ExtractMethodTest);
+    defineReflectiveTests(ExtractMethodTest_Driver);
   });
 }
 
@@ -25,8 +26,8 @@
 class ExtractMethodTest extends RefactoringTest {
   ExtractMethodRefactoringImpl refactoring;
 
-  test_bad_assignmentLeftHandSide() {
-    indexTestUnit('''
+  test_bad_assignmentLeftHandSide() async {
+    await indexTestUnit('''
 main() {
   int aaa;
   aaa = 0;
@@ -37,8 +38,8 @@
         'Cannot extract the left-hand side of an assignment.');
   }
 
-  test_bad_comment_selectionEndsInside() {
-    indexTestUnit('''
+  test_bad_comment_selectionEndsInside() async {
+    await indexTestUnit('''
 main() {
 // start
   print(0);
@@ -51,8 +52,8 @@
     return _assertConditionsFatal('Selection ends inside a comment.');
   }
 
-  test_bad_comment_selectionStartsInside() {
-    indexTestUnit('''
+  test_bad_comment_selectionStartsInside() async {
+    await indexTestUnit('''
 main() {
 /*
 // start
@@ -65,8 +66,8 @@
     return _assertConditionsFatal('Selection begins inside a comment.');
   }
 
-  test_bad_conflict_method_alreadyDeclaresMethod() {
-    indexTestUnit('''
+  test_bad_conflict_method_alreadyDeclaresMethod() async {
+    await indexTestUnit('''
 class A {
   void res() {}
   main() {
@@ -81,8 +82,8 @@
         "Class 'A' already declares method with name 'res'.");
   }
 
-  test_bad_conflict_method_shadowsSuperDeclaration() {
-    indexTestUnit('''
+  test_bad_conflict_method_shadowsSuperDeclaration() async {
+    await indexTestUnit('''
 class A {
   void res() {} // marker
 }
@@ -99,8 +100,8 @@
     return _assertConditionsError("Created method will shadow method 'A.res'.");
   }
 
-  test_bad_conflict_topLevel_alreadyDeclaresFunction() {
-    indexTestUnit('''
+  test_bad_conflict_topLevel_alreadyDeclaresFunction() async {
+    await indexTestUnit('''
 library my.lib;
 
 void res() {}
@@ -115,8 +116,8 @@
         "Library already declares function with name 'res'.");
   }
 
-  test_bad_conflict_topLevel_willHideInheritedMemberUsage() {
-    indexTestUnit('''
+  test_bad_conflict_topLevel_willHideInheritedMemberUsage() async {
+    await indexTestUnit('''
 class A {
   void res() {}
 }
@@ -136,8 +137,8 @@
         "Created function will shadow method 'A.res'.");
   }
 
-  test_bad_constructor_initializer() {
-    indexTestUnit('''
+  test_bad_constructor_initializer() async {
+    await indexTestUnit('''
 class A {
   int f;
   A() : f = 0 {}
@@ -148,8 +149,8 @@
         'Cannot extract a constructor initializer. Select expression part of initializer.');
   }
 
-  test_bad_constructor_redirectingConstructor() {
-    indexTestUnit('''
+  test_bad_constructor_redirectingConstructor() async {
+    await indexTestUnit('''
 class A {
   A() : this.named();
   A.named() {}
@@ -160,8 +161,8 @@
         'Cannot extract a constructor initializer. Select expression part of initializer.');
   }
 
-  test_bad_constructor_superConstructor() {
-    indexTestUnit('''
+  test_bad_constructor_superConstructor() async {
+    await indexTestUnit('''
 class A {}
 class B extends A {
   B() : super();
@@ -172,8 +173,8 @@
         'Cannot extract a constructor initializer. Select expression part of initializer.');
   }
 
-  test_bad_doWhile_body() {
-    indexTestUnit('''
+  test_bad_doWhile_body() async {
+    await indexTestUnit('''
 main() {
   do
 // start
@@ -188,8 +189,8 @@
         "Operation not applicable to a 'do' statement's body and expression.");
   }
 
-  test_bad_emptySelection() {
-    indexTestUnit('''
+  test_bad_emptySelection() async {
+    await indexTestUnit('''
 main() {
 // start
 // end
@@ -201,8 +202,8 @@
         "Can only extract a single expression or a set of statements.");
   }
 
-  test_bad_forLoop_conditionAndUpdaters() {
-    indexTestUnit('''
+  test_bad_forLoop_conditionAndUpdaters() async {
+    await indexTestUnit('''
 main() {
   for (
     int i = 0;
@@ -218,8 +219,8 @@
         "Operation not applicable to a 'for' statement's condition and updaters.");
   }
 
-  test_bad_forLoop_init() {
-    indexTestUnit('''
+  test_bad_forLoop_init() async {
+    await indexTestUnit('''
 main() {
   for (
 // start
@@ -235,8 +236,8 @@
         "Cannot extract initialization part of a 'for' statement.");
   }
 
-  test_bad_forLoop_initAndCondition() {
-    indexTestUnit('''
+  test_bad_forLoop_initAndCondition() async {
+    await indexTestUnit('''
 main() {
   for (
 // start
@@ -252,8 +253,8 @@
         "Operation not applicable to a 'for' statement's initializer and condition.");
   }
 
-  test_bad_forLoop_updaters() {
-    indexTestUnit('''
+  test_bad_forLoop_updaters() async {
+    await indexTestUnit('''
 main() {
   for (
     int i = 0;
@@ -269,8 +270,8 @@
         "Cannot extract increment part of a 'for' statement.");
   }
 
-  test_bad_forLoop_updatersAndBody() {
-    indexTestUnit('''
+  test_bad_forLoop_updatersAndBody() async {
+    await indexTestUnit('''
 main() {
   for (
     int i = 0;
@@ -286,8 +287,8 @@
         "Operation not applicable to a 'for' statement's updaters and body.");
   }
 
-  test_bad_methodName_reference() {
-    indexTestUnit('''
+  test_bad_methodName_reference() async {
+    await indexTestUnit('''
 main() {
   main();
 }
@@ -296,8 +297,8 @@
     return _assertConditionsFatal("Cannot extract a single method name.");
   }
 
-  test_bad_namePartOfDeclaration_function() {
-    indexTestUnit('''
+  test_bad_namePartOfDeclaration_function() async {
+    await indexTestUnit('''
 main() {
 }
 ''');
@@ -306,8 +307,8 @@
         "Cannot extract the name part of a declaration.");
   }
 
-  test_bad_namePartOfDeclaration_variable() {
-    indexTestUnit('''
+  test_bad_namePartOfDeclaration_variable() async {
+    await indexTestUnit('''
 main() {
   int vvv = 0;
 }
@@ -317,8 +318,8 @@
         "Cannot extract the name part of a declaration.");
   }
 
-  test_bad_namePartOfQualified() {
-    indexTestUnit('''
+  test_bad_namePartOfQualified() async {
+    await indexTestUnit('''
 class A {
   var fff;
 }
@@ -332,8 +333,8 @@
         "Can not extract name part of a property access.");
   }
 
-  test_bad_newMethodName_notIdentifier() {
-    indexTestUnit('''
+  test_bad_newMethodName_notIdentifier() async {
+    await indexTestUnit('''
 main() {
 // start
   print(0);
@@ -346,8 +347,8 @@
     return _assertConditionsFatal("Method name must not contain '-'.");
   }
 
-  test_bad_notSameParent() {
-    indexTestUnit('''
+  test_bad_notSameParent() async {
+    await indexTestUnit('''
 main() {
   while (false)
 // start
@@ -363,7 +364,7 @@
   }
 
   test_bad_parameterName_duplicate() async {
-    indexTestUnit('''
+    await indexTestUnit('''
 main() {
   int v1 = 1;
   int v2 = 2;
@@ -386,7 +387,7 @@
   }
 
   test_bad_parameterName_inUse_function() async {
-    indexTestUnit('''
+    await indexTestUnit('''
 main() {
   int v1 = 1;
   int v2 = 2;
@@ -410,7 +411,7 @@
   }
 
   test_bad_parameterName_inUse_localVariable() async {
-    indexTestUnit('''
+    await indexTestUnit('''
 main() {
   int v1 = 1;
   int v2 = 2;
@@ -433,7 +434,7 @@
   }
 
   test_bad_parameterName_inUse_method() async {
-    indexTestUnit('''
+    await indexTestUnit('''
 class A {
   main() {
     int v1 = 1;
@@ -458,8 +459,8 @@
         "'m' is already used as a name in the selected code");
   }
 
-  test_bad_selectionEndsInSomeNode() {
-    indexTestUnit('''
+  test_bad_selectionEndsInSomeNode() async {
+    await indexTestUnit('''
 main() {
 // start
   print(0);
@@ -473,8 +474,8 @@
         "Extend selection to a valid range.");
   }
 
-  test_bad_statements_exit_notAllExecutionFlows() {
-    indexTestUnit('''
+  test_bad_statements_exit_notAllExecutionFlows() async {
+    await indexTestUnit('''
 main(int p) {
 // start
   if (p == 0) {
@@ -488,8 +489,8 @@
     return _assertConditionsError(ExtractMethodRefactoringImpl.ERROR_EXITS);
   }
 
-  test_bad_statements_return_andAssignsVariable() {
-    indexTestUnit('''
+  test_bad_statements_return_andAssignsVariable() async {
+    await indexTestUnit('''
 main() {
 // start
   var v = 0;
@@ -504,8 +505,8 @@
         "local variables and return statement.");
   }
 
-  test_bad_switchCase() {
-    indexTestUnit('''
+  test_bad_switchCase() async {
+    await indexTestUnit('''
 main() {
   switch (1) {
 // start
@@ -520,8 +521,8 @@
         "or parts of a single case block.");
   }
 
-  test_bad_tokensBetweenLastNodeAndSelectionEnd() {
-    indexTestUnit('''
+  test_bad_tokensBetweenLastNodeAndSelectionEnd() async {
+    await indexTestUnit('''
 main() {
 // start
   print(0);
@@ -534,8 +535,8 @@
         "The end of the selection contains characters that do not belong to a statement.");
   }
 
-  test_bad_tokensBetweenSelectionStartAndFirstNode() {
-    indexTestUnit('''
+  test_bad_tokensBetweenSelectionStartAndFirstNode() async {
+    await indexTestUnit('''
 main() {
 // start
   print(0); // marker
@@ -548,8 +549,8 @@
         "The beginning of the selection contains characters that do not belong to a statement.");
   }
 
-  test_bad_try_catchBlock_block() {
-    indexTestUnit('''
+  test_bad_try_catchBlock_block() async {
+    await indexTestUnit('''
 main() {
   try
   {}
@@ -565,8 +566,8 @@
         "parts of try, catch, or finally block.");
   }
 
-  test_bad_try_catchBlock_complete() {
-    indexTestUnit('''
+  test_bad_try_catchBlock_complete() async {
+    await indexTestUnit('''
 main() {
   try
   {}
@@ -582,8 +583,8 @@
         "parts of try, catch, or finally block.");
   }
 
-  test_bad_try_catchBlock_exception() {
-    indexTestUnit('''
+  test_bad_try_catchBlock_exception() async {
+    await indexTestUnit('''
 main() {
   try {
   } catch (
@@ -599,8 +600,8 @@
         'Cannot extract the name part of a declaration.');
   }
 
-  test_bad_try_finallyBlock() {
-    indexTestUnit('''
+  test_bad_try_finallyBlock() async {
+    await indexTestUnit('''
 main() {
   try
   {}
@@ -616,8 +617,8 @@
         "parts of try, catch, or finally block.");
   }
 
-  test_bad_try_tryBlock() {
-    indexTestUnit('''
+  test_bad_try_tryBlock() async {
+    await indexTestUnit('''
 main() {
   try
 // start
@@ -633,8 +634,8 @@
         "parts of try, catch, or finally block.");
   }
 
-  test_bad_typeReference() {
-    indexTestUnit('''
+  test_bad_typeReference() async {
+    await indexTestUnit('''
 main() {
   int a = 0;
 }
@@ -643,8 +644,8 @@
     return _assertConditionsFatal("Cannot extract a single type reference.");
   }
 
-  test_bad_variableDeclarationFragment() {
-    indexTestUnit('''
+  test_bad_variableDeclarationFragment() async {
+    await indexTestUnit('''
 main() {
   int
 // start
@@ -658,8 +659,8 @@
         "Cannot extract a variable declaration fragment. Select whole declaration statement.");
   }
 
-  test_bad_while_conditionAndBody() {
-    indexTestUnit('''
+  test_bad_while_conditionAndBody() async {
+    await indexTestUnit('''
 main() {
   while
 // start
@@ -675,7 +676,7 @@
   }
 
   test_canExtractGetter_false_closure() async {
-    indexTestUnit('''
+    await indexTestUnit('''
 main() {
   useFunction((_) => true);
 }
@@ -689,7 +690,7 @@
   }
 
   test_canExtractGetter_false_fieldAssignment() async {
-    indexTestUnit('''
+    await indexTestUnit('''
 class A {
   var f;
   main() {
@@ -707,7 +708,7 @@
   }
 
   test_canExtractGetter_false_hasParameters() async {
-    indexTestUnit('''
+    await indexTestUnit('''
 main(int p) {
   int a = p + 1;
 }
@@ -720,7 +721,7 @@
   }
 
   test_canExtractGetter_false_returnNotUsed_assignment() async {
-    indexTestUnit('''
+    await indexTestUnit('''
 var topVar = 0;
 f(int p) {
   topVar = 5;
@@ -734,7 +735,7 @@
   }
 
   test_canExtractGetter_false_returnNotUsed_noReturn() async {
-    indexTestUnit('''
+    await indexTestUnit('''
 var topVar = 0;
 main() {
 // start
@@ -752,7 +753,7 @@
   }
 
   test_canExtractGetter_true() async {
-    indexTestUnit('''
+    await indexTestUnit('''
 main() {
   int a = 1 + 2;
 }
@@ -764,8 +765,8 @@
     expect(refactoring.createGetter, true);
   }
 
-  test_checkName() {
-    indexTestUnit('''
+  test_checkName() async {
+    await indexTestUnit('''
 main() {
   int a = 1 + 2;
 }
@@ -786,8 +787,8 @@
     assertRefactoringStatusOK(refactoring.checkName());
   }
 
-  test_closure_asFunction_singleExpression() {
-    indexTestUnit('''
+  test_closure_asFunction_singleExpression() async {
+    await indexTestUnit('''
 process(f(x)) {}
 main() {
   process((x) => x * 2);
@@ -805,8 +806,8 @@
 ''');
   }
 
-  test_closure_asFunction_statements() {
-    indexTestUnit('''
+  test_closure_asFunction_statements() async {
+    await indexTestUnit('''
 process(f(x)) {}
 main() {
   process((x) {
@@ -830,8 +831,8 @@
 ''');
   }
 
-  test_closure_asMethod_statements() {
-    indexTestUnit('''
+  test_closure_asMethod_statements() async {
+    await indexTestUnit('''
 process(f(x)) {}
 class A {
   int k = 2;
@@ -862,7 +863,7 @@
   }
 
   test_closure_bad_referencesLocalVariable() async {
-    indexTestUnit('''
+    await indexTestUnit('''
 process(f(x)) {}
 main() {
   int k = 2;
@@ -878,7 +879,7 @@
   }
 
   test_closure_bad_referencesParameter() async {
-    indexTestUnit('''
+    await indexTestUnit('''
 process(f(x)) {}
 main(int k) {
   process((x) => x * k);
@@ -892,8 +893,8 @@
             'Cannot extract closure as method, it references 1 external variable(s).');
   }
 
-  test_fromTopLevelVariableInitializerClosure() {
-    indexTestUnit('''
+  test_fromTopLevelVariableInitializerClosure() async {
+    await indexTestUnit('''
 var X = 1;
 
 var Y = () {
@@ -914,7 +915,7 @@
   }
 
   test_getExtractGetter_expression_true_binaryExpression() async {
-    indexTestUnit('''
+    await indexTestUnit('''
 main() {
   print(1 + 2);
 }
@@ -926,7 +927,7 @@
   }
 
   test_getExtractGetter_expression_true_literal() async {
-    indexTestUnit('''
+    await indexTestUnit('''
 main() {
   print(42);
 }
@@ -938,7 +939,7 @@
   }
 
   test_getExtractGetter_expression_true_prefixedExpression() async {
-    indexTestUnit('''
+    await indexTestUnit('''
 main() {
   print(!true);
 }
@@ -950,7 +951,7 @@
   }
 
   test_getExtractGetter_expression_true_prefixedIdentifier() async {
-    indexTestUnit('''
+    await indexTestUnit('''
 main() {
   print(myValue.isEven);
 }
@@ -963,7 +964,7 @@
   }
 
   test_getExtractGetter_expression_true_propertyAccess() async {
-    indexTestUnit('''
+    await indexTestUnit('''
 main() {
   print(1.isEven);
 }
@@ -975,7 +976,7 @@
   }
 
   test_getExtractGetter_statements() async {
-    indexTestUnit('''
+    await indexTestUnit('''
 main() {
 // start
   int v = 0;
@@ -989,8 +990,8 @@
     expect(refactoring.createGetter, false);
   }
 
-  test_getRefactoringName_function() {
-    indexTestUnit('''
+  test_getRefactoringName_function() async {
+    await indexTestUnit('''
 main() {
   print(1 + 2);
 }
@@ -999,8 +1000,8 @@
     expect(refactoring.refactoringName, 'Extract Function');
   }
 
-  test_getRefactoringName_method() {
-    indexTestUnit('''
+  test_getRefactoringName_method() async {
+    await indexTestUnit('''
 class A {
   main() {
     print(1 + 2);
@@ -1012,7 +1013,7 @@
   }
 
   test_names_singleExpression() async {
-    indexTestUnit('''
+    await indexTestUnit('''
 class TreeItem {}
 TreeItem getSelectedItem() => null;
 process(my) {}
@@ -1029,7 +1030,7 @@
   }
 
   test_offsets_lengths() async {
-    indexTestUnit('''
+    await indexTestUnit('''
 main() {
   int a = 1 + 2;
   int b = 1 +  2;
@@ -1044,7 +1045,7 @@
   }
 
   test_returnType_closure() async {
-    indexTestUnit('''
+    await indexTestUnit('''
 process(f(x)) {}
 main() {
   process((x) => x * 2);
@@ -1057,7 +1058,7 @@
   }
 
   test_returnType_expression() async {
-    indexTestUnit('''
+    await indexTestUnit('''
 main() {
   int a = 1 + 2;
 }
@@ -1069,7 +1070,7 @@
   }
 
   test_returnType_mixInterfaceFunction() async {
-    indexTestUnit('''
+    await indexTestUnit('''
 main() {
 // start
   if (true) {
@@ -1087,7 +1088,7 @@
   }
 
   test_returnType_statements() async {
-    indexTestUnit('''
+    await indexTestUnit('''
 main() {
 // start
   double v = 5.0;
@@ -1102,7 +1103,7 @@
   }
 
   test_returnType_statements_nullMix() async {
-    indexTestUnit('''
+    await indexTestUnit('''
 main(bool p) {
 // start
   if (p) {
@@ -1119,7 +1120,7 @@
   }
 
   test_returnType_statements_void() async {
-    indexTestUnit('''
+    await indexTestUnit('''
 main() {
 // start
   print(42);
@@ -1133,7 +1134,7 @@
   }
 
   test_setExtractGetter() async {
-    indexTestUnit('''
+    await indexTestUnit('''
 main() {
   int a = 1 + 2;
 }
@@ -1153,8 +1154,8 @@
 ''');
   }
 
-  test_singleExpression() {
-    indexTestUnit('''
+  test_singleExpression() async {
+    await indexTestUnit('''
 main() {
   int a = 1 + 2;
 }
@@ -1170,8 +1171,8 @@
 ''');
   }
 
-  test_singleExpression_cascade() {
-    indexTestUnit('''
+  test_singleExpression_cascade() async {
+    await indexTestUnit('''
 main() {
   String s = '';
   var v = s..length;
@@ -1189,8 +1190,8 @@
 ''');
   }
 
-  test_singleExpression_dynamic() {
-    indexTestUnit('''
+  test_singleExpression_dynamic() async {
+    await indexTestUnit('''
 dynaFunction() {}
 main() {
   var v = dynaFunction(); // marker
@@ -1208,10 +1209,10 @@
 ''');
   }
 
-  test_singleExpression_hasAwait() {
-    indexTestUnit('''
+  test_singleExpression_hasAwait() async {
+    await indexTestUnit('''
 import 'dart:async';
-Future<int> getValue() => 42;
+Future<int> getValue() async => 42;
 main() async {
   int v = await getValue();
   print(v);
@@ -1221,7 +1222,7 @@
     // apply refactoring
     return _assertSuccessfulRefactoring('''
 import 'dart:async';
-Future<int> getValue() => 42;
+Future<int> getValue() async => 42;
 main() async {
   int v = await res();
   print(v);
@@ -1231,8 +1232,8 @@
 ''');
   }
 
-  test_singleExpression_ignore_assignmentLeftHandSize() {
-    indexTestUnit('''
+  test_singleExpression_ignore_assignmentLeftHandSize() async {
+    await indexTestUnit('''
 main() {
   getButton().text = 'txt';
   print(getButton().text); // marker
@@ -1252,8 +1253,8 @@
 ''');
   }
 
-  test_singleExpression_occurrences() {
-    indexTestUnit('''
+  test_singleExpression_occurrences() async {
+    await indexTestUnit('''
 main() {
   int v1 = 1;
   int v2 = 2;
@@ -1289,8 +1290,8 @@
 ''');
   }
 
-  test_singleExpression_occurrences_disabled() {
-    indexTestUnit('''
+  test_singleExpression_occurrences_disabled() async {
+    await indexTestUnit('''
 main() {
   int v1 = 1;
   int v2 = 2;
@@ -1315,8 +1316,8 @@
 ''');
   }
 
-  test_singleExpression_occurrences_inClassOnly() {
-    indexTestUnit('''
+  test_singleExpression_occurrences_inClassOnly() async {
+    await indexTestUnit('''
 class A {
   myMethod() {
     int v1 = 1;
@@ -1350,8 +1351,8 @@
 ''');
   }
 
-  test_singleExpression_occurrences_incompatibleTypes() {
-    indexTestUnit('''
+  test_singleExpression_occurrences_incompatibleTypes() async {
+    await indexTestUnit('''
 main() {
   int x = 1;
   String y = 'foo';
@@ -1373,8 +1374,8 @@
 ''');
   }
 
-  test_singleExpression_occurrences_inWholeUnit() {
-    indexTestUnit('''
+  test_singleExpression_occurrences_inWholeUnit() async {
+    await indexTestUnit('''
 main() {
   int v1 = 1;
   int v2 = 2;
@@ -1408,8 +1409,8 @@
 ''');
   }
 
-  test_singleExpression_parameter_functionTypeAlias() {
-    indexTestUnit('''
+  test_singleExpression_parameter_functionTypeAlias() async {
+    await indexTestUnit('''
 typedef R Foo<S, R>(S s);
 void main(Foo<String, int> foo, String s) {
   int a = foo(s);
@@ -1429,7 +1430,7 @@
 
   test_singleExpression_returnType_importLibrary() async {
     _addLibraryReturningAsync();
-    indexTestUnit('''
+    await indexTestUnit('''
 import 'asyncLib.dart';
 main() {
   var a = newFuture();
@@ -1448,8 +1449,8 @@
 ''');
   }
 
-  test_singleExpression_returnTypeGeneric() {
-    indexTestUnit('''
+  test_singleExpression_returnTypeGeneric() async {
+    await indexTestUnit('''
 main() {
   var v = new List<String>();
 }
@@ -1465,8 +1466,8 @@
 ''');
   }
 
-  test_singleExpression_returnTypePrefix() {
-    indexTestUnit('''
+  test_singleExpression_returnTypePrefix() async {
+    await indexTestUnit('''
 import 'dart:math' as pref;
 main() {
   var v = new pref.Random();
@@ -1484,8 +1485,8 @@
 ''');
   }
 
-  test_singleExpression_staticContext_extractFromInitializer() {
-    indexTestUnit('''
+  test_singleExpression_staticContext_extractFromInitializer() async {
+    await indexTestUnit('''
 class A {
   A(int v) {}
 }
@@ -1507,8 +1508,8 @@
 ''');
   }
 
-  test_singleExpression_staticContext_extractFromInstance() {
-    indexTestUnit('''
+  test_singleExpression_staticContext_extractFromInstance() async {
+    await indexTestUnit('''
 class A {
   instanceMethodA() {
     int v1 = 1;
@@ -1552,8 +1553,8 @@
 ''');
   }
 
-  test_singleExpression_staticContext_extractFromStatic() {
-    indexTestUnit('''
+  test_singleExpression_staticContext_extractFromStatic() async {
+    await indexTestUnit('''
 class A {
   static staticMethodA() {
     int v1 = 1;
@@ -1597,8 +1598,8 @@
 ''');
   }
 
-  test_singleExpression_staticContext_hasInInitializer() {
-    indexTestUnit('''
+  test_singleExpression_staticContext_hasInInitializer() async {
+    await indexTestUnit('''
 class A {
   A(int v) {}
 }
@@ -1626,8 +1627,8 @@
 ''');
   }
 
-  test_singleExpression_usesParameter() {
-    indexTestUnit('''
+  test_singleExpression_usesParameter() async {
+    await indexTestUnit('''
 fooA(int a1) {
   int a2 = 2;
   int a = a1 + a2;
@@ -1653,8 +1654,8 @@
 ''');
   }
 
-  test_singleExpression_withVariables() {
-    indexTestUnit('''
+  test_singleExpression_withVariables() async {
+    await indexTestUnit('''
 main() {
   int v1 = 1;
   int v2 = 2;
@@ -1675,7 +1676,7 @@
   }
 
   test_singleExpression_withVariables_doRename() async {
-    indexTestUnit('''
+    await indexTestUnit('''
 main() {
   int v1 = 1;
   int v2 = 2;
@@ -1712,7 +1713,7 @@
   }
 
   test_singleExpression_withVariables_doReorder() async {
-    indexTestUnit('''
+    await indexTestUnit('''
 main() {
   int v1 = 1;
   int v2 = 2;
@@ -1748,8 +1749,8 @@
 ''');
   }
 
-  test_singleExpression_withVariables_namedExpression() {
-    indexTestUnit('''
+  test_singleExpression_withVariables_namedExpression() async {
+    await indexTestUnit('''
 main() {
   int v1 = 1;
   int v2 = 2;
@@ -1772,7 +1773,7 @@
   }
 
   test_singleExpression_withVariables_newType() async {
-    indexTestUnit('''
+    await indexTestUnit('''
 main() {
   int v1 = 1;
   int v2 = 2;
@@ -1808,8 +1809,8 @@
 ''');
   }
 
-  test_singleExpression_withVariables_useBestType() {
-    indexTestUnit('''
+  test_singleExpression_withVariables_useBestType() async {
+    await indexTestUnit('''
 main() {
   var v1 = 1;
   var v2 = 2;
@@ -1829,8 +1830,8 @@
 ''');
   }
 
-  test_statements_assignment() {
-    indexTestUnit('''
+  test_statements_assignment() async {
+    await indexTestUnit('''
 main() {
   int v;
 // start
@@ -1857,8 +1858,8 @@
 ''');
   }
 
-  test_statements_changeIndentation() {
-    indexTestUnit('''
+  test_statements_changeIndentation() async {
+    await indexTestUnit('''
 main() {
   {
 // start
@@ -1888,8 +1889,8 @@
 ''');
   }
 
-  test_statements_changeIndentation_multilineString() {
-    indexTestUnit('''
+  test_statements_changeIndentation_multilineString() async {
+    await indexTestUnit('''
 main() {
   {
 // start
@@ -1921,8 +1922,8 @@
 ''');
   }
 
-  test_statements_definesVariable_notUsedOutside() {
-    indexTestUnit('''
+  test_statements_definesVariable_notUsedOutside() async {
+    await indexTestUnit('''
 main() {
   int a = 1;
   int b = 1;
@@ -1950,8 +1951,8 @@
 ''');
   }
 
-  test_statements_definesVariable_oneUsedOutside_assignment() {
-    indexTestUnit('''
+  test_statements_definesVariable_oneUsedOutside_assignment() async {
+    await indexTestUnit('''
 myFunctionA() {
   int a = 1;
 // start
@@ -1988,8 +1989,8 @@
 ''');
   }
 
-  test_statements_definesVariable_oneUsedOutside_declaration() {
-    indexTestUnit('''
+  test_statements_definesVariable_oneUsedOutside_declaration() async {
+    await indexTestUnit('''
 myFunctionA() {
   int a = 1;
   int b = 2;
@@ -2031,7 +2032,7 @@
   }
 
   test_statements_definesVariable_twoUsedOutside() async {
-    indexTestUnit('''
+    await indexTestUnit('''
 main() {
 // start
   int varA = 1;
@@ -2046,8 +2047,8 @@
     assertRefactoringStatus(status, RefactoringProblemSeverity.FATAL);
   }
 
-  test_statements_duplicate_absolutelySame() {
-    indexTestUnit('''
+  test_statements_duplicate_absolutelySame() async {
+    await indexTestUnit('''
 myFunctionA() {
   print(0);
   print(1);
@@ -2078,8 +2079,8 @@
 ''');
   }
 
-  test_statements_duplicate_declaresDifferentlyNamedVariable() {
-    indexTestUnit('''
+  test_statements_duplicate_declaresDifferentlyNamedVariable() async {
+    await indexTestUnit('''
 myFunctionA() {
   int varA = 1;
   print(varA);
@@ -2110,8 +2111,8 @@
 ''');
   }
 
-  test_statements_dynamic() {
-    indexTestUnit('''
+  test_statements_dynamic() async {
+    await indexTestUnit('''
 dynaFunction(p) => 0;
 main() {
 // start
@@ -2143,8 +2144,8 @@
   /**
    * We should always add ";" when invoke method with extracted statements.
    */
-  test_statements_endsWithBlock() {
-    indexTestUnit('''
+  test_statements_endsWithBlock() async {
+    await indexTestUnit('''
 main() {
 // start
   if (true) {
@@ -2171,7 +2172,7 @@
   }
 
   test_statements_exit_throws() async {
-    indexTestUnit('''
+    await indexTestUnit('''
 main(int p) {
 // start
   if (p == 0) {
@@ -2185,10 +2186,10 @@
     await assertRefactoringConditionsOK();
   }
 
-  test_statements_hasAwait_dynamicReturnType() {
-    indexTestUnit('''
+  test_statements_hasAwait_dynamicReturnType() async {
+    await indexTestUnit('''
 import 'dart:async';
-Future getValue() => 42;
+Future getValue() async => 42;
 main() async {
 // start
   var v = await getValue();
@@ -2200,7 +2201,7 @@
     // apply refactoring
     return _assertSuccessfulRefactoring('''
 import 'dart:async';
-Future getValue() => 42;
+Future getValue() async => 42;
 main() async {
 // start
   var v = await res();
@@ -2215,10 +2216,10 @@
 ''');
   }
 
-  test_statements_hasAwait_expression() {
-    indexTestUnit('''
+  test_statements_hasAwait_expression() async {
+    await indexTestUnit('''
 import 'dart:async';
-Future<int> getValue() => 42;
+Future<int> getValue() async => 42;
 main() async {
 // start
   int v = await getValue();
@@ -2231,7 +2232,7 @@
     // apply refactoring
     return _assertSuccessfulRefactoring('''
 import 'dart:async';
-Future<int> getValue() => 42;
+Future<int> getValue() async => 42;
 main() async {
 // start
   int v = await res();
@@ -2247,8 +2248,8 @@
 ''');
   }
 
-  test_statements_hasAwait_forEach() {
-    indexTestUnit('''
+  test_statements_hasAwait_forEach() async {
+    await indexTestUnit('''
 import 'dart:async';
 Stream<int> getValueStream() => null;
 main() async {
@@ -2283,10 +2284,10 @@
 ''');
   }
 
-  test_statements_hasAwait_voidReturnType() {
-    indexTestUnit('''
+  test_statements_hasAwait_voidReturnType() async {
+    await indexTestUnit('''
 import 'dart:async';
-Future<int> getValue() => 42;
+Future<int> getValue() async => 42;
 main() async {
 // start
   int v = await getValue();
@@ -2298,7 +2299,7 @@
     // apply refactoring
     return _assertSuccessfulRefactoring('''
 import 'dart:async';
-Future<int> getValue() => 42;
+Future<int> getValue() async => 42;
 main() async {
 // start
   await res();
@@ -2312,8 +2313,8 @@
 ''');
   }
 
-  test_statements_inSwitchMember() {
-    indexTestUnit('''
+  test_statements_inSwitchMember() async {
+    await indexTestUnit('''
 class A {
   foo(int p) {
     switch (p) {
@@ -2351,8 +2352,8 @@
 ''');
   }
 
-  test_statements_method() {
-    indexTestUnit('''
+  test_statements_method() async {
+    await indexTestUnit('''
 class A {
   foo() {
 // start
@@ -2378,8 +2379,8 @@
 ''');
   }
 
-  test_statements_noDuplicates() {
-    indexTestUnit('''
+  test_statements_noDuplicates() async {
+    await indexTestUnit('''
 main() {
   int a = 1;
   int b = 1;
@@ -2406,7 +2407,7 @@
   }
 
   test_statements_parameters_ignoreInnerPropagatedType() async {
-    indexTestUnit('''
+    await indexTestUnit('''
 main(Object x) {
 // start
   if (x is int) {
@@ -2438,9 +2439,9 @@
 ''');
   }
 
-  test_statements_parameters_importType() {
+  test_statements_parameters_importType() async {
     _addLibraryReturningAsync();
-    indexTestUnit('''
+    await indexTestUnit('''
 import 'asyncLib.dart';
 main() {
   var v = newFuture();
@@ -2467,9 +2468,9 @@
 ''');
   }
 
-  test_statements_parameters_localFunction() {
+  test_statements_parameters_localFunction() async {
     _addLibraryReturningAsync();
-    indexTestUnit('''
+    await indexTestUnit('''
 class C {
   int f(int a) {
     int callback(int x, int y) => x + a;
@@ -2503,7 +2504,7 @@
   }
 
   test_statements_parameters_noLocalVariableConflict() async {
-    indexTestUnit('''
+    await indexTestUnit('''
 int f(int x) {
   int y = x + 1;
 // start
@@ -2520,8 +2521,8 @@
     await assertRefactoringConditionsOK();
   }
 
-  test_statements_return_last() {
-    indexTestUnit('''
+  test_statements_return_last() async {
+    await indexTestUnit('''
 main() {
 // start
   int v = 5;
@@ -2545,8 +2546,8 @@
 ''');
   }
 
-  test_statements_return_multiple_ifElse() {
-    indexTestUnit('''
+  test_statements_return_multiple_ifElse() async {
+    await indexTestUnit('''
 num main(bool b) {
 // start
   if (b) {
@@ -2576,8 +2577,8 @@
 ''');
   }
 
-  test_statements_return_multiple_ifThen() {
-    indexTestUnit('''
+  test_statements_return_multiple_ifThen() async {
+    await indexTestUnit('''
 num main(bool b) {
 // start
   if (b) {
@@ -2605,8 +2606,8 @@
 ''');
   }
 
-  test_statements_return_multiple_ignoreInFunction() {
-    indexTestUnit('''
+  test_statements_return_multiple_ignoreInFunction() async {
+    await indexTestUnit('''
 int main() {
 // start
   localFunction() {
@@ -2634,8 +2635,8 @@
 ''');
   }
 
-  test_statements_return_multiple_interfaceFunction() {
-    indexTestUnit('''
+  test_statements_return_multiple_interfaceFunction() async {
+    await indexTestUnit('''
 main(bool b) {
 // start
   if (b) {
@@ -2663,8 +2664,8 @@
 ''');
   }
 
-  test_statements_return_multiple_sameElementDifferentTypeArgs() {
-    indexTestUnit('''
+  test_statements_return_multiple_sameElementDifferentTypeArgs() async {
+    await indexTestUnit('''
 main(bool b) {
 // start
   if (b) {
@@ -2698,8 +2699,8 @@
 ''');
   }
 
-  test_statements_return_single() {
-    indexTestUnit('''
+  test_statements_return_single() async {
+    await indexTestUnit('''
 main() {
 // start
   return 42;
@@ -2725,8 +2726,8 @@
    * We have 3 identical statements, but select only 2.
    * This should not cause problems.
    */
-  test_statements_twoOfThree() {
-    indexTestUnit('''
+  test_statements_twoOfThree() async {
+    await indexTestUnit('''
 main() {
 // start
   print(0);
@@ -2842,3 +2843,9 @@
     }).toList();
   }
 }
+
+@reflectiveTest
+class ExtractMethodTest_Driver extends ExtractMethodTest {
+  @override
+  bool get enableNewAnalysisDriver => true;
+}
diff --git a/pkg/analysis_server/test/services/refactoring/inline_local_test.dart b/pkg/analysis_server/test/services/refactoring/inline_local_test.dart
index e3ccaa1..674b5a7 100644
--- a/pkg/analysis_server/test/services/refactoring/inline_local_test.dart
+++ b/pkg/analysis_server/test/services/refactoring/inline_local_test.dart
@@ -16,6 +16,7 @@
 main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(InlineLocalTest);
+    defineReflectiveTests(InlineLocalTest_Driver);
   });
 }
 
@@ -24,7 +25,7 @@
   InlineLocalRefactoringImpl refactoring;
 
   test_access() async {
-    indexTestUnit('''
+    await indexTestUnit('''
 main() {
   int test = 1 + 2;
   print(test);
@@ -40,7 +41,7 @@
   }
 
   test_bad_selectionMethod() async {
-    indexTestUnit(r'''
+    await indexTestUnit(r'''
 main() {
 }
 ''');
@@ -50,7 +51,7 @@
   }
 
   test_bad_selectionParameter() async {
-    indexTestUnit(r'''
+    await indexTestUnit(r'''
 main(int test) {
 }
 ''');
@@ -60,7 +61,7 @@
   }
 
   test_bad_selectionVariable_hasAssignments_1() async {
-    indexTestUnit(r'''
+    await indexTestUnit(r'''
 main() {
   int test = 0;
   test = 1;
@@ -73,7 +74,7 @@
   }
 
   test_bad_selectionVariable_hasAssignments_2() async {
-    indexTestUnit(r'''
+    await indexTestUnit(r'''
 main() {
   int test = 0;
   test += 1;
@@ -86,7 +87,7 @@
   }
 
   test_bad_selectionVariable_notInBlock() async {
-    indexTestUnit(r'''
+    await indexTestUnit(r'''
 main() {
   if (true)
     int test = 0;
@@ -98,7 +99,7 @@
   }
 
   test_bad_selectionVariable_notInitialized() async {
-    indexTestUnit(r'''
+    await indexTestUnit(r'''
 main() {
   int test;
 }
@@ -108,8 +109,8 @@
     assertRefactoringStatus(status, RefactoringProblemSeverity.FATAL);
   }
 
-  test_OK_cascade_intoCascade() {
-    indexTestUnit(r'''
+  test_OK_cascade_intoCascade() async {
+    await indexTestUnit(r'''
 class A {
   foo() {}
   bar() {}
@@ -132,8 +133,8 @@
 ''');
   }
 
-  test_OK_cascade_intoNotCascade() {
-    indexTestUnit(r'''
+  test_OK_cascade_intoNotCascade() async {
+    await indexTestUnit(r'''
 class A {
   foo() {}
   bar() {}
@@ -156,8 +157,8 @@
 ''');
   }
 
-  test_OK_inSwitchCase() {
-    indexTestUnit('''
+  test_OK_inSwitchCase() async {
+    await indexTestUnit('''
 main(int p) {
   switch (p) {
     case 0:
@@ -180,8 +181,8 @@
 ''');
   }
 
-  test_OK_intoStringInterpolation_binaryExpression() {
-    indexTestUnit(r'''
+  test_OK_intoStringInterpolation_binaryExpression() async {
+    await indexTestUnit(r'''
 main() {
   int test = 1 + 2;
   print('test = $test');
@@ -202,8 +203,8 @@
 ''');
   }
 
-  test_OK_intoStringInterpolation_simpleIdentifier() {
-    indexTestUnit(r'''
+  test_OK_intoStringInterpolation_simpleIdentifier() async {
+    await indexTestUnit(r'''
 main() {
   int foo = 1 + 2;
   int test = foo;
@@ -226,8 +227,8 @@
 ''');
   }
 
-  test_OK_intoStringInterpolation_string_differentQuotes() {
-    indexTestUnit(r'''
+  test_OK_intoStringInterpolation_string_differentQuotes() async {
+    await indexTestUnit(r'''
 main() {
   String a = "aaa";
   String b = '$a bbb';
@@ -242,8 +243,8 @@
 ''');
   }
 
-  test_OK_intoStringInterpolation_string_doubleQuotes() {
-    indexTestUnit(r'''
+  test_OK_intoStringInterpolation_string_doubleQuotes() async {
+    await indexTestUnit(r'''
 main() {
   String a = "aaa";
   String b = "$a bbb";
@@ -258,8 +259,8 @@
 ''');
   }
 
-  test_OK_intoStringInterpolation_string_multiLineIntoMulti_leadingSpaces() {
-    indexTestUnit(r"""
+  test_OK_intoStringInterpolation_string_multiLineIntoMulti_leadingSpaces() async {
+    await indexTestUnit(r"""
 main() {
   String a = '''\ \
 a
@@ -281,8 +282,8 @@
 """);
   }
 
-  test_OK_intoStringInterpolation_string_multiLineIntoMulti_unixEOL() {
-    indexTestUnit(r"""
+  test_OK_intoStringInterpolation_string_multiLineIntoMulti_unixEOL() async {
+    await indexTestUnit(r"""
 main() {
   String a = '''
 a
@@ -306,8 +307,8 @@
 """);
   }
 
-  test_OK_intoStringInterpolation_string_multiLineIntoMulti_windowsEOL() {
-    indexTestUnit(r"""
+  test_OK_intoStringInterpolation_string_multiLineIntoMulti_windowsEOL() async {
+    await indexTestUnit(r"""
 main() {
   String a = '''
 a
@@ -333,8 +334,8 @@
         .replaceAll('\n', '\r\n'));
   }
 
-  test_OK_intoStringInterpolation_string_multiLineIntoSingle() {
-    indexTestUnit(r'''
+  test_OK_intoStringInterpolation_string_multiLineIntoSingle() async {
+    await indexTestUnit(r'''
 main() {
   String a = """aaa""";
   String b = "$a bbb";
@@ -349,8 +350,8 @@
 ''');
   }
 
-  test_OK_intoStringInterpolation_string_raw() {
-    indexTestUnit(r'''
+  test_OK_intoStringInterpolation_string_raw() async {
+    await indexTestUnit(r'''
 main() {
   String a = r'an $ignored interpolation';
   String b = '$a bbb';
@@ -365,8 +366,8 @@
 ''');
   }
 
-  test_OK_intoStringInterpolation_string_singleLineIntoMulti_doubleQuotes() {
-    indexTestUnit(r'''
+  test_OK_intoStringInterpolation_string_singleLineIntoMulti_doubleQuotes() async {
+    await indexTestUnit(r'''
 main() {
   String a = "aaa";
   String b = """$a bbb""";
@@ -381,8 +382,8 @@
 ''');
   }
 
-  test_OK_intoStringInterpolation_string_singleLineIntoMulti_singleQuotes() {
-    indexTestUnit(r"""
+  test_OK_intoStringInterpolation_string_singleLineIntoMulti_singleQuotes() async {
+    await indexTestUnit(r"""
 main() {
   String a = 'aaa';
   String b = '''$a bbb''';
@@ -397,8 +398,8 @@
 """);
   }
 
-  test_OK_intoStringInterpolation_string_singleQuotes() {
-    indexTestUnit(r'''
+  test_OK_intoStringInterpolation_string_singleQuotes() async {
+    await indexTestUnit(r'''
 main() {
   String a = 'aaa';
   String b = '$a bbb';
@@ -413,8 +414,8 @@
 ''');
   }
 
-  test_OK_intoStringInterpolation_stringInterpolation() {
-    indexTestUnit(r'''
+  test_OK_intoStringInterpolation_stringInterpolation() async {
+    await indexTestUnit(r'''
 main() {
   String a = 'aaa';
   String b = '$a bbb';
@@ -435,8 +436,8 @@
    * <p>
    * https://code.google.com/p/dart/issues/detail?id=18587
    */
-  test_OK_keepNextCommentedLine() {
-    indexTestUnit('''
+  test_OK_keepNextCommentedLine() async {
+    await indexTestUnit('''
 main() {
   int test = 1 + 2;
   // foo
@@ -455,8 +456,8 @@
 ''');
   }
 
-  test_OK_noUsages_1() {
-    indexTestUnit('''
+  test_OK_noUsages_1() async {
+    await indexTestUnit('''
 main() {
   int test = 1 + 2;
   print(0);
@@ -471,8 +472,8 @@
 ''');
   }
 
-  test_OK_noUsages_2() {
-    indexTestUnit('''
+  test_OK_noUsages_2() async {
+    await indexTestUnit('''
 main() {
   int test = 1 + 2;
 }
@@ -485,8 +486,8 @@
 ''');
   }
 
-  test_OK_oneUsage() {
-    indexTestUnit('''
+  test_OK_oneUsage() async {
+    await indexTestUnit('''
 main() {
   int test = 1 + 2;
   print(test);
@@ -501,8 +502,8 @@
 ''');
   }
 
-  test_OK_parenthesis_decrement_intoNegate() {
-    indexTestUnit('''
+  test_OK_parenthesis_decrement_intoNegate() async {
+    await indexTestUnit('''
 main() {
   var a = 1;
   var test = --a;
@@ -519,8 +520,8 @@
 ''');
   }
 
-  test_OK_parenthesis_instanceCreation_intoList() {
-    indexTestUnit('''
+  test_OK_parenthesis_instanceCreation_intoList() async {
+    await indexTestUnit('''
 class A {}
 main() {
   var test = new A();
@@ -537,8 +538,8 @@
 ''');
   }
 
-  test_OK_parenthesis_intoIndexExpression_index() {
-    indexTestUnit('''
+  test_OK_parenthesis_intoIndexExpression_index() async {
+    await indexTestUnit('''
 main() {
   var items = [];
   var test = 1 + 2;
@@ -555,8 +556,8 @@
 ''');
   }
 
-  test_OK_parenthesis_intoParenthesizedExpression() {
-    indexTestUnit('''
+  test_OK_parenthesis_intoParenthesizedExpression() async {
+    await indexTestUnit('''
 f(m, x, y) {
   int test = x as int;
   m[test] = y;
@@ -573,8 +574,8 @@
 ''');
   }
 
-  test_OK_parenthesis_negate_intoNegate() {
-    indexTestUnit('''
+  test_OK_parenthesis_negate_intoNegate() async {
+    await indexTestUnit('''
 main() {
   var a = 1;
   var test = -a;
@@ -591,8 +592,8 @@
 ''');
   }
 
-  test_OK_parenthesis_plus_intoMultiply() {
-    indexTestUnit('''
+  test_OK_parenthesis_plus_intoMultiply() async {
+    await indexTestUnit('''
 main() {
   var test = 1 + 2;
   print(test * 3);
@@ -607,8 +608,8 @@
 ''');
   }
 
-  test_OK_twoUsages() {
-    indexTestUnit('''
+  test_OK_twoUsages() async {
+    await indexTestUnit('''
 main() {
   int test = 1 + 2;
   print(test);
@@ -638,3 +639,9 @@
     refactoring = new InlineLocalRefactoring(searchEngine, testUnit, offset);
   }
 }
+
+@reflectiveTest
+class InlineLocalTest_Driver extends InlineLocalTest {
+  @override
+  bool get enableNewAnalysisDriver => true;
+}
diff --git a/pkg/analysis_server/test/services/refactoring/inline_method_test.dart b/pkg/analysis_server/test/services/refactoring/inline_method_test.dart
index bf8f481..19fead0 100644
--- a/pkg/analysis_server/test/services/refactoring/inline_method_test.dart
+++ b/pkg/analysis_server/test/services/refactoring/inline_method_test.dart
@@ -19,6 +19,7 @@
 main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(InlineMethodTest);
+    defineReflectiveTests(InlineMethodTest_Driver);
   });
 }
 
@@ -29,7 +30,7 @@
   bool inlineAll;
 
   test_access_FunctionElement() async {
-    indexTestUnit(r'''
+    await indexTestUnit(r'''
 test(a, b) {
   return a + b;
 }
@@ -47,7 +48,7 @@
   }
 
   test_access_MethodElement() async {
-    indexTestUnit(r'''
+    await indexTestUnit(r'''
 class A {
   test(a, b) {
     return a + b;
@@ -66,8 +67,8 @@
     expect(refactoring.isDeclaration, isTrue);
   }
 
-  test_bad_async_intoSyncStar() {
-    indexTestUnit(r'''
+  test_bad_async_intoSyncStar() async {
+    await indexTestUnit(r'''
 import 'dart:async';
 class A {
   Future<int> get test async => 42;
@@ -81,8 +82,8 @@
     return _assertConditionsFatal('Cannot inline async into sync*.');
   }
 
-  test_bad_async_targetIsSync_doesNotReturnFuture() {
-    indexTestUnit(r'''
+  test_bad_async_targetIsSync_doesNotReturnFuture() async {
+    await indexTestUnit(r'''
 import 'dart:async';
 class A {
   Future<int> get test async => 42;
@@ -98,8 +99,8 @@
         'Cannot inline async into a function that does not return a Future.');
   }
 
-  test_bad_asyncStar() {
-    indexTestUnit(r'''
+  test_bad_asyncStar() async {
+    await indexTestUnit(r'''
 import 'dart:async';
 class A {
   Stream<int> test() async* {
@@ -117,7 +118,7 @@
   }
 
   test_bad_cascadeInvocation() async {
-    indexTestUnit(r'''
+    await indexTestUnit(r'''
 class A {
   foo() {}
   bar() {}
@@ -137,8 +138,8 @@
         expectedContextRange: location);
   }
 
-  test_bad_constructor() {
-    indexTestUnit(r'''
+  test_bad_constructor() async {
+    await indexTestUnit(r'''
 class A {
   A.named() {}
 }
@@ -149,7 +150,7 @@
   }
 
   test_bad_deleteSource_inlineOne() async {
-    indexTestUnit(r'''
+    await indexTestUnit(r'''
 test(a, b) {
   return a + b;
 }
@@ -171,8 +172,8 @@
             'All references must be inlined to remove the source.');
   }
 
-  test_bad_notExecutableElement() {
-    indexTestUnit(r'''
+  test_bad_notExecutableElement() async {
+    await indexTestUnit(r'''
 main() {
 }
 ''');
@@ -181,8 +182,8 @@
     return _assertInvalidSelection();
   }
 
-  test_bad_notSimpleIdentifier() {
-    indexTestUnit(r'''
+  test_bad_notSimpleIdentifier() async {
+    await indexTestUnit(r'''
 main() {
   var test = 42;
   var res = test;
@@ -193,8 +194,8 @@
     return _assertInvalidSelection();
   }
 
-  test_bad_operator() {
-    indexTestUnit(r'''
+  test_bad_operator() async {
+    await indexTestUnit(r'''
 class A {
   operator -(other) => this;
 }
@@ -204,8 +205,8 @@
     return _assertConditionsFatal('Cannot inline operator.');
   }
 
-  test_bad_propertyAccessor_synthetic() {
-    indexTestUnit(r'''
+  test_bad_propertyAccessor_synthetic() async {
+    await indexTestUnit(r'''
 class A {
   int fff;
 }
@@ -219,8 +220,8 @@
     return _assertInvalidSelection();
   }
 
-  test_bad_reference_toClassMethod() {
-    indexTestUnit(r'''
+  test_bad_reference_toClassMethod() async {
+    await indexTestUnit(r'''
 class A {
   test(a, b) {
     print(a);
@@ -236,8 +237,8 @@
     return _assertConditionsFatal('Cannot inline class method reference.');
   }
 
-  test_bad_severalReturns() {
-    indexTestUnit(r'''
+  test_bad_severalReturns() async {
+    await indexTestUnit(r'''
 test() {
   if (true) {
     return 1;
@@ -253,8 +254,8 @@
     return _assertConditionsError('Ambiguous return value.');
   }
 
-  test_fieldAccessor_getter() {
-    indexTestUnit(r'''
+  test_fieldAccessor_getter() async {
+    await indexTestUnit(r'''
 class A {
   var f;
   get foo {
@@ -279,8 +280,8 @@
 ''');
   }
 
-  test_fieldAccessor_getter_PropertyAccess() {
-    indexTestUnit(r'''
+  test_fieldAccessor_getter_PropertyAccess() async {
+    await indexTestUnit(r'''
 class A {
   var f;
   get foo {
@@ -311,8 +312,8 @@
 ''');
   }
 
-  test_fieldAccessor_setter() {
-    indexTestUnit(r'''
+  test_fieldAccessor_setter() async {
+    await indexTestUnit(r'''
 class A {
   var f;
   set foo(x) {
@@ -337,8 +338,8 @@
 ''');
   }
 
-  test_fieldAccessor_setter_PropertyAccess() {
-    indexTestUnit(r'''
+  test_fieldAccessor_setter_PropertyAccess() async {
+    await indexTestUnit(r'''
 class A {
   var f;
   set foo(x) {
@@ -369,8 +370,8 @@
 ''');
   }
 
-  test_function_expressionFunctionBody() {
-    indexTestUnit(r'''
+  test_function_expressionFunctionBody() async {
+    await indexTestUnit(r'''
 test(a, b) => a + b;
 main() {
   print(test(1, 2));
@@ -385,8 +386,8 @@
 ''');
   }
 
-  test_function_hasReturn_assign() {
-    indexTestUnit(r'''
+  test_function_hasReturn_assign() async {
+    await indexTestUnit(r'''
 test(a, b) {
   print(a);
   print(b);
@@ -409,8 +410,8 @@
 ''');
   }
 
-  test_function_hasReturn_hasReturnType() {
-    indexTestUnit(r'''
+  test_function_hasReturn_hasReturnType() async {
+    await indexTestUnit(r'''
 int test(a, b) {
   return a + b;
 }
@@ -427,8 +428,8 @@
 ''');
   }
 
-  test_function_hasReturn_noVars_oneUsage() {
-    indexTestUnit(r'''
+  test_function_hasReturn_noVars_oneUsage() async {
+    await indexTestUnit(r'''
 test(a, b) {
   print(a);
   print(b);
@@ -449,8 +450,8 @@
 ''');
   }
 
-  test_function_multilineString() {
-    indexTestUnit(r"""
+  test_function_multilineString() async {
+    await indexTestUnit(r"""
 main() {
   {
     test();
@@ -477,8 +478,8 @@
 """);
   }
 
-  test_function_noReturn_hasVars_hasConflict_fieldSuperClass() {
-    indexTestUnit(r'''
+  test_function_noReturn_hasVars_hasConflict_fieldSuperClass() async {
+    await indexTestUnit(r'''
 class A {
   var c;
 }
@@ -507,8 +508,8 @@
 ''');
   }
 
-  test_function_noReturn_hasVars_hasConflict_fieldThisClass() {
-    indexTestUnit(r'''
+  test_function_noReturn_hasVars_hasConflict_fieldThisClass() async {
+    await indexTestUnit(r'''
 class A {
   var c;
   foo() {
@@ -533,8 +534,8 @@
 ''');
   }
 
-  test_function_noReturn_hasVars_hasConflict_localAfter() {
-    indexTestUnit(r'''
+  test_function_noReturn_hasVars_hasConflict_localAfter() async {
+    await indexTestUnit(r'''
 test(a, b) {
   var c = a + b;
   print(c);
@@ -555,8 +556,8 @@
 ''');
   }
 
-  test_function_noReturn_hasVars_hasConflict_localBefore() {
-    indexTestUnit(r'''
+  test_function_noReturn_hasVars_hasConflict_localBefore() async {
+    await indexTestUnit(r'''
 test(a, b) {
   var c = a + b;
   print(c);
@@ -577,8 +578,8 @@
 ''');
   }
 
-  test_function_noReturn_hasVars_noConflict() {
-    indexTestUnit(r'''
+  test_function_noReturn_hasVars_noConflict() async {
+    await indexTestUnit(r'''
 test(a, b) {
   var c = a + b;
   print(c);
@@ -597,8 +598,8 @@
 ''');
   }
 
-  test_function_noReturn_noVars_oneUsage() {
-    indexTestUnit(r'''
+  test_function_noReturn_noVars_oneUsage() async {
+    await indexTestUnit(r'''
 test(a, b) {
   print(a);
   print(b);
@@ -617,8 +618,8 @@
 ''');
   }
 
-  test_function_noReturn_noVars_useIndentation() {
-    indexTestUnit(r'''
+  test_function_noReturn_noVars_useIndentation() async {
+    await indexTestUnit(r'''
 test(a, b) {
   print(a);
   print(b);
@@ -641,8 +642,8 @@
 ''');
   }
 
-  test_function_noReturn_voidReturnType() {
-    indexTestUnit(r'''
+  test_function_noReturn_voidReturnType() async {
+    await indexTestUnit(r'''
 void test(a, b) {
   print(a + b);
 }
@@ -659,8 +660,8 @@
 ''');
   }
 
-  test_function_notStatement_oneStatement_assign() {
-    indexTestUnit(r'''
+  test_function_notStatement_oneStatement_assign() async {
+    await indexTestUnit(r'''
 test(int p) {
   print(p * 2);
 }
@@ -681,8 +682,8 @@
 ''');
   }
 
-  test_function_notStatement_oneStatement_variableDeclaration() {
-    indexTestUnit(r'''
+  test_function_notStatement_oneStatement_variableDeclaration() async {
+    await indexTestUnit(r'''
 test(int p) {
   print(p * 2);
 }
@@ -701,8 +702,8 @@
 ''');
   }
 
-  test_function_notStatement_severalStatements() {
-    indexTestUnit(r'''
+  test_function_notStatement_severalStatements() async {
+    await indexTestUnit(r'''
 test(int p) {
   print(p);
   print(p * 2);
@@ -723,8 +724,8 @@
 ''');
   }
 
-  test_function_notStatement_zeroStatements() {
-    indexTestUnit(r'''
+  test_function_notStatement_zeroStatements() async {
+    await indexTestUnit(r'''
 test(int p) {
 }
 main() {
@@ -741,8 +742,8 @@
 ''');
   }
 
-  test_function_singleStatement() {
-    indexTestUnit(r'''
+  test_function_singleStatement() async {
+    await indexTestUnit(r'''
 var topLevelField = 0;
 test() {
   print(topLevelField);
@@ -761,8 +762,8 @@
 ''');
   }
 
-  test_getter_async_targetIsAsync() {
-    indexTestUnit(r'''
+  test_getter_async_targetIsAsync() async {
+    await indexTestUnit(r'''
 import 'dart:async';
 class A {
   Future<int> get test async => 42;
@@ -783,13 +784,13 @@
 ''');
   }
 
-  test_getter_async_targetIsAsyncStar() {
-    indexTestUnit(r'''
+  test_getter_async_targetIsAsyncStar() async {
+    await indexTestUnit(r'''
 import 'dart:async';
 class A {
   Future<int> get test async => 42;
-  Stream<int> foo() async {
-    return await test;
+  Stream<int> foo() async* {
+    yield await test;
   }
 }
 ''');
@@ -798,15 +799,15 @@
     return _assertSuccessfulRefactoring(r'''
 import 'dart:async';
 class A {
-  Stream<int> foo() async {
-    return await 42;
+  Stream<int> foo() async* {
+    yield await 42;
   }
 }
 ''');
   }
 
-  test_getter_async_targetIsSync() {
-    indexTestUnit(r'''
+  test_getter_async_targetIsSync() async {
+    await indexTestUnit(r'''
 import 'dart:async';
 class A {
   Future<int> get test async => 42;
@@ -827,8 +828,8 @@
 ''');
   }
 
-  test_getter_async_targetIsSync2() {
-    indexTestUnit(r'''
+  test_getter_async_targetIsSync2() async {
+    await indexTestUnit(r'''
 import 'dart:async';
 class A {
   Future<int> get test async => 42;
@@ -855,8 +856,8 @@
 ''');
   }
 
-  test_getter_classMember_instance() {
-    indexTestUnit(r'''
+  test_getter_classMember_instance() async {
+    await indexTestUnit(r'''
 class A {
   int f;
   int get result => f + 1;
@@ -877,8 +878,8 @@
 ''');
   }
 
-  test_getter_classMember_static() {
-    indexTestUnit(r'''
+  test_getter_classMember_static() async {
+    await indexTestUnit(r'''
 class A {
   static int get result => 1 + 2;
 }
@@ -897,8 +898,8 @@
 ''');
   }
 
-  test_getter_topLevel() {
-    indexTestUnit(r'''
+  test_getter_topLevel() async {
+    await indexTestUnit(r'''
 String get message => 'Hello, World!';
 main() {
   print(message);
@@ -914,7 +915,7 @@
   }
 
   test_initialMode_all() async {
-    indexTestUnit(r'''
+    await indexTestUnit(r'''
 test(a, b) {
   return a + b;
 }
@@ -930,7 +931,7 @@
   }
 
   test_initialMode_single() async {
-    indexTestUnit(r'''
+    await indexTestUnit(r'''
 test(a, b) {
   return a + b;
 }
@@ -947,8 +948,8 @@
     expect(refactoring.inlineAll, false);
   }
 
-  test_method_async() {
-    indexTestUnit(r'''
+  test_method_async() async {
+    await indexTestUnit(r'''
 import 'dart:async';
 class A {
   Future<int> test() async => 42;
@@ -969,13 +970,14 @@
 ''');
   }
 
-  test_method_async2() {
-    indexTestUnit(r'''
+  test_method_async2() async {
+    await indexTestUnit(r'''
 import 'dart:async';
 class A {
-  Future<int> test() async => 42;
-  Future foo() {
-    return [test(), test()];
+  Future<int> foo() async => 42;
+  Future<int> test() async => await foo();
+  Future bar() {
+    return new Future.value([test(), test()]);
   }
 }
 ''');
@@ -984,15 +986,16 @@
     return _assertSuccessfulRefactoring(r'''
 import 'dart:async';
 class A {
-  Future foo() async {
-    return [42, 42];
+  Future<int> foo() async => 42;
+  Future bar() async {
+    return new Future.value([(await foo()), (await foo())]);
   }
 }
 ''');
   }
 
-  test_method_emptyBody() {
-    indexTestUnit(r'''
+  test_method_emptyBody() async {
+    await indexTestUnit(r'''
 abstract class A {
   test();
 }
@@ -1005,8 +1008,8 @@
     return _assertConditionsFatal('Cannot inline method without body.');
   }
 
-  test_method_fieldInstance() {
-    indexTestUnit(r'''
+  test_method_fieldInstance() async {
+    await indexTestUnit(r'''
 class A {
   var fA;
 }
@@ -1043,15 +1046,14 @@
 ''');
   }
 
-  test_method_fieldStatic() {
-    indexTestUnit(r'''
+  test_method_fieldStatic() async {
+    await indexTestUnit(r'''
 class A {
   static var FA = 1;
 }
 class B extends A {
   static var FB = 2;
   test() {
-    print(FA);
     print(FB);
     print(A.FA);
     print(B.FB);
@@ -1073,7 +1075,6 @@
 }
 main() {
   B b = new B();
-  print(A.FA);
   print(B.FB);
   print(A.FA);
   print(B.FB);
@@ -1081,8 +1082,8 @@
 ''');
   }
 
-  test_method_fieldStatic_sameClass() {
-    indexTestUnit(r'''
+  test_method_fieldStatic_sameClass() async {
+    await indexTestUnit(r'''
 class A {
   static var F = 1;
   foo() {
@@ -1105,8 +1106,8 @@
 ''');
   }
 
-  test_method_methodInstance() {
-    indexTestUnit(r'''
+  test_method_methodInstance() async {
+    await indexTestUnit(r'''
 class A {
   ma() {}
 }
@@ -1141,8 +1142,8 @@
 ''');
   }
 
-  test_method_methodStatic() {
-    indexTestUnit(r'''
+  test_method_methodStatic() async {
+    await indexTestUnit(r'''
 class A {
   static ma() {}
 }
@@ -1180,8 +1181,8 @@
 ''');
   }
 
-  test_method_singleStatement() {
-    indexTestUnit(r'''
+  test_method_singleStatement() async {
+    await indexTestUnit(r'''
 class A {
   test() {
     print(0);
@@ -1202,8 +1203,8 @@
 ''');
   }
 
-  test_method_this() {
-    indexTestUnit(r'''
+  test_method_this() async {
+    await indexTestUnit(r'''
 class A {
   accept(B b) {}
 }
@@ -1236,8 +1237,8 @@
 ''');
   }
 
-  test_method_unqualifiedInvocation() {
-    indexTestUnit(r'''
+  test_method_unqualifiedInvocation() async {
+    await indexTestUnit(r'''
 class A {
   test(a, b) {
     print(a);
@@ -1262,8 +1263,8 @@
 ''');
   }
 
-  test_namedArgument_inBody() {
-    indexTestUnit(r'''
+  test_namedArgument_inBody() async {
+    await indexTestUnit(r'''
 fa(pa) => fb(pb: true);
 fb({pb: false}) {}
 main() {
@@ -1281,8 +1282,8 @@
 ''');
   }
 
-  test_namedArguments() {
-    indexTestUnit(r'''
+  test_namedArguments() async {
+    await indexTestUnit(r'''
 test({a: 0, b: 2}) {
   print(a + b);
 }
@@ -1301,9 +1302,9 @@
 ''');
   }
 
-  test_noArgument_named_hasDefault() {
+  test_noArgument_named_hasDefault() async {
     verifyNoTestUnitErrors = false;
-    indexTestUnit(r'''
+    await indexTestUnit(r'''
 test({a: 42}) {
   print(a);
 }
@@ -1320,9 +1321,9 @@
 ''');
   }
 
-  test_noArgument_positional_hasDefault() {
+  test_noArgument_positional_hasDefault() async {
     verifyNoTestUnitErrors = false;
-    indexTestUnit(r'''
+    await indexTestUnit(r'''
 test([a = 42]) {
   print(a);
 }
@@ -1339,9 +1340,9 @@
 ''');
   }
 
-  test_noArgument_positional_noDefault() {
+  test_noArgument_positional_noDefault() async {
     verifyNoTestUnitErrors = false;
-    indexTestUnit(r'''
+    await indexTestUnit(r'''
 test([a]) {
   print(a);
 }
@@ -1360,7 +1361,7 @@
 
   test_noArgument_required() async {
     verifyNoTestUnitErrors = false;
-    indexTestUnit(r'''
+    await indexTestUnit(r'''
 test(a) {
   print(a);
 }
@@ -1377,8 +1378,8 @@
         expectedContextRange: location);
   }
 
-  test_reference_expressionBody() {
-    indexTestUnit(r'''
+  test_reference_expressionBody() async {
+    await indexTestUnit(r'''
 String message() => 'Hello, World!';
 main() {
   print(message);
@@ -1393,8 +1394,8 @@
 ''');
   }
 
-  test_reference_noStatement() {
-    indexTestUnit(r'''
+  test_reference_noStatement() async {
+    await indexTestUnit(r'''
 test(a, b) {
   return a || b;
 }
@@ -1417,8 +1418,8 @@
 ''');
   }
 
-  test_reference_toLocal() {
-    indexTestUnit(r'''
+  test_reference_toLocal() async {
+    await indexTestUnit(r'''
 main() {
   test(a, b) {
     print(a);
@@ -1439,8 +1440,8 @@
 ''');
   }
 
-  test_reference_toTopLevel() {
-    indexTestUnit(r'''
+  test_reference_toTopLevel() async {
+    await indexTestUnit(r'''
 test(a, b) {
   print(a);
   print(b);
@@ -1461,8 +1462,8 @@
 ''');
   }
 
-  test_removeEmptyLinesBefore_method() {
-    indexTestUnit(r'''
+  test_removeEmptyLinesBefore_method() async {
+    await indexTestUnit(r'''
 class A {
   before() {
   }
@@ -1491,8 +1492,8 @@
 ''');
   }
 
-  test_setter_classMember_instance() {
-    indexTestUnit(r'''
+  test_setter_classMember_instance() async {
+    await indexTestUnit(r'''
 class A {
   int f;
   void set result(x) {
@@ -1515,8 +1516,8 @@
 ''');
   }
 
-  test_setter_topLevel() {
-    indexTestUnit(r'''
+  test_setter_topLevel() async {
+    await indexTestUnit(r'''
 void set result(x) {
   print(x + 1);
 }
@@ -1533,8 +1534,8 @@
 ''');
   }
 
-  test_singleExpression_oneUsage() {
-    indexTestUnit(r'''
+  test_singleExpression_oneUsage() async {
+    await indexTestUnit(r'''
 test(a, b) {
   return a + b;
 }
@@ -1551,8 +1552,8 @@
 ''');
   }
 
-  test_singleExpression_oneUsage_keepMethod() {
-    indexTestUnit(r'''
+  test_singleExpression_oneUsage_keepMethod() async {
+    await indexTestUnit(r'''
 test(a, b) {
   return a + b;
 }
@@ -1573,8 +1574,8 @@
 ''');
   }
 
-  test_singleExpression_twoUsages() {
-    indexTestUnit(r'''
+  test_singleExpression_twoUsages() async {
+    await indexTestUnit(r'''
 test(a, b) {
   return a + b;
 }
@@ -1593,8 +1594,8 @@
 ''');
   }
 
-  test_singleExpression_twoUsages_inlineOne() {
-    indexTestUnit(r'''
+  test_singleExpression_twoUsages_inlineOne() async {
+    await indexTestUnit(r'''
 test(a, b) {
   return a + b;
 }
@@ -1616,8 +1617,8 @@
 ''');
   }
 
-  test_singleExpression_wrapIntoParenthesized_alreadyInMethod() {
-    indexTestUnit(r'''
+  test_singleExpression_wrapIntoParenthesized_alreadyInMethod() async {
+    await indexTestUnit(r'''
 test(a, b) {
   return a * (b);
 }
@@ -1634,8 +1635,8 @@
 ''');
   }
 
-  test_singleExpression_wrapIntoParenthesized_asNeeded() {
-    indexTestUnit(r'''
+  test_singleExpression_wrapIntoParenthesized_asNeeded() async {
+    await indexTestUnit(r'''
 test(a, b) {
   return a * b;
 }
@@ -1654,8 +1655,8 @@
 ''');
   }
 
-  test_singleExpression_wrapIntoParenthesized_bool() {
-    indexTestUnit(r'''
+  test_singleExpression_wrapIntoParenthesized_bool() async {
+    await indexTestUnit(r'''
 test(bool a, bool b) {
   return a || b;
 }
@@ -1716,3 +1717,9 @@
         searchEngine, getResolvedUnitWithElement, testUnit, offset);
   }
 }
+
+@reflectiveTest
+class InlineMethodTest_Driver extends InlineMethodTest {
+  @override
+  bool get enableNewAnalysisDriver => true;
+}
diff --git a/pkg/analysis_server/test/services/refactoring/rename_class_member_test.dart b/pkg/analysis_server/test/services/refactoring/rename_class_member_test.dart
index e65a6e0..8596dc3 100644
--- a/pkg/analysis_server/test/services/refactoring/rename_class_member_test.dart
+++ b/pkg/analysis_server/test/services/refactoring/rename_class_member_test.dart
@@ -15,13 +15,14 @@
 main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(RenameClassMemberTest);
+    defineReflectiveTests(RenameClassMemberTest_Driver);
   });
 }
 
 @reflectiveTest
 class RenameClassMemberTest extends RenameRefactoringTest {
   test_checkFinalConditions_classNameConflict_sameClass() async {
-    indexTestUnit('''
+    await indexTestUnit('''
 class NewName {
   void test() {}
 }
@@ -37,7 +38,7 @@
   }
 
   test_checkFinalConditions_classNameConflict_subClass() async {
-    indexTestUnit('''
+    await indexTestUnit('''
 class A {
   void test() {} // 1
 }
@@ -56,7 +57,7 @@
   }
 
   test_checkFinalConditions_classNameConflict_superClass() async {
-    indexTestUnit('''
+    await indexTestUnit('''
 class NewName {
   void test() {} // 1
 }
@@ -75,7 +76,7 @@
   }
 
   test_checkFinalConditions_hasMember_MethodElement() async {
-    indexTestUnit('''
+    await indexTestUnit('''
 class A {
   test() {}
   newName() {} // existing
@@ -92,7 +93,7 @@
   }
 
   test_checkFinalConditions_OK_dropSuffix() async {
-    indexTestUnit(r'''
+    await indexTestUnit(r'''
 abstract class A {
   void testOld();
 }
@@ -108,7 +109,7 @@
   }
 
   test_checkFinalConditions_OK_noShadow() async {
-    indexTestUnit('''
+    await indexTestUnit('''
 class A {
   int newName;
 }
@@ -129,12 +130,12 @@
   }
 
   test_checkFinalConditions_publicToPrivate_usedInOtherLibrary() async {
-    indexTestUnit('''
+    await indexTestUnit('''
 class A {
   test() {}
 }
 ''');
-    indexUnit(
+    await indexUnit(
         '/lib.dart',
         '''
 library my.lib;
@@ -153,7 +154,7 @@
   }
 
   test_checkFinalConditions_shadowed_byLocalFunction_inSameClass() async {
-    indexTestUnit('''
+    await indexTestUnit('''
 class A {
   test() {}
   main() {
@@ -173,7 +174,7 @@
   }
 
   test_checkFinalConditions_shadowed_byLocalVariable_inSameClass() async {
-    indexTestUnit('''
+    await indexTestUnit('''
 class A {
   test() {}
   main() {
@@ -193,7 +194,7 @@
   }
 
   test_checkFinalConditions_shadowed_byLocalVariable_inSubClass() async {
-    indexTestUnit('''
+    await indexTestUnit('''
 class A {
   test() {}
 }
@@ -215,7 +216,7 @@
   }
 
   test_checkFinalConditions_shadowed_byLocalVariable_OK_qualifiedReference() async {
-    indexTestUnit('''
+    await indexTestUnit('''
 class A {
   test() {}
   main() {
@@ -232,7 +233,7 @@
   }
 
   test_checkFinalConditions_shadowed_byLocalVariable_OK_renamedNotUsed() async {
-    indexTestUnit('''
+    await indexTestUnit('''
 class A {
   test() {}
   main() {
@@ -248,7 +249,7 @@
   }
 
   test_checkFinalConditions_shadowed_byParameter_inSameClass() async {
-    indexTestUnit('''
+    await indexTestUnit('''
 class A {
   test() {}
   main(newName) {
@@ -267,7 +268,7 @@
   }
 
   test_checkFinalConditions_shadowedBySub_MethodElement() async {
-    indexTestUnit('''
+    await indexTestUnit('''
 class A {
   test() {}
 }
@@ -289,7 +290,7 @@
   }
 
   test_checkFinalConditions_shadowsSuper_FieldElement() async {
-    indexTestUnit('''
+    await indexTestUnit('''
 class A {
   int newName; // marker
 }
@@ -312,7 +313,7 @@
   }
 
   test_checkFinalConditions_shadowsSuper_MethodElement() async {
-    indexTestUnit('''
+    await indexTestUnit('''
 class A {
   newName() {} // marker
 }
@@ -335,8 +336,8 @@
   newName() {} // marker
 }
 ''';
-    indexUnit('/lib.dart', libCode);
-    indexTestUnit('''
+    await indexUnit('/lib.dart', libCode);
+    await indexTestUnit('''
 import 'lib.dart';
 class B extends A {
   test() {}
@@ -353,7 +354,7 @@
   }
 
   test_checkInitialConditions_inSDK() async {
-    indexTestUnit('''
+    await indexTestUnit('''
 main() {
   'abc'.toUpperCase();
 }
@@ -368,7 +369,7 @@
   }
 
   test_checkInitialConditions_operator() async {
-    indexTestUnit('''
+    await indexTestUnit('''
 class A {
   operator -(other) => this;
 }
@@ -380,8 +381,8 @@
     assertRefactoringStatus(status, RefactoringProblemSeverity.FATAL);
   }
 
-  test_checkNewName_FieldElement() {
-    indexTestUnit('''
+  test_checkNewName_FieldElement() async {
+    await indexTestUnit('''
 class A {
   int test;
 }
@@ -397,8 +398,8 @@
     assertRefactoringStatusOK(refactoring.checkNewName());
   }
 
-  test_checkNewName_MethodElement() {
-    indexTestUnit('''
+  test_checkNewName_MethodElement() async {
+    await indexTestUnit('''
 class A {
   test() {}
 }
@@ -425,8 +426,8 @@
     assertRefactoringStatusOK(refactoring.checkNewName());
   }
 
-  test_createChange_FieldElement() {
-    indexTestUnit('''
+  test_createChange_FieldElement() async {
+    await indexTestUnit('''
 class A {
   int test; // marker
   main() {
@@ -491,8 +492,8 @@
 ''');
   }
 
-  test_createChange_FieldElement_constructorFieldInitializer() {
-    indexTestUnit('''
+  test_createChange_FieldElement_constructorFieldInitializer() async {
+    await indexTestUnit('''
 class A {
   final test;
   A() : test = 5;
@@ -512,8 +513,8 @@
 ''');
   }
 
-  test_createChange_FieldElement_fieldFormalParameter() {
-    indexTestUnit('''
+  test_createChange_FieldElement_fieldFormalParameter() async {
+    await indexTestUnit('''
 class A {
   final test;
   A(this.test);
@@ -533,8 +534,8 @@
 ''');
   }
 
-  test_createChange_FieldElement_fieldFormalParameter_named() {
-    indexTestUnit('''
+  test_createChange_FieldElement_fieldFormalParameter_named() async {
+    await indexTestUnit('''
 class A {
   final test;
   A({this.test});
@@ -560,8 +561,8 @@
 ''');
   }
 
-  test_createChange_FieldElement_invocation() {
-    indexTestUnit('''
+  test_createChange_FieldElement_invocation() async {
+    await indexTestUnit('''
 typedef F(a);
 class A {
   F test;
@@ -595,8 +596,8 @@
 ''');
   }
 
-  test_createChange_MethodElement() {
-    indexTestUnit('''
+  test_createChange_MethodElement() async {
+    await indexTestUnit('''
 class A {
   test() {}
 }
@@ -664,7 +665,7 @@
   }
 
   test_createChange_MethodElement_potential() async {
-    indexTestUnit('''
+    await indexTestUnit('''
 class A {
   test() {}
 }
@@ -695,14 +696,14 @@
 
   test_createChange_MethodElement_potential_inPubCache() async {
     String pkgLib = '/.pub-cache/lib.dart';
-    indexUnit(
+    await indexUnit(
         pkgLib,
         r'''
 processObj(p) {
   p.test();
 }
 ''');
-    indexTestUnit('''
+    await indexTestUnit('''
 import '$pkgLib';
 class A {
   test() {}
@@ -731,7 +732,7 @@
   }
 
   test_createChange_MethodElement_potential_private_otherLibrary() async {
-    indexUnit(
+    await indexUnit(
         '/lib.dart',
         '''
 library lib;
@@ -739,7 +740,7 @@
   p._test();
 }
 ''');
-    indexTestUnit('''
+    await indexTestUnit('''
 class A {
   _test() {}
 }
@@ -766,8 +767,8 @@
     assertNoFileChange('/lib.dart');
   }
 
-  test_createChange_PropertyAccessorElement_getter() {
-    indexTestUnit('''
+  test_createChange_PropertyAccessorElement_getter() async {
+    await indexTestUnit('''
 class A {
   get test {} // marker
   set test(x) {}
@@ -821,8 +822,8 @@
 ''');
   }
 
-  test_createChange_PropertyAccessorElement_setter() {
-    indexTestUnit('''
+  test_createChange_PropertyAccessorElement_setter() async {
+    await indexTestUnit('''
 class A {
   get test {}
   set test(x) {} // marker
@@ -876,8 +877,8 @@
 ''');
   }
 
-  test_createChange_TypeParameterElement() {
-    indexTestUnit('''
+  test_createChange_TypeParameterElement() async {
+    await indexTestUnit('''
 class A<Test> {
   Test field;
   List<Test> items;
@@ -900,3 +901,45 @@
 ''');
   }
 }
+
+@reflectiveTest
+class RenameClassMemberTest_Driver extends RenameClassMemberTest {
+  @override
+  bool get enableNewAnalysisDriver => true;
+
+  @failingTest
+  @override
+  test_checkFinalConditions_shadowed_byLocalFunction_inSameClass() {
+    return super.test_checkFinalConditions_shadowed_byLocalFunction_inSameClass();
+  }
+
+  @failingTest
+  @override
+  test_checkFinalConditions_shadowed_byLocalVariable_inSameClass() {
+    return super.test_checkFinalConditions_shadowed_byLocalVariable_inSameClass();
+  }
+
+  @failingTest
+  @override
+  test_checkFinalConditions_shadowed_byLocalVariable_inSubClass() {
+    return super.test_checkFinalConditions_shadowed_byLocalVariable_inSubClass();
+  }
+
+  @failingTest
+  @override
+  test_createChange_MethodElement_potential() {
+    return super.test_createChange_MethodElement_potential();
+  }
+
+  @failingTest
+  @override
+  test_createChange_MethodElement_potential_inPubCache() {
+    return super.test_createChange_MethodElement_potential_inPubCache();
+  }
+
+  @failingTest
+  @override
+  test_createChange_MethodElement_potential_private_otherLibrary() {
+    return super.test_createChange_MethodElement_potential_private_otherLibrary();
+  }
+}
diff --git a/pkg/analysis_server/test/services/refactoring/rename_constructor_test.dart b/pkg/analysis_server/test/services/refactoring/rename_constructor_test.dart
index afc7782..b018389 100644
--- a/pkg/analysis_server/test/services/refactoring/rename_constructor_test.dart
+++ b/pkg/analysis_server/test/services/refactoring/rename_constructor_test.dart
@@ -17,13 +17,14 @@
 main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(RenameConstructorTest);
+    defineReflectiveTests(RenameConstructorTest_Driver);
   });
 }
 
 @reflectiveTest
 class RenameConstructorTest extends RenameRefactoringTest {
   test_checkInitialConditions_inSDK() async {
-    indexTestUnit('''
+    await indexTestUnit('''
 main() {
   new String.fromCharCodes([]);
 }
@@ -37,8 +38,8 @@
             "The constructor 'String.fromCharCodes' is defined in the SDK, so cannot be renamed.");
   }
 
-  test_checkNewName() {
-    indexTestUnit('''
+  test_checkNewName() async {
+    await indexTestUnit('''
 class A {
   A.test() {}
 }
@@ -65,7 +66,7 @@
   }
 
   test_checkNewName_hasMember_constructor() async {
-    indexTestUnit('''
+    await indexTestUnit('''
 class A {
   A.test() {}
   A.newName() {} // existing
@@ -82,7 +83,7 @@
   }
 
   test_checkNewName_hasMember_method() async {
-    indexTestUnit('''
+    await indexTestUnit('''
 class A {
   A.test() {}
   newName() {} // existing
@@ -98,8 +99,8 @@
         expectedContextSearch: 'newName() {} // existing');
   }
 
-  test_createChange_add() {
-    indexTestUnit('''
+  test_createChange_add() async {
+    await indexTestUnit('''
 class A {
   A() {} // marker
 }
@@ -132,8 +133,8 @@
 ''');
   }
 
-  test_createChange_add_toSynthetic() {
-    indexTestUnit('''
+  test_createChange_add_toSynthetic() async {
+    await indexTestUnit('''
 class A {
 }
 class B extends A {
@@ -165,8 +166,8 @@
 ''');
   }
 
-  test_createChange_change() {
-    indexTestUnit('''
+  test_createChange_change() async {
+    await indexTestUnit('''
 class A {
   A.test() {} // marker
 }
@@ -199,8 +200,8 @@
 ''');
   }
 
-  test_createChange_remove() {
-    indexTestUnit('''
+  test_createChange_remove() async {
+    await indexTestUnit('''
 class A {
   A.test() {} // marker
 }
@@ -233,7 +234,7 @@
 ''');
   }
 
-  void test_newInstance_nullElement() {
+  test_newInstance_nullElement() async {
     RenameRefactoring refactoring = new RenameRefactoring(searchEngine, null);
     expect(refactoring, isNull);
   }
@@ -250,3 +251,9 @@
     createRenameRefactoringForElement(element);
   }
 }
+
+@reflectiveTest
+class RenameConstructorTest_Driver extends RenameConstructorTest {
+  @override
+  bool get enableNewAnalysisDriver => true;
+}
diff --git a/pkg/analysis_server/test/services/refactoring/rename_import_test.dart b/pkg/analysis_server/test/services/refactoring/rename_import_test.dart
index f2df10b..5f13597 100644
--- a/pkg/analysis_server/test/services/refactoring/rename_import_test.dart
+++ b/pkg/analysis_server/test/services/refactoring/rename_import_test.dart
@@ -14,13 +14,14 @@
 main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(RenameImportTest);
+    defineReflectiveTests(RenameImportTest_Driver);
   });
 }
 
 @reflectiveTest
 class RenameImportTest extends RenameRefactoringTest {
-  test_checkNewName() {
-    indexTestUnit("import 'dart:async' as test;");
+  test_checkNewName() async {
+    await indexTestUnit("import 'dart:async' as test;");
     _createRefactoring("import 'dart:");
     expect(refactoring.oldName, 'test');
     // null
@@ -42,8 +43,8 @@
     assertRefactoringStatusOK(refactoring.checkNewName());
   }
 
-  test_createChange_add() {
-    indexTestUnit('''
+  test_createChange_add() async {
+    await indexTestUnit('''
 import 'dart:async';
 import 'dart:math' show Random, min hide max;
 main() {
@@ -68,8 +69,8 @@
 ''');
   }
 
-  test_createChange_add_interpolationExpression_hasCurlyBrackets() {
-    indexTestUnit(r'''
+  test_createChange_add_interpolationExpression_hasCurlyBrackets() async {
+    await indexTestUnit(r'''
 import 'dart:async';
 main() {
   Future f;
@@ -90,8 +91,8 @@
 ''');
   }
 
-  test_createChange_add_interpolationExpression_noCurlyBrackets() {
-    indexTestUnit(r'''
+  test_createChange_add_interpolationExpression_noCurlyBrackets() async {
+    await indexTestUnit(r'''
 import 'dart:async';
 main() {
   Future f;
@@ -112,8 +113,8 @@
 ''');
   }
 
-  test_createChange_change_className() {
-    indexTestUnit('''
+  test_createChange_change_className() async {
+    await indexTestUnit('''
 import 'dart:math' as test;
 import 'dart:async' as test;
 main() {
@@ -135,8 +136,8 @@
 ''');
   }
 
-  test_createChange_change_function() {
-    indexTestUnit('''
+  test_createChange_change_function() async {
+    await indexTestUnit('''
 import 'dart:math' as test;
 import 'dart:async' as test;
 main() {
@@ -160,8 +161,8 @@
 ''');
   }
 
-  test_createChange_change_onPrefixElement() {
-    indexTestUnit('''
+  test_createChange_change_onPrefixElement() async {
+    await indexTestUnit('''
 import 'dart:async' as test;
 import 'dart:math' as test;
 main() {
@@ -187,8 +188,8 @@
 ''');
   }
 
-  test_createChange_remove() {
-    indexTestUnit('''
+  test_createChange_remove() async {
+    await indexTestUnit('''
 import 'dart:math' as test;
 import 'dart:async' as test;
 main() {
@@ -210,8 +211,8 @@
 ''');
   }
 
-  test_oldName_empty() {
-    indexTestUnit('''
+  test_oldName_empty() async {
+    await indexTestUnit('''
 import 'dart:math';
 import 'dart:async';
 main() {
@@ -230,3 +231,9 @@
     createRenameRefactoringForElement(directive.element);
   }
 }
+
+@reflectiveTest
+class RenameImportTest_Driver extends RenameImportTest {
+  @override
+  bool get enableNewAnalysisDriver => true;
+}
diff --git a/pkg/analysis_server/test/services/refactoring/rename_label_test.dart b/pkg/analysis_server/test/services/refactoring/rename_label_test.dart
index c1e995f..8d5d17b 100644
--- a/pkg/analysis_server/test/services/refactoring/rename_label_test.dart
+++ b/pkg/analysis_server/test/services/refactoring/rename_label_test.dart
@@ -13,13 +13,14 @@
 main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(RenameLabelTest);
+    defineReflectiveTests(RenameLabelTest_Driver);
   });
 }
 
 @reflectiveTest
 class RenameLabelTest extends RenameRefactoringTest {
-  test_checkNewName_LocalVariableElement() {
-    indexTestUnit('''
+  test_checkNewName_LocalVariableElement() async {
+    await indexTestUnit('''
 main() {
 test:
   while (true) {
@@ -43,8 +44,8 @@
     assertRefactoringStatusOK(refactoring.checkNewName());
   }
 
-  test_createChange() {
-    indexTestUnit('''
+  test_createChange() async {
+    await indexTestUnit('''
 main() {
 test:
   while (true) {
@@ -68,8 +69,8 @@
 ''');
   }
 
-  test_oldName() {
-    indexTestUnit('''
+  test_oldName() async {
+    await indexTestUnit('''
 main() {
 test:
   while (true) {
@@ -83,3 +84,9 @@
     expect(refactoring.oldName, 'test');
   }
 }
+
+@reflectiveTest
+class RenameLabelTest_Driver extends RenameLabelTest {
+  @override
+  bool get enableNewAnalysisDriver => true;
+}
diff --git a/pkg/analysis_server/test/services/refactoring/rename_library_test.dart b/pkg/analysis_server/test/services/refactoring/rename_library_test.dart
index fd58cc2..e49de69 100644
--- a/pkg/analysis_server/test/services/refactoring/rename_library_test.dart
+++ b/pkg/analysis_server/test/services/refactoring/rename_library_test.dart
@@ -14,13 +14,14 @@
 main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(RenameLibraryTest);
+    defineReflectiveTests(RenameLibraryTest_Driver);
   });
 }
 
 @reflectiveTest
 class RenameLibraryTest extends RenameRefactoringTest {
-  void test_checkNewName() {
-    indexTestUnit('''
+  test_checkNewName() async {
+    await indexTestUnit('''
 library my.app;
 ''');
     _createRenameRefactoring();
@@ -48,11 +49,13 @@
         '''
 part of my.app;
 ''');
-    indexTestUnit('''
+    await indexTestUnit('''
 library my.app;
 part 'part.dart';
 ''');
-    index.indexUnit(context.resolveCompilationUnit2(unitSource, testSource));
+    if (!enableNewAnalysisDriver) {
+      index.indexUnit(context.resolveCompilationUnit2(unitSource, testSource));
+    }
     // configure refactoring
     _createRenameRefactoring();
     expect(refactoring.refactoringName, 'Rename Library');
@@ -76,11 +79,13 @@
         '''
 part of my .  app;
 ''');
-    indexTestUnit('''
+    await indexTestUnit('''
 library my    . app;
 part 'part.dart';
 ''');
-    index.indexUnit(context.resolveCompilationUnit2(unitSource, testSource));
+    if (!enableNewAnalysisDriver) {
+      index.indexUnit(context.resolveCompilationUnit2(unitSource, testSource));
+    }
     // configure refactoring
     _createRenameRefactoring();
     expect(refactoring.refactoringName, 'Rename Library');
@@ -102,3 +107,9 @@
     createRenameRefactoringForElement(testUnitElement.library);
   }
 }
+
+@reflectiveTest
+class RenameLibraryTest_Driver extends RenameLibraryTest {
+  @override
+  bool get enableNewAnalysisDriver => true;
+}
diff --git a/pkg/analysis_server/test/services/refactoring/rename_local_test.dart b/pkg/analysis_server/test/services/refactoring/rename_local_test.dart
index 7cc5811..4879c76 100644
--- a/pkg/analysis_server/test/services/refactoring/rename_local_test.dart
+++ b/pkg/analysis_server/test/services/refactoring/rename_local_test.dart
@@ -14,13 +14,14 @@
 main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(RenameLocalTest);
+    defineReflectiveTests(RenameLocalTest_Driver);
   });
 }
 
 @reflectiveTest
 class RenameLocalTest extends RenameRefactoringTest {
   test_checkFinalConditions_hasLocalFunction_after() async {
-    indexTestUnit('''
+    await indexTestUnit('''
 main() {
   int test = 0;
   newName() => 1;
@@ -36,7 +37,7 @@
   }
 
   test_checkFinalConditions_hasLocalFunction_before() async {
-    indexTestUnit('''
+    await indexTestUnit('''
 main() {
   newName() => 1;
   int test = 0;
@@ -51,7 +52,7 @@
   }
 
   test_checkFinalConditions_hasLocalVariable_after() async {
-    indexTestUnit('''
+    await indexTestUnit('''
 main() {
   int test = 0;
   var newName = 1;
@@ -69,7 +70,7 @@
   }
 
   test_checkFinalConditions_hasLocalVariable_before() async {
-    indexTestUnit('''
+    await indexTestUnit('''
 main() {
   var newName = 1;
   int test = 0;
@@ -84,8 +85,8 @@
         expectedContextSearch: 'newName = 1;');
   }
 
-  test_checkFinalConditions_hasLocalVariable_otherBlock() {
-    indexTestUnit('''
+  test_checkFinalConditions_hasLocalVariable_otherBlock() async {
+    await indexTestUnit('''
 main() {
   {
     var newName = 1;
@@ -101,8 +102,8 @@
     return assertRefactoringConditionsOK();
   }
 
-  test_checkFinalConditions_hasLocalVariable_otherForEachLoop() {
-    indexTestUnit('''
+  test_checkFinalConditions_hasLocalVariable_otherForEachLoop() async {
+    await indexTestUnit('''
 main() {
   for (int newName in []) {}
   for (int test in []) {}
@@ -114,8 +115,8 @@
     return assertRefactoringConditionsOK();
   }
 
-  test_checkFinalConditions_hasLocalVariable_otherForLoop() {
-    indexTestUnit('''
+  test_checkFinalConditions_hasLocalVariable_otherForLoop() async {
+    await indexTestUnit('''
 main() {
   for (int newName = 0; newName < 10; newName++) {}
   for (int test = 0; test < 10; test++) {}
@@ -127,8 +128,8 @@
     return assertRefactoringConditionsOK();
   }
 
-  test_checkFinalConditions_hasLocalVariable_otherFunction() {
-    indexTestUnit('''
+  test_checkFinalConditions_hasLocalVariable_otherFunction() async {
+    await indexTestUnit('''
 main() {
   int test = 0;
 }
@@ -143,7 +144,7 @@
   }
 
   test_checkFinalConditions_shadows_classMember() async {
-    indexTestUnit('''
+    await indexTestUnit('''
 class A {
   var newName = 1;
   main() {
@@ -163,19 +164,19 @@
   }
 
   test_checkFinalConditions_shadows_classMember_namedParameter() async {
-    indexTestUnit('''
+    await indexTestUnit('''
 class A {
-  foo({test: 1}) {
+  foo({test: 1}) { // in A
   }
 }
 class B extends A {
   var newName = 1;
-  foo({test: 2}) {
+  foo({test: 1}) {
     print(newName);
   }
 }
 ''');
-    createRenameRefactoringAtString('test: 1}');
+    createRenameRefactoringAtString('test: 1}) { // in A');
     // check status
     refactoring.newName = 'newName';
     RefactoringStatus status = await refactoring.checkFinalConditions();
@@ -185,8 +186,8 @@
         expectedContextSearch: 'newName);');
   }
 
-  test_checkFinalConditions_shadows_classMemberOK_qualifiedReference() {
-    indexTestUnit('''
+  test_checkFinalConditions_shadows_classMemberOK_qualifiedReference() async {
+    await indexTestUnit('''
 class A {
   var newName = 1;
   main() {
@@ -201,8 +202,8 @@
     return assertRefactoringConditionsOK();
   }
 
-  test_checkFinalConditions_shadows_OK_namedParameterReference() {
-    indexTestUnit('''
+  test_checkFinalConditions_shadows_OK_namedParameterReference() async {
+    await indexTestUnit('''
 void f({newName}) {}
 main() {
   var test = 0;
@@ -216,7 +217,7 @@
   }
 
   test_checkFinalConditions_shadows_topLevelFunction() async {
-    indexTestUnit('''
+    await indexTestUnit('''
 newName() {}
 main() {
   var test = 0;
@@ -231,13 +232,13 @@
         expectedContextSearch: 'newName(); // ref');
   }
 
-  test_checkNewName_FunctionElement() {
-    indexTestUnit('''
+  test_checkNewName_FunctionElement() async {
+    await indexTestUnit('''
 main() {
-  int test() {}
+  int test() => 0;
 }
 ''');
-    createRenameRefactoringAtString('test() {}');
+    createRenameRefactoringAtString('test() => 0;');
     // null
     refactoring.newName = null;
     assertRefactoringStatus(
@@ -248,8 +249,8 @@
     assertRefactoringStatusOK(refactoring.checkNewName());
   }
 
-  test_checkNewName_LocalVariableElement() {
-    indexTestUnit('''
+  test_checkNewName_LocalVariableElement() async {
+    await indexTestUnit('''
 main() {
   int test = 0;
 }
@@ -270,8 +271,8 @@
     assertRefactoringStatusOK(refactoring.checkNewName());
   }
 
-  test_checkNewName_ParameterElement() {
-    indexTestUnit('''
+  test_checkNewName_ParameterElement() async {
+    await indexTestUnit('''
 main(test) {
 }
 ''');
@@ -286,8 +287,8 @@
     assertRefactoringStatusOK(refactoring.checkNewName());
   }
 
-  test_createChange_localFunction() {
-    indexTestUnit('''
+  test_createChange_localFunction() async {
+    await indexTestUnit('''
 main() {
   int test() => 0;
   print(test);
@@ -309,8 +310,8 @@
 ''');
   }
 
-  test_createChange_localFunction_sameNameDifferenceScopes() {
-    indexTestUnit('''
+  test_createChange_localFunction_sameNameDifferenceScopes() async {
+    await indexTestUnit('''
 main() {
   {
     int test() => 0;
@@ -349,8 +350,8 @@
 ''');
   }
 
-  test_createChange_localVariable() {
-    indexTestUnit('''
+  test_createChange_localVariable() async {
+    await indexTestUnit('''
 main() {
   int test = 0;
   test = 1;
@@ -374,8 +375,8 @@
 ''');
   }
 
-  test_createChange_localVariable_sameNameDifferenceScopes() {
-    indexTestUnit('''
+  test_createChange_localVariable_sameNameDifferenceScopes() async {
+    await indexTestUnit('''
 main() {
   {
     int test = 0;
@@ -414,8 +415,8 @@
 ''');
   }
 
-  test_createChange_parameter() {
-    indexTestUnit('''
+  test_createChange_parameter() async {
+    await indexTestUnit('''
 myFunction({int test}) {
   test = 1;
   test += 2;
@@ -444,12 +445,12 @@
   }
 
   test_createChange_parameter_named_inOtherFile() async {
-    indexTestUnit('''
+    await indexTestUnit('''
 class A {
   A({test});
 }
 ''');
-    indexUnit(
+    await indexUnit(
         '/test2.dart',
         '''
 import 'test.dart';
@@ -478,7 +479,7 @@
   }
 
   test_createChange_parameter_named_updateHierarchy() async {
-    indexUnit(
+    await indexUnit(
         '/test2.dart',
         '''
 library test2;
@@ -493,7 +494,7 @@
   }
 }
 ''');
-    indexTestUnit('''
+    await indexTestUnit('''
 import 'test2.dart';
 main() {
   new A().foo(test: 10);
@@ -541,8 +542,8 @@
 ''');
   }
 
-  test_oldName() {
-    indexTestUnit('''
+  test_oldName() async {
+    await indexTestUnit('''
 main() {
   int test = 0;
 }
@@ -553,3 +554,9 @@
     expect(refactoring.oldName, 'test');
   }
 }
+
+@reflectiveTest
+class RenameLocalTest_Driver extends RenameLocalTest {
+  @override
+  bool get enableNewAnalysisDriver => true;
+}
diff --git a/pkg/analysis_server/test/services/refactoring/rename_unit_member_test.dart b/pkg/analysis_server/test/services/refactoring/rename_unit_member_test.dart
index 1ce560d..3e0fc83 100644
--- a/pkg/analysis_server/test/services/refactoring/rename_unit_member_test.dart
+++ b/pkg/analysis_server/test/services/refactoring/rename_unit_member_test.dart
@@ -14,13 +14,14 @@
 main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(RenameUnitMemberTest);
+    defineReflectiveTests(RenameUnitMemberTest_Driver);
   });
 }
 
 @reflectiveTest
 class RenameUnitMemberTest extends RenameRefactoringTest {
   test_checkFinalConditions_hasTopLevel_ClassElement() async {
-    indexTestUnit('''
+    await indexTestUnit('''
 class Test {}
 class NewName {} // existing
 ''');
@@ -34,7 +35,7 @@
   }
 
   test_checkFinalConditions_hasTopLevel_FunctionTypeAliasElement() async {
-    indexTestUnit('''
+    await indexTestUnit('''
 class Test {}
 typedef NewName(); // existing
 ''');
@@ -49,7 +50,7 @@
   }
 
   test_checkFinalConditions_OK_qualifiedSuper_MethodElement() async {
-    indexTestUnit('''
+    await indexTestUnit('''
 class Test {}
 class A {
   NewName() {}
@@ -68,10 +69,10 @@
   }
 
   test_checkFinalConditions_publicToPrivate_usedInOtherLibrary() async {
-    indexTestUnit('''
+    await indexTestUnit('''
 class Test {}
 ''');
-    indexUnit(
+    await indexUnit(
         '/lib.dart',
         '''
 library my.lib;
@@ -90,7 +91,7 @@
   }
 
   test_checkFinalConditions_shadowedBy_MethodElement() async {
-    indexTestUnit('''
+    await indexTestUnit('''
 class Test {}
 class A {
   void NewName() {}
@@ -110,10 +111,10 @@
   }
 
   test_checkFinalConditions_shadowsInSubClass_importedLib() async {
-    indexTestUnit('''
+    await indexTestUnit('''
 class Test {}
 ''');
-    indexUnit(
+    await indexUnit(
         '/lib.dart',
         '''
 library my.lib;
@@ -136,10 +137,10 @@
   }
 
   test_checkFinalConditions_shadowsInSubClass_importedLib_hideCombinator() async {
-    indexTestUnit('''
+    await indexTestUnit('''
 class Test {}
 ''');
-    indexUnit(
+    await indexUnit(
         '/lib.dart',
         '''
 library my.lib;
@@ -161,7 +162,7 @@
   }
 
   test_checkFinalConditions_shadowsInSubClass_MethodElement() async {
-    indexTestUnit('''
+    await indexTestUnit('''
 class Test {}
 class A {
   NewName() {}
@@ -182,7 +183,7 @@
   }
 
   test_checkFinalConditions_shadowsInSubClass_notImportedLib() async {
-    indexUnit(
+    await indexUnit(
         '/lib.dart',
         '''
 library my.lib;
@@ -195,7 +196,7 @@
   }",
 }
 ''');
-    indexTestUnit('''
+    await indexTestUnit('''
 class Test {}
 ''');
     createRenameRefactoringAtString('Test {}');
@@ -206,7 +207,7 @@
   }
 
   test_checkFinalConditions_shadowsInSubClass_notSubClass() async {
-    indexTestUnit('''
+    await indexTestUnit('''
 class Test {}
 class A {
   NewName() {}
@@ -230,7 +231,7 @@
         r'''
 class A {}
 ''');
-    indexTestUnit('''
+    await indexTestUnit('''
 import '/.pub-cache/lib.dart';
 main() {
   A a;
@@ -251,7 +252,7 @@
         r'''
 class A {}
 ''');
-    indexTestUnit('''
+    await indexTestUnit('''
 import '/Pub/Cache/lib.dart';
 main() {
   A a;
@@ -267,7 +268,7 @@
   }
 
   test_checkInitialConditions_inSDK() async {
-    indexTestUnit('''
+    await indexTestUnit('''
 main() {
   String s;
 }
@@ -281,8 +282,8 @@
             "The class 'String' is defined in the SDK, so cannot be renamed.");
   }
 
-  test_checkNewName_ClassElement() {
-    indexTestUnit('''
+  test_checkNewName_ClassElement() async {
+    await indexTestUnit('''
 class Test {}
 ''');
     createRenameRefactoringAtString('Test {}');
@@ -307,8 +308,8 @@
     assertRefactoringStatusOK(refactoring.checkNewName());
   }
 
-  test_checkNewName_FunctionElement() {
-    indexTestUnit('''
+  test_checkNewName_FunctionElement() async {
+    await indexTestUnit('''
 test() {}
 ''');
     createRenameRefactoringAtString('test() {}');
@@ -327,8 +328,8 @@
     assertRefactoringStatusOK(refactoring.checkNewName());
   }
 
-  test_checkNewName_FunctionTypeAliasElement() {
-    indexTestUnit('''
+  test_checkNewName_FunctionTypeAliasElement() async {
+    await indexTestUnit('''
 typedef Test();
 ''');
     createRenameRefactoringAtString('Test();');
@@ -342,8 +343,8 @@
     assertRefactoringStatusOK(refactoring.checkNewName());
   }
 
-  test_checkNewName_TopLevelVariableElement() {
-    indexTestUnit('''
+  test_checkNewName_TopLevelVariableElement() async {
+    await indexTestUnit('''
 var test;
 ''');
     createRenameRefactoringAtString('test;');
@@ -362,8 +363,8 @@
     assertRefactoringStatusOK(refactoring.checkNewName());
   }
 
-  test_createChange_ClassElement() {
-    indexTestUnit('''
+  test_createChange_ClassElement() async {
+    await indexTestUnit('''
 class Test implements Other {
   Test() {}
   Test.named() {}
@@ -400,9 +401,9 @@
 ''');
   }
 
-  test_createChange_ClassElement_invocation() {
+  test_createChange_ClassElement_invocation() async {
     verifyNoTestUnitErrors = false;
-    indexTestUnit('''
+    await indexTestUnit('''
 class Test {
 }
 main() {
@@ -425,8 +426,8 @@
 ''');
   }
 
-  test_createChange_ClassElement_parameterTypeNested() {
-    indexTestUnit('''
+  test_createChange_ClassElement_parameterTypeNested() async {
+    await indexTestUnit('''
 class Test {
 }
 main(f(Test p)) {
@@ -446,8 +447,8 @@
 ''');
   }
 
-  test_createChange_ClassElement_typeAlias() {
-    indexTestUnit('''
+  test_createChange_ClassElement_typeAlias() async {
+    await indexTestUnit('''
 class A {}
 class Test = Object with A;
 main(Test t) {
@@ -468,8 +469,8 @@
 ''');
   }
 
-  test_createChange_FunctionElement() {
-    indexTestUnit('''
+  test_createChange_FunctionElement() async {
+    await indexTestUnit('''
 test() {}
 foo() {}
 main() {
@@ -497,13 +498,13 @@
   }
 
   test_createChange_FunctionElement_imported() async {
-    indexUnit(
+    await indexUnit(
         '/foo.dart',
         r'''
 test() {}
 foo() {}
 ''');
-    indexTestUnit('''
+    await indexTestUnit('''
 import 'foo.dart';
 main() {
   print(test);
@@ -534,44 +535,44 @@
 ''');
   }
 
-  test_createChange_PropertyAccessorElement_getter_declaration() {
-    return _test_createChange_PropertyAccessorElement("test {}");
+  test_createChange_PropertyAccessorElement_getter_declaration() async {
+    await _test_createChange_PropertyAccessorElement("test {}");
   }
 
-  test_createChange_PropertyAccessorElement_getter_usage() {
-    return _test_createChange_PropertyAccessorElement("test);");
+  test_createChange_PropertyAccessorElement_getter_usage() async {
+    await _test_createChange_PropertyAccessorElement("test);");
   }
 
-  test_createChange_PropertyAccessorElement_mix() {
-    return _test_createChange_PropertyAccessorElement("test += 2");
+  test_createChange_PropertyAccessorElement_mix() async {
+    await _test_createChange_PropertyAccessorElement("test += 2");
   }
 
-  test_createChange_PropertyAccessorElement_setter_declaration() {
-    return _test_createChange_PropertyAccessorElement("test(x) {}");
+  test_createChange_PropertyAccessorElement_setter_declaration() async {
+    await _test_createChange_PropertyAccessorElement("test(x) {}");
   }
 
-  test_createChange_PropertyAccessorElement_setter_usage() {
-    return _test_createChange_PropertyAccessorElement("test = 1");
+  test_createChange_PropertyAccessorElement_setter_usage() async {
+    await _test_createChange_PropertyAccessorElement("test = 1");
   }
 
-  test_createChange_TopLevelVariableElement_field() {
-    return _test_createChange_TopLevelVariableElement("test = 0");
+  test_createChange_TopLevelVariableElement_field() async {
+    await _test_createChange_TopLevelVariableElement("test = 0");
   }
 
-  test_createChange_TopLevelVariableElement_getter() {
-    return _test_createChange_TopLevelVariableElement("test);");
+  test_createChange_TopLevelVariableElement_getter() async {
+    await _test_createChange_TopLevelVariableElement("test);");
   }
 
-  test_createChange_TopLevelVariableElement_mix() {
-    return _test_createChange_TopLevelVariableElement("test += 2");
+  test_createChange_TopLevelVariableElement_mix() async {
+    await _test_createChange_TopLevelVariableElement("test += 2");
   }
 
-  test_createChange_TopLevelVariableElement_setter() {
-    return _test_createChange_TopLevelVariableElement("test = 1");
+  test_createChange_TopLevelVariableElement_setter() async {
+    await _test_createChange_TopLevelVariableElement("test = 1");
   }
 
-  _test_createChange_PropertyAccessorElement(String search) {
-    indexTestUnit('''
+  _test_createChange_PropertyAccessorElement(String search) async {
+    await indexTestUnit('''
 get test {}
 set test(x) {}
 main() {
@@ -597,8 +598,8 @@
 ''');
   }
 
-  _test_createChange_TopLevelVariableElement(String search) {
-    indexTestUnit('''
+  _test_createChange_TopLevelVariableElement(String search) async {
+    await indexTestUnit('''
 int test = 0;
 main() {
   print(test);
@@ -623,3 +624,9 @@
 ''');
   }
 }
+
+@reflectiveTest
+class RenameUnitMemberTest_Driver extends RenameUnitMemberTest {
+  @override
+  bool get enableNewAnalysisDriver => true;
+}
diff --git a/pkg/analysis_server/test/services/search/hierarchy_test.dart b/pkg/analysis_server/test/services/search/hierarchy_test.dart
index 1762d57..e8638dc 100644
--- a/pkg/analysis_server/test/services/search/hierarchy_test.dart
+++ b/pkg/analysis_server/test/services/search/hierarchy_test.dart
@@ -8,7 +8,9 @@
 
 import 'package:analysis_server/src/services/index/index.dart';
 import 'package:analysis_server/src/services/search/hierarchy.dart';
+import 'package:analysis_server/src/services/search/search_engine.dart';
 import 'package:analysis_server/src/services/search/search_engine_internal.dart';
+import 'package:analysis_server/src/services/search/search_engine_internal2.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -18,22 +20,16 @@
 main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(HierarchyTest);
+    defineReflectiveTests(HierarchyTest_Driver);
   });
 }
 
 @reflectiveTest
-class HierarchyTest extends AbstractSingleUnitTest {
-  Index index;
-  SearchEngineImpl searchEngine;
+abstract class AbstractHierarchyTest extends AbstractSingleUnitTest {
+  SearchEngine get searchEngine;
 
-  void setUp() {
-    super.setUp();
-    index = createMemoryIndex();
-    searchEngine = new SearchEngineImpl(index);
-  }
-
-  void test_getClassMembers() {
-    _indexTestUnit('''
+  test_getClassMembers() async {
+    await _indexTestUnit('''
 class A {
   A() {}
   var ma1;
@@ -58,8 +54,8 @@
     }
   }
 
-  Future test_getHierarchyMembers_constructors() {
-    _indexTestUnit('''
+  test_getHierarchyMembers_constructors() async {
+    await _indexTestUnit('''
 class A {
   A() {}
 }
@@ -80,8 +76,8 @@
     return Future.wait([futureA, futureB]);
   }
 
-  Future test_getHierarchyMembers_fields() {
-    _indexTestUnit('''
+  test_getHierarchyMembers_fields() async {
+    await _indexTestUnit('''
 class A {
   int foo;
 }
@@ -118,8 +114,8 @@
     return Future.wait([futureA, futureB, futureC, futureD]);
   }
 
-  Future test_getHierarchyMembers_fields_static() async {
-    _indexTestUnit('''
+  test_getHierarchyMembers_fields_static() async {
+    await _indexTestUnit('''
 class A {
   static int foo;
 }
@@ -153,8 +149,8 @@
     }
   }
 
-  Future test_getHierarchyMembers_methods() {
-    _indexTestUnit('''
+  test_getHierarchyMembers_methods() async {
+    await _indexTestUnit('''
 class A {
   foo() {}
 }
@@ -199,8 +195,8 @@
     return Future.wait([futureA, futureB, futureC, futureD, futureE]);
   }
 
-  Future test_getHierarchyMembers_methods_static() async {
-    _indexTestUnit('''
+  test_getHierarchyMembers_methods_static() async {
+    await _indexTestUnit('''
 class A {
   static foo() {}
 }
@@ -224,8 +220,8 @@
     }
   }
 
-  Future test_getHierarchyMembers_withInterfaces() {
-    _indexTestUnit('''
+  test_getHierarchyMembers_withInterfaces() async {
+    await _indexTestUnit('''
 class A {
   foo() {}
 }
@@ -259,8 +255,8 @@
     return Future.wait([futureA, futureB, futureD]);
   }
 
-  void test_getMembers() {
-    _indexTestUnit('''
+  test_getMembers() async {
+    await _indexTestUnit('''
 class A {
   A() {}
   var ma1;
@@ -307,8 +303,8 @@
     }
   }
 
-  void test_getSuperClasses() {
-    _indexTestUnit('''
+  test_getSuperClasses() async {
+    await _indexTestUnit('''
 class A {}
 class B extends A {}
 class C extends B {}
@@ -361,8 +357,40 @@
     }
   }
 
-  void _indexTestUnit(String code) {
-    resolveTestUnit(code);
+  Future<Null> _indexTestUnit(String code);
+}
+
+@reflectiveTest
+class HierarchyTest extends AbstractHierarchyTest {
+  Index index;
+  SearchEngineImpl searchEngine;
+
+  void setUp() {
+    super.setUp();
+    index = createMemoryIndex();
+    searchEngine = new SearchEngineImpl(index);
+  }
+
+  Future<Null> _indexTestUnit(String code) async {
+    await resolveTestUnit(code);
     index.indexUnit(testUnit);
   }
 }
+
+@reflectiveTest
+class HierarchyTest_Driver extends AbstractHierarchyTest {
+  SearchEngineImpl2 searchEngine;
+
+  @override
+  bool get enableNewAnalysisDriver => true;
+
+  void setUp() {
+    super.setUp();
+    searchEngine = new SearchEngineImpl2([driver]);
+  }
+
+  @override
+  Future<Null> _indexTestUnit(String code) async {
+    await resolveTestUnit(code);
+  }
+}
diff --git a/pkg/analysis_server/test/services/search/search_engine_test.dart b/pkg/analysis_server/test/services/search/search_engine_test.dart
index 24c0a9f..152364d 100644
--- a/pkg/analysis_server/test/services/search/search_engine_test.dart
+++ b/pkg/analysis_server/test/services/search/search_engine_test.dart
@@ -75,7 +75,7 @@
   }
 
   test_searchAllSubtypes() async {
-    _indexTestUnit('''
+    await _indexTestUnit('''
 class T {}
 class A extends T {}
 class B extends A {}
@@ -90,7 +90,7 @@
   }
 
   test_searchMemberDeclarations() async {
-    _indexTestUnit('''
+    await _indexTestUnit('''
 class A {
   test() {}
 }
@@ -114,7 +114,7 @@
   }
 
   test_searchMemberReferences_qualified_resolved() async {
-    _indexTestUnit('''
+    await _indexTestUnit('''
 class C {
   var test;
 }
@@ -131,7 +131,7 @@
   }
 
   test_searchMemberReferences_qualified_unresolved() async {
-    _indexTestUnit('''
+    await _indexTestUnit('''
 main(p) {
   print(p.test);
   p.test = 1;
@@ -152,7 +152,7 @@
   }
 
   test_searchMemberReferences_unqualified_resolved() async {
-    _indexTestUnit('''
+    await _indexTestUnit('''
 class C {
   var test;
   main() {
@@ -170,7 +170,7 @@
 
   test_searchMemberReferences_unqualified_unresolved() async {
     verifyNoTestUnitErrors = false;
-    _indexTestUnit('''
+    await _indexTestUnit('''
 class C {
   main() {
     print(test);
@@ -193,7 +193,7 @@
   }
 
   test_searchReferences_ClassElement() async {
-    _indexTestUnit('''
+    await _indexTestUnit('''
 class A {}
 main(A p) {
   A v;
@@ -215,7 +215,7 @@
         '''
 part of lib;
 ''');
-    _indexTestUnit('''
+    await _indexTestUnit('''
 library lib;
 part 'my_part.dart';
 ''');
@@ -228,7 +228,7 @@
   }
 
   test_searchReferences_ConstructorElement() async {
-    _indexTestUnit('''
+    await _indexTestUnit('''
 class A {
   A.named() {}
 }
@@ -245,7 +245,7 @@
   }
 
   test_searchReferences_ConstructorElement_synthetic() async {
-    _indexTestUnit('''
+    await _indexTestUnit('''
 class A {
 }
 main() {
@@ -266,7 +266,7 @@
   }
 
   test_searchReferences_FieldElement() async {
-    _indexTestUnit('''
+    await _indexTestUnit('''
 class A {
   var field;
   A({this.field});
@@ -300,7 +300,7 @@
   }
 
   test_searchReferences_FieldElement_ofEnum() async {
-    _indexTestUnit('''
+    await _indexTestUnit('''
 enum MyEnum {
   A, B, C
 }
@@ -326,7 +326,7 @@
   }
 
   test_searchReferences_FieldElement_synthetic() async {
-    _indexTestUnit('''
+    await _indexTestUnit('''
 class A {
   get field => null;
   set field(x) {}
@@ -356,7 +356,7 @@
   }
 
   test_searchReferences_FunctionElement() async {
-    _indexTestUnit('''
+    await _indexTestUnit('''
 test() {}
 main() {
   test();
@@ -373,7 +373,7 @@
   }
 
   test_searchReferences_FunctionElement_local() async {
-    _indexTestUnit('''
+    await _indexTestUnit('''
 main() {
   test() {}
   test();
@@ -390,7 +390,7 @@
   }
 
   test_searchReferences_FunctionTypeAliasElement() async {
-    _indexTestUnit('''
+    await _indexTestUnit('''
 typedef Test();
 main() {
   Test a;
@@ -408,7 +408,7 @@
   }
 
   test_searchReferences_ImportElement_noPrefix() async {
-    _indexTestUnit('''
+    await _indexTestUnit('''
 import 'dart:math' show max, PI, Random hide min;
 export 'dart:math' show max, PI, Random hide min;
 main() {
@@ -432,7 +432,7 @@
   }
 
   test_searchReferences_ImportElement_withPrefix() async {
-    _indexTestUnit('''
+    await _indexTestUnit('''
 import 'dart:math' as math show max, PI, Random hide min;
 export 'dart:math' show max, PI, Random hide min;
 main() {
@@ -457,7 +457,7 @@
   }
 
   test_searchReferences_ImportElement_withPrefix_forMultipleImports() async {
-    _indexTestUnit('''
+    await _indexTestUnit('''
 import 'dart:async' as p;
 import 'dart:math' as p;
 main() {
@@ -485,7 +485,7 @@
   }
 
   test_searchReferences_LabelElement() async {
-    _indexTestUnit('''
+    await _indexTestUnit('''
 main() {
 label:
   while (true) {
@@ -510,7 +510,7 @@
     var codeB = 'part of lib; // B';
     addSource('/unitA.dart', codeA);
     addSource('/unitB.dart', codeB);
-    _indexTestUnit('''
+    await _indexTestUnit('''
 library lib;
 part 'unitA.dart';
 part 'unitB.dart';
@@ -530,7 +530,7 @@
   }
 
   test_searchReferences_LocalVariableElement() async {
-    _indexTestUnit('''
+    await _indexTestUnit('''
 main() {
   var v;
   v = 1;
@@ -551,7 +551,7 @@
   }
 
   test_searchReferences_LocalVariableElement_inForEachLoop() async {
-    _indexTestUnit('''
+    await _indexTestUnit('''
 main() {
   for (var v in []) {
     v = 1;
@@ -573,7 +573,7 @@
   }
 
   test_searchReferences_MethodElement() async {
-    _indexTestUnit('''
+    await _indexTestUnit('''
 class A {
   m() {}
   main() {
@@ -596,7 +596,7 @@
   }
 
   test_searchReferences_MethodMember() async {
-    _indexTestUnit('''
+    await _indexTestUnit('''
 class A<T> {
   T m() => null;
 }
@@ -613,7 +613,7 @@
   }
 
   test_searchReferences_null_noUnitElement() async {
-    _indexTestUnit('''
+    await _indexTestUnit('''
 class A {
   m() {}
 }
@@ -630,7 +630,7 @@
   }
 
   test_searchReferences_ParameterElement_ofConstructor() async {
-    _indexTestUnit('''
+    await _indexTestUnit('''
 class C {
   var f;
   C({p}) : f = p + 1 {
@@ -660,7 +660,7 @@
   }
 
   test_searchReferences_ParameterElement_ofLocalFunction() async {
-    _indexTestUnit('''
+    await _indexTestUnit('''
 main() {
   foo({p}) {
     p = 1;
@@ -685,7 +685,7 @@
   }
 
   test_searchReferences_ParameterElement_ofMethod() async {
-    _indexTestUnit('''
+    await _indexTestUnit('''
 class C {
   foo({p}) {
     p = 1;
@@ -712,7 +712,7 @@
   }
 
   test_searchReferences_ParameterElement_ofTopLevelFunction() async {
-    _indexTestUnit('''
+    await _indexTestUnit('''
 foo({p}) {
   p = 1;
   p += 2;
@@ -737,7 +737,7 @@
   }
 
   test_searchReferences_PrefixElement() async {
-    _indexTestUnit('''
+    await _indexTestUnit('''
 import 'dart:async' as ppp;
 main() {
   ppp.Future a;
@@ -755,7 +755,7 @@
   }
 
   test_searchReferences_PropertyAccessorElement_getter() async {
-    _indexTestUnit('''
+    await _indexTestUnit('''
 class A {
   get ggg => null;
   main() {
@@ -778,7 +778,7 @@
   }
 
   test_searchReferences_PropertyAccessorElement_setter() async {
-    _indexTestUnit('''
+    await _indexTestUnit('''
 class A {
   set s(x) {}
   main() {
@@ -803,7 +803,7 @@
 library lib;
 var V;
 ''');
-    _indexTestUnit('''
+    await _indexTestUnit('''
 import 'lib.dart' show V; // imp
 import 'lib.dart' as pref;
 main() {
@@ -833,7 +833,7 @@
   }
 
   test_searchReferences_TypeParameterElement() async {
-    _indexTestUnit('''
+    await _indexTestUnit('''
 class A<T> {
   main(T a, T b) {}
 }
@@ -849,7 +849,7 @@
   }
 
   test_searchSubtypes() async {
-    _indexTestUnit('''
+    await _indexTestUnit('''
 class T {}
 class A extends T {} // A
 class B = Object with T; // B
@@ -869,7 +869,7 @@
   }
 
   test_searchTopLevelDeclarations() async {
-    _indexTestUnit('''
+    await _indexTestUnit('''
 class A {} // A
 class B = Object with A;
 typedef C();
@@ -930,8 +930,8 @@
         isQualified: false, isResolved: false, length: length);
   }
 
-  void _indexTestUnit(String code) {
-    resolveTestUnit(code);
+  Future<Null> _indexTestUnit(String code) async {
+    await resolveTestUnit(code);
     index.indexUnit(testUnit);
   }
 
diff --git a/pkg/analysis_server/test/src/utilities/change_builder_dart_test.dart b/pkg/analysis_server/test/src/utilities/change_builder_dart_test.dart
index 2849493..4e88aec 100644
--- a/pkg/analysis_server/test/src/utilities/change_builder_dart_test.dart
+++ b/pkg/analysis_server/test/src/utilities/change_builder_dart_test.dart
@@ -27,9 +27,9 @@
 
 @reflectiveTest
 class DartChangeBuilderImplTest extends AbstractContextTest {
-  void test_createFileEditBuilder() {
+  test_createFileEditBuilder() async {
     Source source = addSource('/test.dart', 'library test;');
-    resolveLibraryUnit(source);
+    await resolveLibraryUnit(source);
     int timeStamp = 54;
     DartChangeBuilderImpl builder = new DartChangeBuilderImpl(context);
     DartFileEditBuilderImpl fileEditBuilder =
@@ -55,9 +55,9 @@
     return edits[0];
   }
 
-  void test_writeClassDeclaration_interfaces() {
+  test_writeClassDeclaration_interfaces() async {
     Source source = addSource('/test.dart', 'class A {}');
-    CompilationUnit unit = resolveLibraryUnit(source);
+    CompilationUnit unit = await resolveLibraryUnit(source);
     ClassDeclaration declaration = unit.declarations[0];
 
     DartChangeBuilderImpl builder = new DartChangeBuilderImpl(context);
@@ -73,9 +73,9 @@
         edit.replacement, equalsIgnoringWhitespace('class C implements A { }'));
   }
 
-  void test_writeClassDeclaration_isAbstract() {
+  test_writeClassDeclaration_isAbstract() async {
     Source source = addSource('/test.dart', '');
-    resolveLibraryUnit(source);
+    await resolveLibraryUnit(source);
 
     DartChangeBuilderImpl builder = new DartChangeBuilderImpl(context);
     builder.addFileEdit(source, 1, (FileEditBuilder builder) {
@@ -88,9 +88,9 @@
     expect(edit.replacement, equalsIgnoringWhitespace('abstract class C { }'));
   }
 
-  void test_writeClassDeclaration_memberWriter() {
+  test_writeClassDeclaration_memberWriter() async {
     Source source = addSource('/test.dart', '');
-    resolveLibraryUnit(source);
+    await resolveLibraryUnit(source);
 
     DartChangeBuilderImpl builder = new DartChangeBuilderImpl(context);
     builder.addFileEdit(source, 1, (FileEditBuilder builder) {
@@ -105,9 +105,9 @@
     expect(edit.replacement, equalsIgnoringWhitespace('class C { /**/ }'));
   }
 
-  void test_writeClassDeclaration_mixins_noSuperclass() {
+  test_writeClassDeclaration_mixins_noSuperclass() async {
     Source source = addSource('/test.dart', 'class A {}');
-    CompilationUnit unit = resolveLibraryUnit(source);
+    CompilationUnit unit = await resolveLibraryUnit(source);
     ClassDeclaration classA = unit.declarations[0];
 
     DartChangeBuilderImpl builder = new DartChangeBuilderImpl(context);
@@ -123,9 +123,9 @@
         equalsIgnoringWhitespace('class C extends Object with A { }'));
   }
 
-  void test_writeClassDeclaration_mixins_superclass() {
+  test_writeClassDeclaration_mixins_superclass() async {
     Source source = addSource('/test.dart', 'class A {} class B {}');
-    CompilationUnit unit = resolveLibraryUnit(source);
+    CompilationUnit unit = await resolveLibraryUnit(source);
     ClassDeclaration classA = unit.declarations[0];
     ClassDeclaration classB = unit.declarations[1];
 
@@ -145,9 +145,9 @@
         equalsIgnoringWhitespace('class C extends A with B { }'));
   }
 
-  void test_writeClassDeclaration_nameGroupName() {
+  test_writeClassDeclaration_nameGroupName() async {
     Source source = addSource('/test.dart', '');
-    resolveLibraryUnit(source);
+    await resolveLibraryUnit(source);
 
     DartChangeBuilderImpl builder = new DartChangeBuilderImpl(context);
     builder.addFileEdit(source, 1, (FileEditBuilder builder) {
@@ -167,9 +167,9 @@
     expect(group.positions, hasLength(1));
   }
 
-  void test_writeClassDeclaration_superclass() {
+  test_writeClassDeclaration_superclass() async {
     Source source = addSource('/test.dart', 'class B {}');
-    CompilationUnit unit = resolveLibraryUnit(source);
+    CompilationUnit unit = await resolveLibraryUnit(source);
     ClassDeclaration declaration = unit.declarations[0];
 
     DartChangeBuilderImpl builder = new DartChangeBuilderImpl(context);
@@ -185,10 +185,10 @@
     expect(edit.replacement, equalsIgnoringWhitespace('class C extends B { }'));
   }
 
-  void test_writeFieldDeclaration_initializerWriter() {
+  test_writeFieldDeclaration_initializerWriter() async {
     String content = 'class A {}';
     Source source = addSource('/test.dart', content);
-    resolveLibraryUnit(source);
+    await resolveLibraryUnit(source);
 
     DartChangeBuilderImpl builder = new DartChangeBuilderImpl(context);
     builder.addFileEdit(source, 1, (FileEditBuilder builder) {
@@ -203,10 +203,10 @@
     expect(edit.replacement, equalsIgnoringWhitespace('var f = e;'));
   }
 
-  void test_writeFieldDeclaration_isConst() {
+  test_writeFieldDeclaration_isConst() async {
     String content = 'class A {}';
     Source source = addSource('/test.dart', content);
-    resolveLibraryUnit(source);
+    await resolveLibraryUnit(source);
 
     DartChangeBuilderImpl builder = new DartChangeBuilderImpl(context);
     builder.addFileEdit(source, 1, (FileEditBuilder builder) {
@@ -218,10 +218,10 @@
     expect(edit.replacement, equalsIgnoringWhitespace('const f;'));
   }
 
-  void test_writeFieldDeclaration_isConst_isFinal() {
+  test_writeFieldDeclaration_isConst_isFinal() async {
     String content = 'class A {}';
     Source source = addSource('/test.dart', content);
-    resolveLibraryUnit(source);
+    await resolveLibraryUnit(source);
 
     DartChangeBuilderImpl builder = new DartChangeBuilderImpl(context);
     builder.addFileEdit(source, 1, (FileEditBuilder builder) {
@@ -234,10 +234,10 @@
     expect(edit.replacement, equalsIgnoringWhitespace('const f;'));
   }
 
-  void test_writeFieldDeclaration_isFinal() {
+  test_writeFieldDeclaration_isFinal() async {
     String content = 'class A {}';
     Source source = addSource('/test.dart', content);
-    resolveLibraryUnit(source);
+    await resolveLibraryUnit(source);
 
     DartChangeBuilderImpl builder = new DartChangeBuilderImpl(context);
     builder.addFileEdit(source, 1, (FileEditBuilder builder) {
@@ -249,10 +249,10 @@
     expect(edit.replacement, equalsIgnoringWhitespace('final f;'));
   }
 
-  void test_writeFieldDeclaration_isStatic() {
+  test_writeFieldDeclaration_isStatic() async {
     String content = 'class A {}';
     Source source = addSource('/test.dart', content);
-    resolveLibraryUnit(source);
+    await resolveLibraryUnit(source);
 
     DartChangeBuilderImpl builder = new DartChangeBuilderImpl(context);
     builder.addFileEdit(source, 1, (FileEditBuilder builder) {
@@ -264,10 +264,10 @@
     expect(edit.replacement, equalsIgnoringWhitespace('static var f;'));
   }
 
-  void test_writeFieldDeclaration_nameGroupName() {
+  test_writeFieldDeclaration_nameGroupName() async {
     String content = 'class A {}';
     Source source = addSource('/test.dart', content);
-    resolveLibraryUnit(source);
+    await resolveLibraryUnit(source);
 
     DartChangeBuilderImpl builder = new DartChangeBuilderImpl(context);
     builder.addFileEdit(source, 1, (FileEditBuilder builder) {
@@ -289,10 +289,10 @@
     expect(position.offset, equals(13));
   }
 
-  void test_writeFieldDeclaration_type_typeGroupName() {
+  test_writeFieldDeclaration_type_typeGroupName() async {
     String content = 'class A {} class B {}';
     Source source = addSource('/test.dart', content);
-    CompilationUnit unit = resolveLibraryUnit(source);
+    CompilationUnit unit = await resolveLibraryUnit(source);
     ClassDeclaration declaration = unit.declarations[0];
 
     DartChangeBuilderImpl builder = new DartChangeBuilderImpl(context);
@@ -318,10 +318,10 @@
     expect(position.offset, equals(20));
   }
 
-  void test_writeGetterDeclaration_bodyWriter() {
+  test_writeGetterDeclaration_bodyWriter() async {
     String content = 'class A {}';
     Source source = addSource('/test.dart', content);
-    resolveLibraryUnit(source);
+    await resolveLibraryUnit(source);
 
     DartChangeBuilderImpl builder = new DartChangeBuilderImpl(context);
     builder.addFileEdit(source, 1, (FileEditBuilder builder) {
@@ -336,10 +336,10 @@
     expect(edit.replacement, equalsIgnoringWhitespace('get g {}'));
   }
 
-  void test_writeGetterDeclaration_isStatic() {
+  test_writeGetterDeclaration_isStatic() async {
     String content = 'class A {}';
     Source source = addSource('/test.dart', content);
-    resolveLibraryUnit(source);
+    await resolveLibraryUnit(source);
 
     DartChangeBuilderImpl builder = new DartChangeBuilderImpl(context);
     builder.addFileEdit(source, 1, (FileEditBuilder builder) {
@@ -352,10 +352,10 @@
     expect(edit.replacement, equalsIgnoringWhitespace('static get g => null;'));
   }
 
-  void test_writeGetterDeclaration_nameGroupName() {
+  test_writeGetterDeclaration_nameGroupName() async {
     String content = 'class A {}';
     Source source = addSource('/test.dart', content);
-    resolveLibraryUnit(source);
+    await resolveLibraryUnit(source);
 
     DartChangeBuilderImpl builder = new DartChangeBuilderImpl(context);
     builder.addFileEdit(source, 1, (FileEditBuilder builder) {
@@ -377,10 +377,10 @@
     expect(position.offset, equals(13));
   }
 
-  void test_writeGetterDeclaration_returnType() {
+  test_writeGetterDeclaration_returnType() async {
     String content = 'class A {} class B {}';
     Source source = addSource('/test.dart', content);
-    CompilationUnit unit = resolveLibraryUnit(source);
+    CompilationUnit unit = await resolveLibraryUnit(source);
     ClassDeclaration classA = unit.declarations[0];
 
     DartChangeBuilderImpl builder = new DartChangeBuilderImpl(context);
@@ -405,7 +405,7 @@
     expect(position.offset, equals(20));
   }
 
-  void test_writeOverrideOfInheritedMember() {
+  test_writeOverrideOfInheritedMember() async {
     String content = '''
 class A {
   A add(A a) => null;
@@ -413,7 +413,7 @@
 class B extends A {
 }''';
     Source source = addSource('/test.dart', content);
-    CompilationUnit unit = resolveLibraryUnit(source);
+    CompilationUnit unit = await resolveLibraryUnit(source);
     ClassDeclaration declaration = unit.declarations[0];
 
     DartChangeBuilderImpl builder = new DartChangeBuilderImpl(context);
@@ -434,10 +434,10 @@
 }'''));
   }
 
-  void test_writeParameters_named() {
+  test_writeParameters_named() async {
     String content = 'f(int i, {String s}) {}';
     Source source = addSource('/test.dart', content);
-    CompilationUnit unit = resolveLibraryUnit(source);
+    CompilationUnit unit = await resolveLibraryUnit(source);
     FunctionDeclaration f = unit.declarations[0];
     FormalParameterList parameters = f.functionExpression.parameters;
     Iterable<ParameterElement> elements = parameters.parameters
@@ -453,10 +453,10 @@
     expect(edit.replacement, equalsIgnoringWhitespace('(int i, {String s})'));
   }
 
-  void test_writeParameters_positional() {
+  test_writeParameters_positional() async {
     String content = 'f(int i, [String s]) {}';
     Source source = addSource('/test.dart', content);
-    CompilationUnit unit = resolveLibraryUnit(source);
+    CompilationUnit unit = await resolveLibraryUnit(source);
     FunctionDeclaration f = unit.declarations[0];
     FormalParameterList parameters = f.functionExpression.parameters;
     Iterable<ParameterElement> elements = parameters.parameters
@@ -472,10 +472,10 @@
     expect(edit.replacement, equalsIgnoringWhitespace('(int i, [String s])'));
   }
 
-  void test_writeParameters_required() {
+  test_writeParameters_required() async {
     String content = 'f(int i, String s) {}';
     Source source = addSource('/test.dart', content);
-    CompilationUnit unit = resolveLibraryUnit(source);
+    CompilationUnit unit = await resolveLibraryUnit(source);
     FunctionDeclaration f = unit.declarations[0];
     FormalParameterList parameters = f.functionExpression.parameters;
     Iterable<ParameterElement> elements = parameters.parameters
@@ -491,13 +491,13 @@
     expect(edit.replacement, equalsIgnoringWhitespace('(int i, String s)'));
   }
 
-  void test_writeParametersMatchingArguments_named() {
+  test_writeParametersMatchingArguments_named() async {
     String content = '''
 f(int i, String s) {
   g(s, index: i);
 }''';
     Source source = addSource('/test.dart', content);
-    CompilationUnit unit = resolveLibraryUnit(source);
+    CompilationUnit unit = await resolveLibraryUnit(source);
     FunctionDeclaration f = unit.declarations[0];
     BlockFunctionBody body = f.functionExpression.body;
     ExpressionStatement statement = body.block.statements[0];
@@ -515,13 +515,13 @@
         edit.replacement, equalsIgnoringWhitespace('(String s, [int index])'));
   }
 
-  void test_writeParametersMatchingArguments_required() {
+  test_writeParametersMatchingArguments_required() async {
     String content = '''
 f(int i, String s) {
   g(s, i);
 }''';
     Source source = addSource('/test.dart', content);
-    CompilationUnit unit = resolveLibraryUnit(source);
+    CompilationUnit unit = await resolveLibraryUnit(source);
     FunctionDeclaration f = unit.declarations[0];
     BlockFunctionBody body = f.functionExpression.body;
     ExpressionStatement statement = body.block.statements[0];
@@ -538,10 +538,10 @@
     expect(edit.replacement, equalsIgnoringWhitespace('(String s, int i)'));
   }
 
-  void test_writeParameterSource() {
+  test_writeParameterSource() async {
     String content = 'class A {}';
     Source source = addSource('/test.dart', content);
-    CompilationUnit unit = resolveLibraryUnit(source);
+    CompilationUnit unit = await resolveLibraryUnit(source);
     ClassDeclaration classA = unit.declarations[0];
 
     DartChangeBuilderImpl builder = new DartChangeBuilderImpl(context);
@@ -555,10 +555,10 @@
     expect(edit.replacement, equalsIgnoringWhitespace('A a'));
   }
 
-  void test_writeType_dymanic() {
+  test_writeType_dynamic() async {
     String content = 'class A {}';
     Source source = addSource('/test.dart', content);
-    CompilationUnit unit = resolveLibraryUnit(source);
+    CompilationUnit unit = await resolveLibraryUnit(source);
 
     DartChangeBuilderImpl builder = new DartChangeBuilderImpl(context);
     builder.addFileEdit(source, 1, (FileEditBuilder builder) {
@@ -574,10 +574,10 @@
     expect(edit.replacement, equalsIgnoringWhitespace(''));
   }
 
-  void test_writeType_genericType() {
+  test_writeType_genericType() async {
     String content = 'class A {} class B<E> {}';
     Source source = addSource('/test.dart', content);
-    CompilationUnit unit = resolveLibraryUnit(source);
+    CompilationUnit unit = await resolveLibraryUnit(source);
     ClassDeclaration classA = unit.declarations[0];
     ClassDeclaration classB = unit.declarations[1];
 
@@ -596,10 +596,10 @@
     expect(edit.replacement, equalsIgnoringWhitespace('B<A>'));
   }
 
-  void test_writeType_groupName() {
+  test_writeType_groupName() async {
     String content = 'class A {} class B extends A {} class C extends B {}';
     Source source = addSource('/test.dart', content);
-    CompilationUnit unit = resolveLibraryUnit(source);
+    CompilationUnit unit = await resolveLibraryUnit(source);
     ClassDeclaration classC = unit.declarations[2];
 
     DartChangeBuilderImpl builder = new DartChangeBuilderImpl(context);
@@ -620,10 +620,10 @@
     expect(group, isNotNull);
   }
 
-  void test_writeType_groupName_addSupertypeProposals() {
+  test_writeType_groupName_addSupertypeProposals() async {
     String content = 'class A {} class B extends A {} class C extends B {}';
     Source source = addSource('/test.dart', content);
-    CompilationUnit unit = resolveLibraryUnit(source);
+    CompilationUnit unit = await resolveLibraryUnit(source);
     ClassDeclaration classC = unit.declarations[2];
 
     DartChangeBuilderImpl builder = new DartChangeBuilderImpl(context);
@@ -655,10 +655,10 @@
     expect(values, contains('C'));
   }
 
-  void test_writeType_null() {
+  test_writeType_null() async {
     String content = 'class A {}';
     Source source = addSource('/test.dart', content);
-    resolveLibraryUnit(source);
+    await resolveLibraryUnit(source);
 
     DartChangeBuilderImpl builder = new DartChangeBuilderImpl(context);
     builder.addFileEdit(source, 1, (FileEditBuilder builder) {
@@ -670,10 +670,10 @@
     expect(edit.replacement, equalsIgnoringWhitespace(''));
   }
 
-  void test_writeType_required_dymanic() {
+  test_writeType_required_dynamic() async {
     String content = 'class A {}';
     Source source = addSource('/test.dart', content);
-    CompilationUnit unit = resolveLibraryUnit(source);
+    CompilationUnit unit = await resolveLibraryUnit(source);
 
     DartChangeBuilderImpl builder = new DartChangeBuilderImpl(context);
     builder.addFileEdit(source, 1, (FileEditBuilder builder) {
@@ -691,10 +691,10 @@
     expect(edit.replacement, equalsIgnoringWhitespace('var'));
   }
 
-  void test_writeType_required_notNull() {
+  test_writeType_required_notNull() async {
     String content = 'class A {}';
     Source source = addSource('/test.dart', content);
-    CompilationUnit unit = resolveLibraryUnit(source);
+    CompilationUnit unit = await resolveLibraryUnit(source);
     ClassDeclaration classA = unit.declarations[0];
 
     DartChangeBuilderImpl builder = new DartChangeBuilderImpl(context);
@@ -709,10 +709,10 @@
     expect(edit.replacement, equalsIgnoringWhitespace('A'));
   }
 
-  void test_writeType_required_null() {
+  test_writeType_required_null() async {
     String content = 'class A {}';
     Source source = addSource('/test.dart', content);
-    resolveLibraryUnit(source);
+    await resolveLibraryUnit(source);
 
     DartChangeBuilderImpl builder = new DartChangeBuilderImpl(context);
     builder.addFileEdit(source, 1, (FileEditBuilder builder) {
@@ -724,10 +724,10 @@
     expect(edit.replacement, equalsIgnoringWhitespace('var'));
   }
 
-  void test_writeType_simpleType() {
+  test_writeType_simpleType() async {
     String content = 'class A {}';
     Source source = addSource('/test.dart', content);
-    CompilationUnit unit = resolveLibraryUnit(source);
+    CompilationUnit unit = await resolveLibraryUnit(source);
     ClassDeclaration classA = unit.declarations[0];
 
     DartChangeBuilderImpl builder = new DartChangeBuilderImpl(context);
@@ -741,10 +741,10 @@
     expect(edit.replacement, equalsIgnoringWhitespace('A'));
   }
 
-  void test_writeTypes_empty() {
+  test_writeTypes_empty() async {
     String content = 'class A {}';
     Source source = addSource('/test.dart', content);
-    resolveLibraryUnit(source);
+    await resolveLibraryUnit(source);
 
     DartChangeBuilderImpl builder = new DartChangeBuilderImpl(context);
     builder.addFileEdit(source, 1, (FileEditBuilder builder) {
@@ -756,10 +756,10 @@
     expect(edit.replacement, isEmpty);
   }
 
-  void test_writeTypes_noPrefix() {
+  test_writeTypes_noPrefix() async {
     String content = 'class A {} class B {}';
     Source source = addSource('/test.dart', content);
-    CompilationUnit unit = resolveLibraryUnit(source);
+    CompilationUnit unit = await resolveLibraryUnit(source);
     ClassDeclaration classA = unit.declarations[0];
     ClassDeclaration classB = unit.declarations[1];
 
@@ -776,10 +776,10 @@
     expect(edit.replacement, equalsIgnoringWhitespace('A, B'));
   }
 
-  void test_writeTypes_null() {
+  test_writeTypes_null() async {
     String content = 'class A {}';
     Source source = addSource('/test.dart', content);
-    resolveLibraryUnit(source);
+    await resolveLibraryUnit(source);
 
     DartChangeBuilderImpl builder = new DartChangeBuilderImpl(context);
     builder.addFileEdit(source, 1, (FileEditBuilder builder) {
@@ -791,10 +791,10 @@
     expect(edit.replacement, isEmpty);
   }
 
-  void test_writeTypes_prefix() {
+  test_writeTypes_prefix() async {
     String content = 'class A {} class B {}';
     Source source = addSource('/test.dart', content);
-    CompilationUnit unit = resolveLibraryUnit(source);
+    CompilationUnit unit = await resolveLibraryUnit(source);
     ClassDeclaration classA = unit.declarations[0];
     ClassDeclaration classB = unit.declarations[1];
 
@@ -814,9 +814,9 @@
 
 @reflectiveTest
 class DartFileEditBuilderImplTest extends AbstractContextTest {
-  void test_createEditBuilder() {
+  test_createEditBuilder() async {
     Source source = addSource('/test.dart', 'library test;');
-    resolveLibraryUnit(source);
+    await resolveLibraryUnit(source);
     int timeStamp = 65;
     DartChangeBuilderImpl builder = new DartChangeBuilderImpl(context);
     builder.addFileEdit(source, timeStamp, (FileEditBuilder builder) {
diff --git a/pkg/analyzer/lib/error/error.dart b/pkg/analyzer/lib/error/error.dart
index 07ebae2..f1917aa 100644
--- a/pkg/analyzer/lib/error/error.dart
+++ b/pkg/analyzer/lib/error/error.dart
@@ -6,13 +6,12 @@
 
 import 'dart:collection';
 
-import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/error/listener.dart';
 import 'package:analyzer/src/dart/scanner/scanner.dart' show ScannerErrorCode;
 import 'package:analyzer/src/error/codes.dart';
-import 'package:analyzer/src/generated/resolver.dart' show ResolverErrorCode;
 import 'package:analyzer/src/generated/java_core.dart';
 import 'package:analyzer/src/generated/parser.dart' show ParserErrorCode;
+import 'package:analyzer/src/generated/resolver.dart' show ResolverErrorCode;
 import 'package:analyzer/src/generated/source.dart';
 import 'package:front_end/src/base/errors.dart';
 import 'package:front_end/src/scanner/errors.dart';
@@ -862,13 +861,6 @@
  */
 class ErrorProperty<V> implements Comparable<ErrorProperty> {
   /**
-   * A property whose value is a list of [FieldElement]s that are final, but
-   * not initialized by a constructor.
-   */
-  static const ErrorProperty<List<FieldElement>> NOT_INITIALIZED_FIELDS =
-      const ErrorProperty<List<FieldElement>>('NOT_INITIALIZED_FIELDS', 0);
-
-  /**
    * A property whose value is the name of the library that is used by all
    * of the "part of" directives, so should be used in the "library" directive.
    * Is `null` if there is no a single name used by all of the parts.
@@ -877,7 +869,6 @@
       const ErrorProperty<String>('PARTS_LIBRARY_NAME', 1);
 
   static const List<ErrorProperty> values = const [
-    NOT_INITIALIZED_FIELDS,
     PARTS_LIBRARY_NAME,
   ];
 
diff --git a/pkg/analyzer/lib/src/dart/analysis/file_state.dart b/pkg/analyzer/lib/src/dart/analysis/file_state.dart
index 70ba1ee..1608c33 100644
--- a/pkg/analyzer/lib/src/dart/analysis/file_state.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/file_state.dart
@@ -437,7 +437,7 @@
     for (UnlinkedImport import in _unlinked.imports) {
       if (!import.isImplicit) {
         String uri = import.uri;
-        if (!_isDartUri(uri)) {
+        if (_isDartFileUri(uri)) {
           FileState file = _fileForRelativeUri(uri);
           if (file != null) {
             _importedFiles.add(file);
@@ -447,7 +447,7 @@
     }
     for (UnlinkedExportPublic export in _unlinked.publicNamespace.exports) {
       String uri = export.uri;
-      if (!_isDartUri(uri)) {
+      if (_isDartFileUri(uri)) {
         FileState file = _fileForRelativeUri(uri);
         if (file != null) {
           _exportedFiles.add(file);
@@ -457,7 +457,7 @@
       }
     }
     for (String uri in _unlinked.publicNamespace.parts) {
-      if (!_isDartUri(uri)) {
+      if (_isDartFileUri(uri)) {
         FileState file = _fileForRelativeUri(uri);
         if (file != null) {
           _partedFiles.add(file);
@@ -524,8 +524,8 @@
     return true;
   }
 
-  static bool _isDartUri(String uri) {
-    return uri.startsWith('dart:');
+  static bool _isDartFileUri(String uri) {
+    return !uri.startsWith('dart:') && AnalysisEngine.isDartFileName(uri);
   }
 }
 
diff --git a/pkg/analyzer/lib/src/dart/analysis/search.dart b/pkg/analyzer/lib/src/dart/analysis/search.dart
index 3ec8f8848..d9e8118 100644
--- a/pkg/analyzer/lib/src/dart/analysis/search.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/search.dart
@@ -88,6 +88,8 @@
     } else if (kind == ElementKind.LABEL ||
         kind == ElementKind.LOCAL_VARIABLE) {
       return _searchReferences_Local(element, (n) => n is Block);
+    } else if (kind == ElementKind.LIBRARY) {
+      return _searchReferences_Library(element);
     } else if (kind == ElementKind.PARAMETER) {
       return _searchReferences_Parameter(element);
     } else if (kind == ElementKind.PREFIX) {
@@ -294,6 +296,34 @@
     return results;
   }
 
+  Future<List<SearchResult>> _searchReferences_Library(
+      LibraryElement element) async {
+    // Search only in drivers to which the library with the prefix was added.
+    String path = element.source.fullName;
+    if (!_driver.addedFiles.contains(path)) {
+      return const <SearchResult>[];
+    }
+
+    List<SearchResult> results = <SearchResult>[];
+    for (CompilationUnitElement unitElement in element.units) {
+      String unitPath = unitElement.source.fullName;
+      AnalysisResult unitAnalysisResult = await _driver.getResult(unitPath);
+      CompilationUnit unit = unitAnalysisResult.unit;
+      for (Directive directive in unit.directives) {
+        if (directive is PartOfDirective && directive.element == element) {
+          results.add(new SearchResult._(
+              unit.element,
+              SearchResultKind.REFERENCE,
+              directive.libraryName.offset,
+              directive.libraryName.length,
+              true,
+              false));
+        }
+      }
+    }
+    return results;
+  }
+
   Future<List<SearchResult>> _searchReferences_Local(
       Element element, bool isRootNode(AstNode n)) async {
     String path = element.source.fullName;
diff --git a/pkg/analyzer/lib/src/dart/ast/utilities.dart b/pkg/analyzer/lib/src/dart/ast/utilities.dart
index 4b9857d..d23485a 100644
--- a/pkg/analyzer/lib/src/dart/ast/utilities.dart
+++ b/pkg/analyzer/lib/src/dart/ast/utilities.dart
@@ -5752,6 +5752,7 @@
         _isEqualTokens(node.forKeyword, toNode.forKeyword),
         _isEqualTokens(node.leftParenthesis, toNode.leftParenthesis),
         _isEqualNodes(node.loopVariable, toNode.loopVariable),
+        _isEqualNodes(node.identifier, toNode.identifier),
         _isEqualTokens(node.inKeyword, toNode.inKeyword),
         _isEqualNodes(node.iterable, toNode.iterable),
         _isEqualTokens(node.rightParenthesis, toNode.rightParenthesis),
diff --git a/pkg/analyzer/lib/src/dart/constant/evaluation.dart b/pkg/analyzer/lib/src/dart/constant/evaluation.dart
index 8659dfe..23ad1a2 100644
--- a/pkg/analyzer/lib/src/dart/constant/evaluation.dart
+++ b/pkg/analyzer/lib/src/dart/constant/evaluation.dart
@@ -94,7 +94,7 @@
             typeProvider.objectType.element.context.analysisOptions.strongMode,
         validator =
             validator ?? new ConstantEvaluationValidator_ForProduction(),
-        typeSystem = typeSystem ?? new TypeSystemImpl();
+        typeSystem = typeSystem ?? new TypeSystemImpl(typeProvider);
 
   /**
    * Check that the arguments to a call to fromEnvironment() are correct. The
@@ -1293,8 +1293,7 @@
     ParameterizedType thenType = thenResult.type;
     ParameterizedType elseType = elseResult.type;
     return new DartObjectImpl.validWithUnknownValue(
-        _typeSystem.getLeastUpperBound(_typeProvider, thenType, elseType)
-        as InterfaceType);
+        _typeSystem.getLeastUpperBound(thenType, elseType) as InterfaceType);
   }
 
   @override
diff --git a/pkg/analyzer/lib/src/dart/element/element.dart b/pkg/analyzer/lib/src/dart/element/element.dart
index 4bfc3e97..218284d 100644
--- a/pkg/analyzer/lib/src/dart/element/element.dart
+++ b/pkg/analyzer/lib/src/dart/element/element.dart
@@ -4169,7 +4169,7 @@
   @override
   void appendTo(StringBuffer buffer) {
     buffer.write("export ");
-    (exportedLibrary as LibraryElementImpl).appendTo(buffer);
+    LibraryElementImpl.getImpl(exportedLibrary).appendTo(buffer);
   }
 }
 
@@ -5126,7 +5126,7 @@
   @override
   void appendTo(StringBuffer buffer) {
     buffer.write("import ");
-    (importedLibrary as LibraryElementImpl).appendTo(buffer);
+    LibraryElementImpl.getImpl(importedLibrary).appendTo(buffer);
   }
 
   @override
@@ -5937,6 +5937,16 @@
   }
 
   /**
+   * Return the [LibraryElementImpl] of the given [element].
+   */
+  static LibraryElementImpl getImpl(LibraryElement element) {
+    if (element is LibraryElementHandle) {
+      return getImpl(element.actualElement);
+    }
+    return element as LibraryElementImpl;
+  }
+
+  /**
    * Return `true` if the [library] has the given [capability].
    */
   static bool hasResolutionCapability(
diff --git a/pkg/analyzer/lib/src/dart/element/type.dart b/pkg/analyzer/lib/src/dart/element/type.dart
index 32a12a5..58932c6 100644
--- a/pkg/analyzer/lib/src/dart/element/type.dart
+++ b/pkg/analyzer/lib/src/dart/element/type.dart
@@ -828,7 +828,7 @@
         type,
         (DartType t, DartType s, _, __) =>
             (t as TypeImpl).isMoreSpecificThan(s, withDynamic),
-        new TypeSystemImpl().instantiateToBounds);
+        new TypeSystemImpl(null).instantiateToBounds);
   }
 
   @override
@@ -837,7 +837,7 @@
         this,
         type,
         (DartType t, DartType s, _, __) => t.isAssignableTo(s),
-        new TypeSystemImpl().instantiateToBounds);
+        new TypeSystemImpl(null).instantiateToBounds);
   }
 
   @override
@@ -1945,7 +1945,7 @@
       //
       if (element.library.context.analysisOptions.strongMode) {
         TypeImpl t = newTypeArguments[0];
-        newTypeArguments[0] = t.flattenFutures(new StrongTypeSystemImpl());
+        newTypeArguments[0] = t.flattenFutures(new StrongTypeSystemImpl(null));
       }
     }
 
@@ -2148,8 +2148,7 @@
       return _leastUpperBound(first, second);
     }
     AnalysisContext context = first.element.context;
-    return context.typeSystem
-        .getLeastUpperBound(context.typeProvider, first, second);
+    return context.typeSystem.getLeastUpperBound(first, second);
   }
 
   /**
diff --git a/pkg/analyzer/lib/src/dart/sdk/patch.dart b/pkg/analyzer/lib/src/dart/sdk/patch.dart
index 60ac49d..44f6765 100644
--- a/pkg/analyzer/lib/src/dart/sdk/patch.dart
+++ b/pkg/analyzer/lib/src/dart/sdk/patch.dart
@@ -99,6 +99,78 @@
     return 'the line ${location.lineNumber}';
   }
 
+  void _matchParameterLists(FormalParameterList baseParameters,
+      FormalParameterList patchParameters, String context()) {
+    if (baseParameters == null && patchParameters == null) return;
+    if (baseParameters == null || patchParameters == null) {
+      throw new ArgumentError("${context()}, parameter lists don't match");
+    }
+    if (baseParameters.parameters.length != patchParameters.parameters.length) {
+      throw new ArgumentError(
+          '${context()}, parameter lists have different lengths');
+    }
+    for (var i = 0; i < baseParameters.parameters.length; i++) {
+      _matchParameters(baseParameters.parameters[i],
+          patchParameters.parameters[i], () => '${context()}, parameter $i');
+    }
+  }
+
+  void _matchParameters(FormalParameter baseParameter,
+      FormalParameter patchParameter, String whichParameter()) {
+    if (baseParameter.identifier.name != patchParameter.identifier.name) {
+      throw new ArgumentError('${whichParameter()} has different name');
+    }
+    NormalFormalParameter baseParameterWithoutDefault =
+        _withoutDefault(baseParameter);
+    NormalFormalParameter patchParameterWithoutDefault =
+        _withoutDefault(patchParameter);
+    if (baseParameterWithoutDefault is SimpleFormalParameter &&
+        patchParameterWithoutDefault is SimpleFormalParameter) {
+      _matchTypes(baseParameterWithoutDefault.type,
+          patchParameterWithoutDefault.type, () => '${whichParameter()} type');
+    } else if (baseParameterWithoutDefault is FunctionTypedFormalParameter &&
+        patchParameterWithoutDefault is FunctionTypedFormalParameter) {
+      _matchTypes(
+          baseParameterWithoutDefault.returnType,
+          patchParameterWithoutDefault.returnType,
+          () => '${whichParameter()} return type');
+      _matchParameterLists(
+          baseParameterWithoutDefault.parameters,
+          patchParameterWithoutDefault.parameters,
+          () => '${whichParameter()} parameters');
+    } else if (baseParameterWithoutDefault is FieldFormalParameter &&
+        patchParameter is FieldFormalParameter) {
+      throw new ArgumentError(
+          '${whichParameter()} cannot be patched (field formal parameters are not supported)');
+    } else {
+      throw new ArgumentError(
+          '${whichParameter()} mismatch (different parameter kinds)');
+    }
+  }
+
+  void _matchTypes(TypeName baseType, TypeName patchType, String whichType()) {
+    error() => new ArgumentError("${whichType()} doesn't match");
+    if (baseType == null && patchType == null) return;
+    if (baseType == null || patchType == null) throw error();
+    // Match up the types token by token; this is more restrictive than strictly
+    // necessary, but it's easy and sufficient for patching purposes.
+    Token baseToken = baseType.beginToken;
+    Token patchToken = patchType.beginToken;
+    while (true) {
+      if (baseToken.lexeme != patchToken.lexeme) throw error();
+      if (identical(baseToken, baseType.endToken) &&
+          identical(patchToken, patchType.endToken)) {
+        break;
+      }
+      if (identical(baseToken, baseType.endToken) ||
+          identical(patchToken, patchType.endToken)) {
+        throw error();
+      }
+      baseToken = baseToken.next;
+      patchToken = patchToken.next;
+    }
+  }
+
   void _patchClassMembers(
       ClassDeclaration baseClass, ClassDeclaration patchClass) {
     String className = baseClass.name.name;
@@ -134,6 +206,12 @@
               } else {
                 _failExternalKeyword(name, baseMember.offset);
               }
+              _matchParameterLists(
+                  baseMember.parameters,
+                  patchMember.parameters,
+                  () => 'While patching $className.$name');
+              _matchTypes(baseMember.returnType, patchMember.returnType,
+                  () => 'While patching $className.$name, return type');
               // Replace the body.
               FunctionBody oldBody = baseMember.body;
               FunctionBody newBody = patchMember.body;
@@ -177,6 +255,11 @@
                     'Cannot patch external constructors with initializers '
                     'in $_baseDesc.');
               }
+              _matchParameterLists(
+                  baseMember.parameters, patchMember.parameters, () {
+                String nameSuffix = name == null ? '' : '.$name';
+                return 'While patching $className$nameSuffix';
+              });
               // Prepare nodes.
               FunctionBody baseBody = baseMember.body;
               FunctionBody patchBody = patchMember.body;
@@ -250,6 +333,14 @@
               } else {
                 _failExternalKeyword(name, baseDeclaration.offset);
               }
+              _matchParameterLists(
+                  baseDeclaration.functionExpression.parameters,
+                  patchDeclaration.functionExpression.parameters,
+                  () => 'While patching $name');
+              _matchTypes(
+                  baseDeclaration.returnType,
+                  patchDeclaration.returnType,
+                  () => 'While patching $name, return type');
               // Replace the body.
               FunctionExpression oldExpr = baseDeclaration.functionExpression;
               FunctionBody newBody = patchDeclaration.functionExpression.body;
@@ -300,6 +391,18 @@
     }
   }
 
+  NormalFormalParameter _withoutDefault(FormalParameter parameter) {
+    if (parameter is NormalFormalParameter) {
+      return parameter;
+    } else if (parameter is DefaultFormalParameter) {
+      return parameter.parameter;
+    } else {
+      // Should not happen.
+      assert(false);
+      return null;
+    }
+  }
+
   /**
    * Parse the given [source] into AST.
    */
diff --git a/pkg/analyzer/lib/src/generated/constant.dart b/pkg/analyzer/lib/src/generated/constant.dart
index db0eb79..5233b48 100644
--- a/pkg/analyzer/lib/src/generated/constant.dart
+++ b/pkg/analyzer/lib/src/generated/constant.dart
@@ -119,7 +119,7 @@
    * types.
    */
   ConstantEvaluator(this._source, this._typeProvider, {TypeSystem typeSystem})
-      : _typeSystem = typeSystem ?? new TypeSystemImpl();
+      : _typeSystem = typeSystem ?? new TypeSystemImpl(_typeProvider);
 
   EvaluationResult evaluate(Expression expression) {
     RecordingErrorListener errorListener = new RecordingErrorListener();
diff --git a/pkg/analyzer/lib/src/generated/error_verifier.dart b/pkg/analyzer/lib/src/generated/error_verifier.dart
index 91b072c..52aec1a 100644
--- a/pkg/analyzer/lib/src/generated/error_verifier.dart
+++ b/pkg/analyzer/lib/src/generated/error_verifier.dart
@@ -1659,28 +1659,24 @@
     });
 
     if (notInitFinalFields.isNotEmpty) {
-      AnalysisErrorWithProperties analysisError;
       List<String> names = notInitFinalFields.map((item) => item.name).toList();
       names.sort();
       if (names.length == 1) {
-        analysisError = _errorReporter.newErrorWithProperties(
+        _errorReporter.reportErrorForNode(
             StaticWarningCode.FINAL_NOT_INITIALIZED_CONSTRUCTOR_1,
             constructor.returnType,
             names);
       } else if (names.length == 2) {
-        analysisError = _errorReporter.newErrorWithProperties(
+        _errorReporter.reportErrorForNode(
             StaticWarningCode.FINAL_NOT_INITIALIZED_CONSTRUCTOR_2,
             constructor.returnType,
             names);
       } else {
-        analysisError = _errorReporter.newErrorWithProperties(
+        _errorReporter.reportErrorForNode(
             StaticWarningCode.FINAL_NOT_INITIALIZED_CONSTRUCTOR_3_PLUS,
             constructor.returnType,
             [names[0], names[1], names.length - 2]);
       }
-      analysisError.setProperty(
-          ErrorProperty.NOT_INITIALIZED_FIELDS, notInitFinalFields);
-      _errorReporter.reportError(analysisError);
     }
   }
 
@@ -6170,8 +6166,8 @@
       DartType actualStaticType, DartType expectedStaticType) {
     bool concrete = _options.strongMode && checker.isKnownFunction(expression);
     if (concrete && actualStaticType is FunctionType) {
-      actualStaticType = _typeSystem.functionTypeToConcreteType(
-          _typeProvider, actualStaticType);
+      actualStaticType =
+          _typeSystem.functionTypeToConcreteType(actualStaticType);
       // TODO(leafp): Move the Downcast functionality here.
     }
     return _typeSystem.isAssignableTo(actualStaticType, expectedStaticType);
@@ -6630,10 +6626,10 @@
           FunctionType requiredMemberFT =
               inheritanceManager.substituteTypeArgumentsInMemberFromInheritance(
                   requiredMemberType, memberName, enclosingType);
-          foundConcreteFT = typeSystem.functionTypeToConcreteType(
-              typeProvider, foundConcreteFT);
-          requiredMemberFT = typeSystem.functionTypeToConcreteType(
-              typeProvider, requiredMemberFT);
+          foundConcreteFT =
+              typeSystem.functionTypeToConcreteType(foundConcreteFT);
+          requiredMemberFT =
+              typeSystem.functionTypeToConcreteType(requiredMemberFT);
 
           // Strong mode does override checking for types in CodeChecker, so
           // we can skip it here. Doing it here leads to unnecessary duplicate
@@ -6655,6 +6651,45 @@
   }
 
   /**
+   * Return [FieldElement]s that are declared in the [ClassDeclaration] with
+   * the given [constructor], but are not initialized.
+   */
+  static List<FieldElement> computeNotInitializedFields(
+      ConstructorDeclaration constructor) {
+    Set<FieldElement> fields = new Set<FieldElement>();
+    var classDeclaration = constructor.parent as ClassDeclaration;
+    for (ClassMember fieldDeclaration in classDeclaration.members) {
+      if (fieldDeclaration is FieldDeclaration) {
+        for (VariableDeclaration field in fieldDeclaration.fields.variables) {
+          if (field.initializer == null) {
+            fields.add(field.element);
+          }
+        }
+      }
+    }
+
+    List<FormalParameter> parameters = constructor.parameters?.parameters ?? [];
+    for (FormalParameter parameter in parameters) {
+      if (parameter is DefaultFormalParameter) {
+        parameter = (parameter as DefaultFormalParameter).parameter;
+      }
+      if (parameter is FieldFormalParameter) {
+        FieldFormalParameterElement element =
+            parameter.identifier.staticElement as FieldFormalParameterElement;
+        fields.remove(element.field);
+      }
+    }
+
+    for (ConstructorInitializer initializer in constructor.initializers) {
+      if (initializer is ConstructorFieldInitializer) {
+        fields.remove(initializer.fieldName.staticElement);
+      }
+    }
+
+    return fields.toList();
+  }
+
+  /**
    * Return the static type of the given [expression] that is to be used for
    * type analysis.
    */
diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart
index 56f172a..2e1b856 100644
--- a/pkg/analyzer/lib/src/generated/resolver.dart
+++ b/pkg/analyzer/lib/src/generated/resolver.dart
@@ -100,7 +100,7 @@
       {TypeSystem typeSystem})
       : _nullType = typeProvider.nullType,
         _futureNullType = typeProvider.futureNullType,
-        _typeSystem = typeSystem ?? new TypeSystemImpl() {
+        _typeSystem = typeSystem ?? new TypeSystemImpl(typeProvider) {
     inDeprecatedMember = _currentLibrary.isDeprecated;
   }
 
@@ -1898,7 +1898,7 @@
    * @param errorReporter the error reporter
    */
   DeadCodeVerifier(this._errorReporter, {TypeSystem typeSystem})
-      : this._typeSystem = typeSystem ?? new TypeSystemImpl();
+      : this._typeSystem = typeSystem ?? new TypeSystemImpl(null);
 
   @override
   Object visitBinaryExpression(BinaryExpression node) {
@@ -4114,7 +4114,7 @@
     }
 
     DartType inferred = _inferredReturn.last;
-    inferred = _typeSystem.getLeastUpperBound(_typeProvider, type, inferred);
+    inferred = _typeSystem.getLeastUpperBound(type, inferred);
     _inferredReturn[_inferredReturn.length - 1] = inferred;
   }
 
@@ -6709,7 +6709,6 @@
           originalType.typeFormals.isNotEmpty &&
           ts is StrongTypeSystemImpl) {
         contextType = ts.inferGenericFunctionCall(
-            typeProvider,
             originalType,
             DartType.EMPTY_LIST,
             DartType.EMPTY_LIST,
@@ -6769,7 +6768,7 @@
             staticClosureType,
             (DartType t, DartType s, _, __) =>
                 (t as TypeImpl).isMoreSpecificThan(s),
-            new TypeSystemImpl().instantiateToBounds,
+            new TypeSystemImpl(typeProvider).instantiateToBounds,
             returnRelation: (s, t) => true)) {
       return;
     }
@@ -8822,8 +8821,12 @@
             } else {
               libraryScope ??= new LibraryScope(library);
               typeParametersScope ??= createTypeParametersScope();
-              typeNameResolver ??= new TypeNameResolver(new TypeSystemImpl(),
-                  typeProvider, library, source, errorListener);
+              typeNameResolver ??= new TypeNameResolver(
+                  new TypeSystemImpl(typeProvider),
+                  typeProvider,
+                  library,
+                  source,
+                  errorListener);
               typeNameResolver.nameScope = typeParametersScope;
               _resolveTypeName(bound);
               typeParameterElement.bound = bound.type;
@@ -10696,7 +10699,7 @@
       this.parameterElements,
       DeclaredVariables declaredVariables,
       {TypeSystem typeSystem})
-      : _typeSystem = typeSystem ?? new TypeSystemImpl(),
+      : _typeSystem = typeSystem ?? new TypeSystemImpl(typeProvider),
         super(
             new ConstantEvaluationEngine(typeProvider, declaredVariables,
                 typeSystem: typeSystem),
diff --git a/pkg/analyzer/lib/src/generated/static_type_analyzer.dart b/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
index 3367b16..63b7b54 100644
--- a/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
+++ b/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
@@ -250,7 +250,6 @@
       ExecutableElement staticMethodElement = node.staticElement;
       DartType staticType = _computeStaticReturnType(staticMethodElement);
       staticType = _typeSystem.refineBinaryExpressionType(
-          _typeProvider,
           node.leftHandSide.staticType,
           operator,
           node.rightHandSide.staticType,
@@ -261,7 +260,6 @@
         DartType propagatedType =
             _computeStaticReturnType(propagatedMethodElement);
         propagatedType = _typeSystem.refineBinaryExpressionType(
-            _typeProvider,
             node.leftHandSide.propagatedType,
             operator,
             node.rightHandSide.propagatedType,
@@ -344,7 +342,6 @@
     ExecutableElement staticMethodElement = node.staticElement;
     DartType staticType = _computeStaticReturnType(staticMethodElement);
     staticType = _typeSystem.refineBinaryExpressionType(
-        _typeProvider,
         node.leftOperand.staticType,
         node.operator.type,
         node.rightOperand.staticType,
@@ -355,7 +352,6 @@
       DartType propagatedType =
           _computeStaticReturnType(propagatedMethodElement);
       propagatedType = _typeSystem.refineBinaryExpressionType(
-          _typeProvider,
           node.leftOperand.bestType,
           node.operator.type,
           node.rightOperand.bestType,
@@ -641,7 +637,6 @@
       var listTypeParam = _typeProvider.listType.typeParameters[0].type;
 
       DartType inferred = ts.inferGenericFunctionCall(
-          _typeProvider,
           _typeProvider.listType,
           new List.filled(elementTypes.length, listTypeParam),
           elementTypes,
@@ -724,7 +719,6 @@
       var valueTypeParam = _typeProvider.mapType.typeParameters[1].type;
 
       DartType inferred = ts.inferGenericFunctionCall(
-          _typeProvider,
           _typeProvider.mapType,
           new List.filled(keyTypes.length, keyTypeParam, growable: true)
             ..addAll(new List.filled(valueTypes.length, valueTypeParam)),
@@ -1435,7 +1429,7 @@
       staticType2 = _dynamicType;
     }
     DartType staticType =
-        _typeSystem.getLeastUpperBound(_typeProvider, staticType1, staticType2);
+        _typeSystem.getLeastUpperBound(staticType1, staticType2);
     if (staticType == null) {
       staticType = _dynamicType;
     }
@@ -1449,8 +1443,8 @@
       if (propagatedType2 == null) {
         propagatedType2 = staticType2;
       }
-      DartType propagatedType = _typeSystem.getLeastUpperBound(
-          _typeProvider, propagatedType1, propagatedType2);
+      DartType propagatedType =
+          _typeSystem.getLeastUpperBound(propagatedType1, propagatedType2);
       _resolver.recordPropagatedTypeIfBetter(node, propagatedType);
     }
   }
@@ -1918,7 +1912,7 @@
     if (context is FunctionType &&
         type is FunctionType &&
         ts is StrongTypeSystemImpl) {
-      return ts.inferFunctionTypeInstantiation(_typeProvider, context, type);
+      return ts.inferFunctionTypeInstantiation(context, type);
     }
     return type;
   }
@@ -2012,8 +2006,8 @@
           }
         }
       }
-      return ts.inferGenericFunctionCall(_typeProvider, fnType, paramTypes,
-          argTypes, fnType.returnType, InferenceContext.getContext(node),
+      return ts.inferGenericFunctionCall(fnType, paramTypes, argTypes,
+          fnType.returnType, InferenceContext.getContext(node),
           errorReporter: _resolver.errorReporter, errorNode: errorNode);
     }
     return null;
@@ -2431,7 +2425,7 @@
     if (result == null) {
       result = type;
     } else {
-      result = _typeSystem.getLeastUpperBound(_typeProvider, result, type);
+      result = _typeSystem.getLeastUpperBound(result, type);
     }
     return null;
   }
diff --git a/pkg/analyzer/lib/src/generated/type_system.dart b/pkg/analyzer/lib/src/generated/type_system.dart
index 2f42296..ed117af 100644
--- a/pkg/analyzer/lib/src/generated/type_system.dart
+++ b/pkg/analyzer/lib/src/generated/type_system.dart
@@ -162,7 +162,9 @@
    */
   final List<String> nonnullableTypes;
 
-  StrongTypeSystemImpl(
+  final TypeProvider typeProvider;
+
+  StrongTypeSystemImpl(this.typeProvider,
       {this.implicitCasts: true,
       this.nonnullableTypes: AnalysisOptionsImpl.NONNULLABLE_TYPES});
 
@@ -197,8 +199,7 @@
   }
 
   @override
-  FunctionType functionTypeToConcreteType(
-      TypeProvider typeProvider, FunctionType t) {
+  FunctionType functionTypeToConcreteType(FunctionType t) {
     // TODO(jmesserly): should we use a real "fuzzyArrow" bit on the function
     // type? That would allow us to implement this in the subtype relation.
     // TODO(jmesserly): we'll need to factor this differently if we want to
@@ -228,6 +229,17 @@
 
   /**
    * Given a type t, if t is an interface type with a call method
+   * defined, return the definite function type for the call method,
+   * otherwise return null.
+   */
+  FunctionType getCallMethodDefiniteType(DartType t) {
+    var type = getCallMethodType(t);
+    if (type == null) return type;
+    return functionTypeToConcreteType(type);
+  }
+
+  /**
+   * Given a type t, if t is an interface type with a call method
    * defined, return the function type for the call method, otherwise
    * return null.
    */
@@ -239,8 +251,7 @@
   }
 
   /// Computes the greatest lower bound of [type1] and [type2].
-  DartType getGreatestLowerBound(
-      TypeProvider provider, DartType type1, DartType type2,
+  DartType getGreatestLowerBound(DartType type1, DartType type2,
       {dynamicIsBottom: false}) {
     // The greatest lower bound relation is reflexive.
     if (identical(type1, type2)) {
@@ -271,7 +282,7 @@
 
     // Function types have structural GLB.
     if (type1 is FunctionType && type2 is FunctionType) {
-      return _functionGreatestLowerBound(provider, type1, type2);
+      return _functionGreatestLowerBound(type1, type2);
     }
 
     // Otherwise, the GLB of two types is one of them it if it is a subtype of
@@ -285,7 +296,7 @@
     }
 
     // No subtype relation, so no known GLB.
-    return provider.bottomType;
+    return typeProvider.bottomType;
   }
 
   /**
@@ -308,8 +319,7 @@
    * Compute the least upper bound of two types.
    */
   @override
-  DartType getLeastUpperBound(
-      TypeProvider typeProvider, DartType type1, DartType type2,
+  DartType getLeastUpperBound(DartType type1, DartType type2,
       {bool dynamicIsBottom: false}) {
     if (isNullableType(type1) && isNonNullableType(type2)) {
       assert(type2 is InterfaceType);
@@ -319,8 +329,8 @@
       assert(type1 is InterfaceType);
       type1 = getLeastNullableSupertype(type1 as InterfaceType);
     }
-    return super.getLeastUpperBound(typeProvider, type1, type2,
-        dynamicIsBottom: dynamicIsBottom);
+    return super
+        .getLeastUpperBound(type1, type2, dynamicIsBottom: dynamicIsBottom);
   }
 
   /**
@@ -334,7 +344,7 @@
    * uninstantiated, or a [fnType] that is already instantiated, it will have
    * no effect and return [fnType].
    */
-  FunctionType inferFunctionTypeInstantiation(TypeProvider typeProvider,
+  FunctionType inferFunctionTypeInstantiation(
       FunctionType contextType, FunctionType fnType) {
     if (contextType.typeFormals.isNotEmpty || fnType.typeFormals.isEmpty) {
       return fnType;
@@ -388,7 +398,6 @@
   /// parameter Tj. Instead we track Uj and Lj where U is the upper bound and
   /// L is the lower bound of that type parameter.
   /*=T*/ inferGenericFunctionCall/*<T extends ParameterizedType>*/(
-      TypeProvider typeProvider,
       /*=T*/ genericType,
       List<DartType> declaredParameterTypes,
       List<DartType> argumentTypes,
@@ -577,12 +586,8 @@
   }
 
   @override
-  DartType refineBinaryExpressionType(
-      TypeProvider typeProvider,
-      DartType leftType,
-      TokenType operator,
-      DartType rightType,
-      DartType currentType) {
+  DartType refineBinaryExpressionType(DartType leftType, TokenType operator,
+      DartType rightType, DartType currentType) {
     if (leftType is TypeParameterType &&
         leftType.element.bound == typeProvider.numType) {
       if (rightType == leftType || rightType == typeProvider.intType) {
@@ -605,14 +610,14 @@
       }
       return currentType;
     }
-    return super.refineBinaryExpressionType(
-        typeProvider, leftType, operator, rightType, currentType);
+    return super
+        .refineBinaryExpressionType(leftType, operator, rightType, currentType);
   }
 
   @override
-  DartType typeToConcreteType(TypeProvider typeProvider, DartType t) {
+  DartType typeToConcreteType(DartType t) {
     if (t is FunctionType) {
-      return functionTypeToConcreteType(typeProvider, t);
+      return functionTypeToConcreteType(t);
     }
     return t;
   }
@@ -634,8 +639,7 @@
    *
    * - Use the GLB of their return types.
    */
-  DartType _functionGreatestLowerBound(
-      TypeProvider provider, FunctionType f, FunctionType g) {
+  DartType _functionGreatestLowerBound(FunctionType f, FunctionType g) {
     // Calculate the LUB of each corresponding pair of parameters.
     List<ParameterElement> parameters = [];
 
@@ -646,8 +650,7 @@
       DartType paramType;
       if (fType != null && gType != null) {
         // If both functions have this parameter, include both of their types.
-        paramType =
-            getLeastUpperBound(provider, fType, gType, dynamicIsBottom: true);
+        paramType = getLeastUpperBound(fType, gType, dynamicIsBottom: true);
       } else {
         paramType = fType ?? gType;
       }
@@ -720,18 +723,16 @@
 
     // Edge case. Dart does not support functions with both optional positional
     // and named parameters. If we would synthesize that, give up.
-    if (hasPositional && hasNamed) return provider.bottomType;
+    if (hasPositional && hasNamed) return typeProvider.bottomType;
 
     // Calculate the GLB of the return type.
-    DartType returnType =
-        getGreatestLowerBound(provider, f.returnType, g.returnType);
+    DartType returnType = getGreatestLowerBound(f.returnType, g.returnType);
     return new FunctionElementImpl.synthetic(parameters, returnType).type;
   }
 
   @override
-  DartType _functionParameterBound(
-          TypeProvider provider, DartType f, DartType g) =>
-      getGreatestLowerBound(provider, f, g, dynamicIsBottom: true);
+  DartType _functionParameterBound(DartType f, DartType g) =>
+      getGreatestLowerBound(f, g, dynamicIsBottom: true);
 
   /// Given a type return its name prepended with the URI to its containing
   /// library and separated by a comma.
@@ -791,8 +792,7 @@
    * TODO(leafp): Figure out the right final algorithm and implement it.
    */
   @override
-  DartType _interfaceLeastUpperBound(
-      TypeProvider provider, InterfaceType type1, InterfaceType type2) {
+  DartType _interfaceLeastUpperBound(InterfaceType type1, InterfaceType type2) {
     if (isSubtypeOf(type1, type2)) {
       return type2;
     }
@@ -806,14 +806,14 @@
       assert(tArgs1.length == tArgs2.length);
       List<DartType> tArgs = new List(tArgs1.length);
       for (int i = 0; i < tArgs1.length; i++) {
-        tArgs[i] = getLeastUpperBound(provider, tArgs1[i], tArgs2[i]);
+        tArgs[i] = getLeastUpperBound(tArgs1[i], tArgs2[i]);
       }
       InterfaceTypeImpl lub = new InterfaceTypeImpl(type1.element);
       lub.typeArguments = tArgs;
       return lub;
     }
     return InterfaceTypeImpl.computeLeastUpperBound(type1, type2) ??
-        provider.dynamicType;
+        typeProvider.dynamicType;
   }
 
   /// Check that [f1] is a subtype of [f2].
@@ -967,7 +967,7 @@
     // the interface type declares a call method with a type
     // which is a super type of the function type.
     if (t1 is InterfaceType && t2 is FunctionType) {
-      var callType = getCallMethodType(t1);
+      var callType = getCallMethodDefiniteType(t1);
       return (callType != null) && _isFunctionSubtypeOf(callType, t2);
     }
 
@@ -1014,8 +1014,7 @@
    * the "inheritance" chain extended by the bounds placed on the variables.
    */
   @override
-  DartType _typeParameterLeastUpperBound(
-      TypeProvider provider, DartType type1, DartType type2) {
+  DartType _typeParameterLeastUpperBound(DartType type1, DartType type2) {
     if (isSubtypeOf(type1, type2)) {
       return type2;
     }
@@ -1024,16 +1023,16 @@
     }
     if (type1 is TypeParameterType) {
       type1 = type1
-          .resolveToBound(provider.objectType)
-          .substitute2([provider.objectType], [type1]);
-      return getLeastUpperBound(provider, type1, type2);
+          .resolveToBound(typeProvider.objectType)
+          .substitute2([typeProvider.objectType], [type1]);
+      return getLeastUpperBound(type1, type2);
     }
     // We should only be called when at least one of the types is a
     // TypeParameterType
     type2 = type2
-        .resolveToBound(provider.objectType)
-        .substitute2([provider.objectType], [type2]);
-    return getLeastUpperBound(provider, type1, type2);
+        .resolveToBound(typeProvider.objectType)
+        .substitute2([typeProvider.objectType], [type2]);
+    return getLeastUpperBound(type1, type2);
   }
 }
 
@@ -1046,6 +1045,11 @@
  */
 abstract class TypeSystem {
   /**
+   * The provider of types for the system
+   */
+  TypeProvider get typeProvider;
+
+  /**
    * Tries to promote from the first type from the second type, and returns the
    * promoted type if it succeeds, otherwise null.
    *
@@ -1075,14 +1079,12 @@
    * Only the outer-most arrow can be strict. Any others must be fuzzy, because
    * we don't know what function value will be passed there.
    */
-  FunctionType functionTypeToConcreteType(
-      TypeProvider typeProvider, FunctionType t);
+  FunctionType functionTypeToConcreteType(FunctionType t);
 
   /**
    * Compute the least upper bound of two types.
    */
-  DartType getLeastUpperBound(
-      TypeProvider typeProvider, DartType type1, DartType type2,
+  DartType getLeastUpperBound(DartType type1, DartType type2,
       {bool dynamicIsBottom: false}) {
     // The least upper bound relation is reflexive.
     if (identical(type1, type2)) {
@@ -1107,7 +1109,7 @@
     }
 
     if (type1 is TypeParameterType || type2 is TypeParameterType) {
-      return _typeParameterLeastUpperBound(typeProvider, type1, type2);
+      return _typeParameterLeastUpperBound(type1, type2);
     }
 
     // The least upper bound of a function type and an interface type T is the
@@ -1122,11 +1124,11 @@
     // At this point type1 and type2 should both either be interface types or
     // function types.
     if (type1 is InterfaceType && type2 is InterfaceType) {
-      return _interfaceLeastUpperBound(typeProvider, type1, type2);
+      return _interfaceLeastUpperBound(type1, type2);
     }
 
     if (type1 is FunctionType && type2 is FunctionType) {
-      return _functionLeastUpperBound(typeProvider, type1, type2);
+      return _functionLeastUpperBound(type1, type2);
     }
 
     // Should never happen. As a defensive measure, return the dynamic type.
@@ -1222,12 +1224,8 @@
    * Attempts to make a better guess for the type of a binary with the given
    * [operator], given that resolution has so far produced the [currentType].
    */
-  DartType refineBinaryExpressionType(
-      TypeProvider typeProvider,
-      DartType leftType,
-      TokenType operator,
-      DartType rightType,
-      DartType currentType) {
+  DartType refineBinaryExpressionType(DartType leftType, TokenType operator,
+      DartType rightType, DartType currentType) {
     // bool
     if (operator == TokenType.AMPERSAND_AMPERSAND ||
         operator == TokenType.BAR_BAR ||
@@ -1304,7 +1302,7 @@
    * non-concrete function type is made concrete by replacing dynamic
    * parameters with Object.
    */
-  DartType typeToConcreteType(TypeProvider typeProvider, DartType t);
+  DartType typeToConcreteType(DartType t);
 
   /**
    * Compute the least upper bound of function types [f] and [g].
@@ -1321,8 +1319,7 @@
    * - Compute the LUB of each corresponding pair of parameter and return types.
    *   Return a function type with those types.
    */
-  DartType _functionLeastUpperBound(
-      TypeProvider provider, FunctionType f, FunctionType g) {
+  DartType _functionLeastUpperBound(FunctionType f, FunctionType g) {
     // TODO(rnystrom): Right now, this assumes f and g do not have any type
     // parameters. Revisit that in the presence of generic methods.
     List<DartType> fRequired = f.normalParameterTypes;
@@ -1336,7 +1333,7 @@
     // If F and G differ in their number of required parameters, then the
     // least upper bound of F and G is Function.
     if (fRequired.length != gRequired.length) {
-      return provider.functionType;
+      return typeProvider.functionType;
     }
 
     // Calculate the LUB of each corresponding pair of parameters.
@@ -1345,7 +1342,7 @@
     for (int i = 0; i < fRequired.length; i++) {
       parameters.add(new ParameterElementImpl.synthetic(
           fRequiredNames[i],
-          _functionParameterBound(provider, fRequired[i], gRequired[i]),
+          _functionParameterBound(fRequired[i], gRequired[i]),
           ParameterKind.REQUIRED));
     }
 
@@ -1358,7 +1355,7 @@
     for (int i = 0; i < length; i++) {
       parameters.add(new ParameterElementImpl.synthetic(
           fPositionalNames[i],
-          _functionParameterBound(provider, fPositional[i], gPositional[i]),
+          _functionParameterBound(fPositional[i], gPositional[i]),
           ParameterKind.POSITIONAL));
     }
 
@@ -1367,13 +1364,12 @@
     for (String name in fNamed.keys.toSet()..retainAll(gNamed.keys)) {
       parameters.add(new ParameterElementImpl.synthetic(
           name,
-          _functionParameterBound(provider, fNamed[name], gNamed[name]),
+          _functionParameterBound(fNamed[name], gNamed[name]),
           ParameterKind.NAMED));
     }
 
     // Calculate the LUB of the return type.
-    DartType returnType =
-        getLeastUpperBound(provider, f.returnType, g.returnType);
+    DartType returnType = getLeastUpperBound(f.returnType, g.returnType);
     return new FunctionElementImpl.synthetic(parameters, returnType).type;
   }
 
@@ -1384,24 +1380,21 @@
    * In spec mode, this uses least upper bound, which... doesn't really make
    * much sense. Strong mode overrides this to use greatest lower bound.
    */
-  DartType _functionParameterBound(
-          TypeProvider provider, DartType f, DartType g) =>
-      getLeastUpperBound(provider, f, g);
+  DartType _functionParameterBound(DartType f, DartType g) =>
+      getLeastUpperBound(f, g);
 
   /**
    * Given two [InterfaceType]s [type1] and [type2] return their least upper
    * bound in a type system specific manner.
    */
-  DartType _interfaceLeastUpperBound(
-      TypeProvider provider, InterfaceType type1, InterfaceType type2);
+  DartType _interfaceLeastUpperBound(InterfaceType type1, InterfaceType type2);
 
   /**
    * Given two [DartType]s [type1] and [type2] at least one of which is a
    * [TypeParameterType], return their least upper bound in a type system
    * specific manner.
    */
-  DartType _typeParameterLeastUpperBound(
-      TypeProvider provider, DartType type1, DartType type2);
+  DartType _typeParameterLeastUpperBound(DartType type1, DartType type2);
 
   /**
    * Create either a strong mode or regular type system based on context.
@@ -1409,10 +1402,10 @@
   static TypeSystem create(AnalysisContext context) {
     var options = context.analysisOptions as AnalysisOptionsImpl;
     return options.strongMode
-        ? new StrongTypeSystemImpl(
+        ? new StrongTypeSystemImpl(context.typeProvider,
             implicitCasts: options.implicitCasts,
             nonnullableTypes: options.nonnullableTypes)
-        : new TypeSystemImpl();
+        : new TypeSystemImpl(context.typeProvider);
   }
 }
 
@@ -1420,7 +1413,9 @@
  * Implementation of [TypeSystem] using the rules in the Dart specification.
  */
 class TypeSystemImpl extends TypeSystem {
-  TypeSystemImpl();
+  final TypeProvider typeProvider;
+
+  TypeSystemImpl(this.typeProvider);
 
   @override
   DartType tryPromoteToType(DartType to, DartType from) {
@@ -1435,9 +1430,7 @@
   }
 
   @override
-  FunctionType functionTypeToConcreteType(
-          TypeProvider typeProvider, FunctionType t) =>
-      t;
+  FunctionType functionTypeToConcreteType(FunctionType t) => t;
 
   /**
    * Instantiate a parameterized type using `dynamic` for all generic
@@ -1469,22 +1462,20 @@
   }
 
   @override
-  DartType typeToConcreteType(TypeProvider typeProvider, DartType t) => t;
+  DartType typeToConcreteType(DartType t) => t;
 
   @override
-  DartType _interfaceLeastUpperBound(
-      TypeProvider provider, InterfaceType type1, InterfaceType type2) {
+  DartType _interfaceLeastUpperBound(InterfaceType type1, InterfaceType type2) {
     InterfaceType result =
         InterfaceTypeImpl.computeLeastUpperBound(type1, type2);
-    return result ?? provider.dynamicType;
+    return result ?? typeProvider.dynamicType;
   }
 
   @override
-  DartType _typeParameterLeastUpperBound(
-      TypeProvider provider, DartType type1, DartType type2) {
-    type1 = type1.resolveToBound(provider.objectType);
-    type2 = type2.resolveToBound(provider.objectType);
-    return getLeastUpperBound(provider, type1, type2);
+  DartType _typeParameterLeastUpperBound(DartType type1, DartType type2) {
+    type1 = type1.resolveToBound(typeProvider.objectType);
+    type2 = type2.resolveToBound(typeProvider.objectType);
+    return getLeastUpperBound(type1, type2);
   }
 }
 
@@ -1512,17 +1503,16 @@
 /// As currently designed, an instance of this class should only be used to
 /// infer a single call and discarded immediately afterwards.
 class _StrongInferenceTypeSystem extends StrongTypeSystemImpl {
-  final TypeProvider _typeProvider;
-
   /// The outer strong mode type system, used for GLB and LUB, so we don't
   /// recurse into our constraint solving code.
   final StrongTypeSystemImpl _typeSystem;
   final Map<TypeParameterType, _TypeParameterBound> _bounds;
 
-  _StrongInferenceTypeSystem(this._typeProvider, this._typeSystem,
+  _StrongInferenceTypeSystem(TypeProvider typeProvider, this._typeSystem,
       Iterable<TypeParameterElement> typeFormals)
       : _bounds = new Map.fromIterable(typeFormals,
-            key: (t) => t.type, value: (t) => new _TypeParameterBound());
+            key: (t) => t.type, value: (t) => new _TypeParameterBound()),
+        super(typeProvider);
 
   /// Given the constraints that were given by calling [isSubtypeOf], find the
   /// instantiation of the generic function that satisfies these constraints.
@@ -1598,8 +1588,7 @@
         // This will typically lead to top with the current rules, but it will
         // work with `bottom` or if we remove Future flattening.
         var f = lowerBound as FutureUnionType;
-        lowerBound = _typeSystem.getLeastUpperBound(
-            _typeProvider, f.futureOfType, f.type);
+        lowerBound = _typeSystem.getLeastUpperBound(f.futureOfType, f.type);
       }
       if (upperBound is FutureUnionType) {
         // T <: upperBound, where upperBound is Future<A> | A.
@@ -1666,8 +1655,7 @@
         // We already know T1 <: U, for some U.
         // So update U to reflect the new constraint T1 <: GLB(U, T2)
         //
-        bound.upper =
-            _typeSystem.getGreatestLowerBound(_typeProvider, bound.upper, t2);
+        bound.upper = _typeSystem.getGreatestLowerBound(bound.upper, t2);
         // Optimistically assume we will be able to satisfy the constraint.
         return true;
       }
@@ -1681,8 +1669,7 @@
         // We already know L <: T2, for some L.
         // So update L to reflect the new constraint LUB(L, T1) <: T2
         //
-        bound.lower =
-            _typeSystem.getLeastUpperBound(_typeProvider, bound.lower, t1);
+        bound.lower = _typeSystem.getLeastUpperBound(bound.lower, t1);
         // Optimistically assume we will be able to satisfy the constraint.
         return true;
       }
diff --git a/pkg/analyzer/lib/src/summary/link.dart b/pkg/analyzer/lib/src/summary/link.dart
index 7684f56..e261675 100644
--- a/pkg/analyzer/lib/src/summary/link.dart
+++ b/pkg/analyzer/lib/src/summary/link.dart
@@ -2556,13 +2556,8 @@
           }
         });
         // Perform inference.
-        FunctionType inferred = ts.inferGenericFunctionCall(
-            typeProvider,
-            rawMethodType,
-            paramTypes,
-            argTypes,
-            rawMethodType.returnType,
-            null);
+        FunctionType inferred = ts.inferGenericFunctionCall(rawMethodType,
+            paramTypes, argTypes, rawMethodType.returnType, null);
         return inferred;
       }
     }
@@ -2571,7 +2566,7 @@
   }
 
   DartType _leastUpperBound(DartType s, DartType t) {
-    return linker.typeSystem.getLeastUpperBound(typeProvider, s, t);
+    return linker.typeSystem.getLeastUpperBound(s, t);
   }
 
   List<DartType> _popList(int n) {
@@ -2587,8 +2582,8 @@
           left.lookUpInheritedMethod(operator.lexeme, library: library);
       if (method != null) {
         DartType type = method.returnType;
-        type = linker.typeSystem.refineBinaryExpressionType(
-            typeProvider, left, operator, right, type);
+        type = linker.typeSystem
+            .refineBinaryExpressionType(left, operator, right, type);
         stack.add(type);
         return;
       }
@@ -3654,8 +3649,9 @@
   /**
    * Get an instance of [TypeSystem] for use during linking.
    */
-  TypeSystem get typeSystem => _typeSystem ??=
-      strongMode ? new StrongTypeSystemImpl() : new TypeSystemImpl();
+  TypeSystem get typeSystem => _typeSystem ??= strongMode
+      ? new StrongTypeSystemImpl(typeProvider)
+      : new TypeSystemImpl(typeProvider);
 
   /**
    * Get the element representing `void`.
diff --git a/pkg/analyzer/lib/src/summary/resynthesize.dart b/pkg/analyzer/lib/src/summary/resynthesize.dart
index c3734e8..69298a5 100644
--- a/pkg/analyzer/lib/src/summary/resynthesize.dart
+++ b/pkg/analyzer/lib/src/summary/resynthesize.dart
@@ -230,9 +230,13 @@
       List<UnlinkedUnit> serializedUnits = <UnlinkedUnit>[unlinkedSummary];
       for (String part in serializedUnits[0].publicNamespace.parts) {
         Source partSource = sourceFactory.resolveUri(librarySource, part);
-        String partAbsUri = partSource.uri.toString();
-        serializedUnits.add(_getUnlinkedSummaryOrNull(partAbsUri) ??
-            new UnlinkedUnitBuilder(codeRange: new CodeRangeBuilder()));
+        if (partSource == null) {
+          serializedUnits.add(null);
+        } else {
+          String partAbsUri = partSource.uri.toString();
+          serializedUnits.add(_getUnlinkedSummaryOrNull(partAbsUri) ??
+              new UnlinkedUnitBuilder(codeRange: new CodeRangeBuilder()));
+        }
       }
       _LibraryResynthesizer libraryResynthesizer = new _LibraryResynthesizer(
           this, serializedLibrary, serializedUnits, librarySource);
@@ -1034,7 +1038,9 @@
           unlinkedDefiningUnit.publicNamespace.parts[i - 1],
           unlinkedDefiningUnit.parts[i - 1],
           i);
-      partResynthesizers.add(partResynthesizer);
+      if (partResynthesizer != null) {
+        partResynthesizers.add(partResynthesizer);
+      }
     }
     library.parts = partResynthesizers.map((r) => r.unit).toList();
     // Populate units.
@@ -1055,13 +1061,16 @@
   }
 
   /**
-   * Create, but do not populate, the [CompilationUnitElement] for a part other
-   * than the defining compilation unit.
+   * Create a [_UnitResynthesizer] that will resynthesize the part with the
+   * given [uri]. Return `null` if the [uri] is invalid.
    */
   _UnitResynthesizer buildPart(_UnitResynthesizer definingUnitResynthesizer,
       String uri, UnlinkedPart partDecl, int unitNum) {
     Source unitSource =
         summaryResynthesizer.sourceFactory.resolveUri(librarySource, uri);
+    if (unitSource == null) {
+      return null;
+    }
     _UnitResynthesizer partResynthesizer =
         createUnitResynthesizer(unitNum, unitSource, partDecl);
     CompilationUnitElementImpl partUnit = partResynthesizer.unit;
diff --git a/pkg/analyzer/lib/src/summary/summarize_ast.dart b/pkg/analyzer/lib/src/summary/summarize_ast.dart
index 5d35783..46b7b2d 100644
--- a/pkg/analyzer/lib/src/summary/summarize_ast.dart
+++ b/pkg/analyzer/lib/src/summary/summarize_ast.dart
@@ -597,7 +597,7 @@
     }
     String text = documentationComment.tokens
         .map((Token t) => t.toString())
-        .join()
+        .join('\n')
         .replaceAll('\r\n', '\n');
     return new UnlinkedDocumentationCommentBuilder(text: text);
   }
diff --git a/pkg/analyzer/lib/src/task/dart.dart b/pkg/analyzer/lib/src/task/dart.dart
index edd2d55..6de317c 100644
--- a/pkg/analyzer/lib/src/task/dart.dart
+++ b/pkg/analyzer/lib/src/task/dart.dart
@@ -6126,7 +6126,7 @@
     if (options.strongMode) {
       CodeChecker checker = new CodeChecker(
           typeProvider,
-          new StrongTypeSystemImpl(
+          new StrongTypeSystemImpl(typeProvider,
               implicitCasts: options.implicitCasts,
               nonnullableTypes: options.nonnullableTypes),
           errorListener,
diff --git a/pkg/analyzer/lib/src/task/strong/checker.dart b/pkg/analyzer/lib/src/task/strong/checker.dart
index 8beac15..c528c65c 100644
--- a/pkg/analyzer/lib/src/task/strong/checker.dart
+++ b/pkg/analyzer/lib/src/task/strong/checker.dart
@@ -38,7 +38,7 @@
       type is FunctionType &&
       _hasStrictArrow(expression)) {
     // Remove fuzzy arrow if possible.
-    return typeSystem.functionTypeToConcreteType(typeProvider, type);
+    return typeSystem.functionTypeToConcreteType(type);
   }
   return type;
 }
@@ -705,7 +705,7 @@
       var rhsType = _getDefiniteType(expr.rightHandSide);
       var lhsType = _getDefiniteType(expr.leftHandSide);
       var returnType = rules.refineBinaryExpressionType(
-          typeProvider, lhsType, op, rhsType, functionType.returnType);
+          lhsType, op, rhsType, functionType.returnType);
 
       // Check the argument for an implicit cast.
       _checkImplicitCast(expr.rightHandSide, paramTypes[0], from: rhsType);
@@ -901,8 +901,8 @@
         var functionType = element.type;
         var rhsType = typeProvider.intType;
         var lhsType = _getDefiniteType(operand);
-        var returnType = rules.refineBinaryExpressionType(typeProvider, lhsType,
-            TokenType.PLUS, rhsType, functionType.returnType);
+        var returnType = rules.refineBinaryExpressionType(
+            lhsType, TokenType.PLUS, rhsType, functionType.returnType);
 
         // Skip the argument check - `int` cannot be downcast.
         //
@@ -985,7 +985,7 @@
     if (type is FunctionType) {
       return type;
     } else if (type is InterfaceType) {
-      return rules.getCallMethodType(type);
+      return rules.getCallMethodDefiniteType(type);
     }
     return null;
   }
diff --git a/pkg/analyzer/lib/src/task/strong_mode.dart b/pkg/analyzer/lib/src/task/strong_mode.dart
index 0917684..d60460e 100644
--- a/pkg/analyzer/lib/src/task/strong_mode.dart
+++ b/pkg/analyzer/lib/src/task/strong_mode.dart
@@ -81,7 +81,9 @@
    */
   InstanceMemberInferrer(this.typeProvider, this.inheritanceManager,
       {TypeSystem typeSystem})
-      : typeSystem = (typeSystem != null) ? typeSystem : new TypeSystemImpl();
+      : typeSystem = (typeSystem != null)
+            ? typeSystem
+            : new TypeSystemImpl(typeProvider);
 
   /**
    * Infer type information for all of the instance members in the given
diff --git a/pkg/analyzer/test/generated/static_type_analyzer_test.dart b/pkg/analyzer/test/generated/static_type_analyzer_test.dart
index ae59f48..3a510f9a 100644
--- a/pkg/analyzer/test/generated/static_type_analyzer_test.dart
+++ b/pkg/analyzer/test/generated/static_type_analyzer_test.dart
@@ -20,7 +20,6 @@
 import 'package:analyzer/src/generated/static_type_analyzer.dart';
 import 'package:analyzer/src/generated/testing/ast_test_factory.dart';
 import 'package:analyzer/src/generated/testing/element_factory.dart';
-import 'package:analyzer/src/generated/testing/test_type_provider.dart';
 import 'package:analyzer/src/generated/testing/token_factory.dart';
 import 'package:analyzer/src/source/source_resource.dart';
 import 'package:test/test.dart';
@@ -191,7 +190,7 @@
   /**
    * The type provider used to access the types.
    */
-  TestTypeProvider _typeProvider;
+  TypeProvider _typeProvider;
 
   /**
    * The type system used to analyze the test cases.
@@ -1551,7 +1550,7 @@
     LibraryElementImpl definingLibrary =
         new LibraryElementImpl.forNode(context, null);
     definingLibrary.definingCompilationUnit = definingCompilationUnit;
-    _typeProvider = new TestTypeProvider(context);
+    _typeProvider = context.typeProvider;
     _visitor = new ResolverVisitor(
         definingLibrary, source, _typeProvider, _listener,
         nameScope: new LibraryScope(definingLibrary));
diff --git a/pkg/analyzer/test/generated/type_system_test.dart b/pkg/analyzer/test/generated/type_system_test.dart
index c555954..0f6ea84 100644
--- a/pkg/analyzer/test/generated/type_system_test.dart
+++ b/pkg/analyzer/test/generated/type_system_test.dart
@@ -65,8 +65,7 @@
 
   void _checkGreatestLowerBound(
       DartType type1, DartType type2, DartType expectedResult) {
-    DartType glb =
-        strongTypeSystem.getGreatestLowerBound(typeProvider, type1, type2);
+    DartType glb = strongTypeSystem.getGreatestLowerBound(type1, type2);
     expect(glb, expectedResult);
     // Check that the result is a lower bound.
     expect(typeSystem.isSubtypeOf(glb, type1), true);
@@ -77,7 +76,7 @@
     // for function types we just check if they are mutual subtypes.
     // https://github.com/dart-lang/sdk/issues/26126
     // TODO(leafp): Fix this.
-    glb = strongTypeSystem.getGreatestLowerBound(typeProvider, type2, type1);
+    glb = strongTypeSystem.getGreatestLowerBound(type2, type1);
     if (glb is FunctionTypeImpl) {
       expect(typeSystem.isSubtypeOf(glb, expectedResult), true);
       expect(typeSystem.isSubtypeOf(expectedResult, glb), true);
@@ -88,7 +87,7 @@
 
   void _checkLeastUpperBound(
       DartType type1, DartType type2, DartType expectedResult) {
-    DartType lub = typeSystem.getLeastUpperBound(typeProvider, type1, type2);
+    DartType lub = typeSystem.getLeastUpperBound(type1, type2);
     expect(lub, expectedResult);
     // Check that the result is an upper bound.
     expect(typeSystem.isSubtypeOf(type1, lub), true);
@@ -100,7 +99,7 @@
     // for function types we just check if they are mutual subtypes.
     // https://github.com/dart-lang/sdk/issues/26126
     // TODO(leafp): Fix this.
-    lub = typeSystem.getLeastUpperBound(typeProvider, type2, type1);
+    lub = typeSystem.getLeastUpperBound(type2, type1);
     if (lub is FunctionTypeImpl) {
       expect(typeSystem.isSubtypeOf(lub, expectedResult), true);
       expect(typeSystem.isSubtypeOf(expectedResult, lub), true);
@@ -138,8 +137,8 @@
 @reflectiveTest
 class LeastUpperBoundTest extends LeastUpperBoundTestBase {
   void setUp() {
-    typeSystem = new TypeSystemImpl();
     super.setUp();
+    typeSystem = new TypeSystemImpl(typeProvider);
   }
 
   void test_functionsLubNamedParams() {
@@ -566,7 +565,7 @@
 
   void setUp() {
     typeProvider = new TestTypeProvider();
-    typeSystem = new StrongTypeSystemImpl();
+    typeSystem = new StrongTypeSystemImpl(typeProvider);
   }
 
   void test_isAssignableTo_bottom_isBottom() {
@@ -865,7 +864,7 @@
 
   void setUp() {
     typeProvider = new TestTypeProvider();
-    typeSystem = new StrongTypeSystemImpl();
+    typeSystem = new StrongTypeSystemImpl(typeProvider);
   }
 
   void test_boundedByAnotherTypeParameter() {
@@ -1125,7 +1124,6 @@
   List<DartType> _inferCall(FunctionTypeImpl ft, List<DartType> arguments,
       [DartType returnType]) {
     FunctionType inferred = typeSystem.inferGenericFunctionCall(
-        typeProvider,
         ft,
         ft.parameters.map((p) => p.type).toList(),
         arguments,
@@ -1141,8 +1139,8 @@
 @reflectiveTest
 class StrongGreatestLowerBoundTest extends BoundTestBase {
   void setUp() {
-    typeSystem = new StrongTypeSystemImpl();
     super.setUp();
+    typeSystem = new StrongTypeSystemImpl(typeProvider);
   }
 
   void test_bottom_function() {
@@ -1402,8 +1400,8 @@
 @reflectiveTest
 class StrongLeastUpperBoundTest extends LeastUpperBoundTestBase {
   void setUp() {
-    typeSystem = new StrongTypeSystemImpl();
     super.setUp();
+    typeSystem = new StrongTypeSystemImpl(typeProvider);
   }
 
   void test_functionsFuzzyArrows() {
@@ -1520,7 +1518,7 @@
 
   void setUp() {
     typeProvider = new TestTypeProvider();
-    typeSystem = new StrongTypeSystemImpl();
+    typeSystem = new StrongTypeSystemImpl(typeProvider);
   }
 
   void test_bottom_isBottom() {
diff --git a/pkg/analyzer/test/src/dart/analysis/driver_test.dart b/pkg/analyzer/test/src/dart/analysis/driver_test.dart
index 24eb692..05b7cb2 100644
--- a/pkg/analyzer/test/src/dart/analysis/driver_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/driver_test.dart
@@ -1122,6 +1122,11 @@
         unorderedEquals(['foo', 'main']));
   }
 
+  test_getUnitElement_notDart() async {
+    CompilationUnitElement unit = await driver.getUnitElement('foo.txt');
+    expect(unit, isNull);
+  }
+
   test_hasFilesToAnalyze() async {
     // No files yet, nothing to analyze.
     expect(driver.hasFilesToAnalyze, isFalse);
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 bb45ad1..99f28e13 100644
--- a/pkg/analyzer/test/src/dart/analysis/file_state_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/file_state_test.dart
@@ -324,6 +324,30 @@
     expect(fileSystemState.getFilesForPath(a1), [file]);
   }
 
+  test_getFileForPath_onlyDartFiles() {
+    String a = _p('/test/lib/a.dart');
+    String b = _p('/test/lib/b.dart');
+    String c = _p('/test/lib/c.dart');
+    String d = _p('/test/lib/d.dart');
+    provider.newFile(
+        a,
+        r'''
+library lib;
+import 'dart:math';
+import 'b.dart';
+import 'not_dart.txt';
+export 'c.dart';
+export 'not_dart.txt';
+part 'd.dart';
+part 'not_dart.txt';
+''');
+    FileState file = fileSystemState.getFileForPath(a);
+    expect(file.importedFiles.map((f) => f.path), [b]);
+    expect(file.exportedFiles.map((f) => f.path), [c]);
+    expect(file.partedFiles.map((f) => f.path), [d]);
+    expect(fileSystemState.knownFilePaths, unorderedEquals([a, b, c, d]));
+  }
+
   test_getFileForPath_part() {
     String a1 = _p('/aaa/lib/a1.dart');
     String a2 = _p('/aaa/lib/a2.dart');
diff --git a/pkg/analyzer/test/src/dart/analysis/search_test.dart b/pkg/analyzer/test/src/dart/analysis/search_test.dart
index cfffe71..6c73bef 100644
--- a/pkg/analyzer/test/src/dart/analysis/search_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/search_test.dart
@@ -465,6 +465,28 @@
     await _verifyReferences(element, expected);
   }
 
+  test_searchReferences_LibraryElement() async {
+    var codeA = 'part of lib; // A';
+    var codeB = 'part of lib; // B';
+    provider.newFile(_p('$testProject/unitA.dart'), codeA);
+    provider.newFile(_p('$testProject/unitB.dart'), codeB);
+    await _resolveTestUnit('''
+library lib;
+part 'unitA.dart';
+part 'unitB.dart';
+''');
+    LibraryElement element = testLibraryElement;
+    CompilationUnitElement unitElementA = element.parts[0];
+    CompilationUnitElement unitElementB = element.parts[1];
+    var expected = [
+      new ExpectedResult(unitElementA, SearchResultKind.REFERENCE,
+          codeA.indexOf('lib; // A'), 'lib'.length),
+      new ExpectedResult(unitElementB, SearchResultKind.REFERENCE,
+          codeB.indexOf('lib; // B'), 'lib'.length),
+    ];
+    await _verifyReferences(element, expected);
+  }
+
   test_searchReferences_LocalVariableElement() async {
     await _resolveTestUnit(r'''
 main() {
diff --git a/pkg/analyzer/test/src/dart/constant/evaluation_test.dart b/pkg/analyzer/test/src/dart/constant/evaluation_test.dart
index 40942d2..665dbb9 100644
--- a/pkg/analyzer/test/src/dart/constant/evaluation_test.dart
+++ b/pkg/analyzer/test/src/dart/constant/evaluation_test.dart
@@ -1581,10 +1581,10 @@
   }
 
   DartObjectImpl _evaluate(Expression expression, ErrorReporter errorReporter) {
+    TestTypeProvider typeProvider = new TestTypeProvider();
     return expression.accept(new ConstantVisitor(
-        new ConstantEvaluationEngine(
-            new TestTypeProvider(), new DeclaredVariables(),
-            typeSystem: new TypeSystemImpl()),
+        new ConstantEvaluationEngine(typeProvider, new DeclaredVariables(),
+            typeSystem: new TypeSystemImpl(typeProvider)),
         errorReporter));
   }
 
diff --git a/pkg/analyzer/test/src/dart/sdk/patch_test.dart b/pkg/analyzer/test/src/dart/sdk/patch_test.dart
index 7e7eeeb..ec02930 100644
--- a/pkg/analyzer/test/src/dart/sdk/patch_test.dart
+++ b/pkg/analyzer/test/src/dart/sdk/patch_test.dart
@@ -162,6 +162,63 @@
     }, throwsArgumentError);
   }
 
+  test_class_constructor_patch_fail_fieldFormalParam_inBase() {
+    expect(() {
+      _doTopLevelPatching(
+          r'''
+class C {
+  int f;
+  external C.named(this.f);
+}
+''',
+          r'''
+@patch
+class C {
+  @patch
+  C.named() : f = 2 {}
+}
+''');
+    }, throwsArgumentError);
+  }
+
+  test_class_constructor_patch_fail_fieldFormalParam_inPatch() {
+    expect(() {
+      _doTopLevelPatching(
+          r'''
+class C {
+  int f;
+  external C.named(int f);
+}
+''',
+          r'''
+@patch
+class C {
+  @patch
+  C.named(this.f) {}
+}
+''');
+    }, throwsArgumentError);
+  }
+
+  test_class_constructor_patch_fail_fieldFormalParam_inPatchAndBase() {
+    expect(() {
+      _doTopLevelPatching(
+          r'''
+class C {
+  int f;
+  external C.named(this.f);
+}
+''',
+          r'''
+@patch
+class C {
+  @patch
+  C.named(this.f) {}
+}
+''');
+    }, throwsArgumentError);
+  }
+
   test_class_constructor_patch_fail_hasInitializers() {
     expect(() {
       _doTopLevelPatching(
@@ -199,6 +256,42 @@
     }, throwsArgumentError);
   }
 
+  test_class_constructor_patch_fail_signatureChange() {
+    expect(() {
+      _doTopLevelPatching(
+          r'''
+class C {
+  external C.named(int x);
+}
+''',
+          r'''
+@patch
+class C {
+  @patch
+  C.named(double x) {}
+}
+''');
+    }, throwsArgumentError);
+  }
+
+  test_class_constructor_patch_fail_signatureChange_nameOnly() {
+    expect(() {
+      _doTopLevelPatching(
+          r'''
+class C {
+  external C.named(int x);
+}
+''',
+          r'''
+@patch
+class C {
+  @patch
+  C.named(int y) {}
+}
+''');
+    }, throwsArgumentError);
+  }
+
   test_class_constructor_patch_initializers() {
     CompilationUnit unit = _doTopLevelPatching(
         r'''
@@ -410,6 +503,254 @@
     }, throwsArgumentError);
   }
 
+  test_class_method_patch_fail_signatureChange() {
+    expect(() {
+      _doTopLevelPatching(
+          r'''
+class C {
+  external void f(int x);
+}
+''',
+          r'''
+@patch
+class C {
+  @patch
+  void f(double x) {}
+}
+''');
+    }, throwsArgumentError);
+  }
+
+  test_class_method_patch_fail_signatureChange_extraArgument() {
+    expect(() {
+      _doTopLevelPatching(
+          r'''
+class C {
+  external void f();
+}
+''',
+          r'''
+@patch
+class C {
+  @patch
+  void f(int x) {}
+}
+''');
+    }, throwsArgumentError);
+  }
+
+  test_class_method_patch_fail_signatureChange_extraTypeTokens() {
+    expect(() {
+      _doTopLevelPatching(
+          r'''
+class C {
+  external List f();
+}
+''',
+          r'''
+@patch
+class C {
+  @patch
+  List<int> f() => null;
+}
+''');
+    }, throwsArgumentError);
+  }
+
+  test_class_method_patch_fail_signatureChange_functionTypedParam_paramType() {
+    expect(() {
+      _doTopLevelPatching(
+          r'''
+class C {
+  external void f(void x(int y));
+}
+''',
+          r'''
+@patch
+class C {
+  @patch
+  void f(void x(double y)) {}
+}
+''');
+    }, throwsArgumentError);
+  }
+
+  test_class_method_patch_fail_signatureChange_functionTypedParam_returnType() {
+    expect(() {
+      _doTopLevelPatching(
+          r'''
+class C {
+  external void f(int x());
+}
+''',
+          r'''
+@patch
+class C {
+  @patch
+  void f(double x()) {}
+}
+''');
+    }, throwsArgumentError);
+  }
+
+  test_class_method_patch_fail_signatureChange_makeReturnTypeExplicit() {
+    expect(() {
+      _doTopLevelPatching(
+          r'''
+class C {
+  external f();
+}
+''',
+          r'''
+@patch
+class C {
+  @patch
+  int f() => 0;
+}
+''');
+    }, throwsArgumentError);
+  }
+
+  test_class_method_patch_fail_signatureChange_missingArgument() {
+    expect(() {
+      _doTopLevelPatching(
+          r'''
+class C {
+  external void f(int x);
+}
+''',
+          r'''
+@patch
+class C {
+  @patch
+  void f() {}
+}
+''');
+    }, throwsArgumentError);
+  }
+
+  test_class_method_patch_fail_signatureChange_missingTypeTokens() {
+    expect(() {
+      _doTopLevelPatching(
+          r'''
+class C {
+  external List<int> f();
+}
+''',
+          r'''
+@patch
+class C {
+  @patch
+  List f() => null;
+}
+''');
+    }, throwsArgumentError);
+  }
+
+  test_class_method_patch_fail_signatureChange_nameOnly() {
+    expect(() {
+      _doTopLevelPatching(
+          r'''
+class C {
+  external void f(int x);
+}
+''',
+          r'''
+@patch
+class C {
+  @patch
+  void f(int y) {}
+}
+''');
+    }, throwsArgumentError);
+  }
+
+  test_class_method_patch_fail_signatureChange_returnTypeOnly() {
+    expect(() {
+      _doTopLevelPatching(
+          r'''
+class C {
+  external void f(int x);
+}
+''',
+          r'''
+@patch
+class C {
+  @patch
+  int f(int x) {}
+}
+''');
+    }, throwsArgumentError);
+  }
+
+  test_class_method_patch_success_defaultFormalParameter() {
+    CompilationUnit unit = _doTopLevelPatching(
+        r'''
+class C {
+  external void f(int x = 0);
+}
+''',
+        r'''
+@patch
+class C {
+  @patch
+  void f(int x) {}
+}
+''');
+    ClassDeclaration cls = unit.declarations[0];
+    MethodDeclaration method = cls.members[0];
+    FormalParameter parameter = method.parameters.parameters[0];
+    expect(parameter, new isInstanceOf<DefaultFormalParameter>());
+  }
+
+  test_class_method_patch_success_implicitReturnType() {
+    _doTopLevelPatching(
+        r'''
+class C {
+  external f();
+}
+''',
+        r'''
+@patch
+class C {
+  @patch
+  f() => null;
+}
+''');
+  }
+
+  test_class_method_patch_success_multiTokenReturnType() {
+    _doTopLevelPatching(
+        r'''
+class C {
+  external List<int> f();
+}
+''',
+        r'''
+@patch
+class C {
+  @patch
+  List<int> f() => null;
+}
+''');
+  }
+
+  test_class_method_patch_success_signatureChange_functionTypedParam_matching() {
+    _doTopLevelPatching(
+        r'''
+class C {
+  external void f(void x(int y));
+}
+''',
+        r'''
+@patch
+class C {
+  @patch
+  void f(void x(int y)) {}
+}
+''');
+  }
+
   test_class_setter_append() {
     CompilationUnit unit = _doTopLevelPatching(
         r'''
@@ -753,6 +1094,45 @@
     _assertUnitCode(unit, 'int foo() {int v = 1; return v + 2;}');
   }
 
+  test_topLevel_patch_function_fail_signatureChange() {
+    expect(() {
+      _doTopLevelPatching(
+          r'''
+external void f(int x);
+''',
+          r'''
+@patch
+void f(double x) {}
+''');
+    }, throwsArgumentError);
+  }
+
+  test_topLevel_patch_function_fail_signatureChange_nameOnly() {
+    expect(() {
+      _doTopLevelPatching(
+          r'''
+external void f(int x);
+''',
+          r'''
+@patch
+void f(int y) {}
+''');
+    }, throwsArgumentError);
+  }
+
+  test_topLevel_patch_function_fail_signatureChange_returnTypeOnly() {
+    expect(() {
+      _doTopLevelPatching(
+          r'''
+external void f(int x);
+''',
+          r'''
+@patch
+int f(int x) {}
+''');
+    }, throwsArgumentError);
+  }
+
   test_topLevel_patch_getter() {
     CompilationUnit unit = _doTopLevelPatching(
         r'''
diff --git a/pkg/analyzer/test/src/summary/resynthesize_ast_test.dart b/pkg/analyzer/test/src/summary/resynthesize_ast_test.dart
index 29e30d3..aa9cde3 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_ast_test.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_ast_test.dart
@@ -832,6 +832,10 @@
   }
 
   UnlinkedUnit _getUnlinkedUnit(Source source) {
+    if (source == null) {
+      return new UnlinkedUnitBuilder();
+    }
+
     String uriStr = source.uri.toString();
     {
       UnlinkedUnit unlinkedUnitInSdk =
@@ -873,7 +877,7 @@
     Source resolveRelativeUri(String relativeUri) {
       Source resolvedSource =
           context.sourceFactory.resolveUri(librarySource, relativeUri);
-      if (resolvedSource == null) {
+      if (resolvedSource == null && !allowMissingFiles) {
         throw new StateError('Could not resolve $relativeUri in the context of '
             '$librarySource (${librarySource.runtimeType})');
       }
diff --git a/pkg/analyzer/test/src/summary/resynthesize_common.dart b/pkg/analyzer/test/src/summary/resynthesize_common.dart
index 65259ba..e5c2b77 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_common.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_common.dart
@@ -1482,6 +1482,14 @@
 class C {}''');
   }
 
+  test_class_documented_tripleSlash() {
+    checkLibrary('''
+/// aaa
+/// bbbb
+/// cc
+class C {}''');
+  }
+
   test_class_documented_with_references() {
     checkLibrary('''
 /**
@@ -4309,6 +4317,12 @@
     checkLibrary('library my.lib; part "a.dart"; part "b.dart";');
   }
 
+  test_parts_invalidUri() {
+    allowMissingFiles = true;
+    addSource('/foo/bar.dart', 'part of my.lib;');
+    checkLibrary('library my.lib; part "foo/";');
+  }
+
   test_propagated_type_refers_to_closure() {
     checkLibrary('''
 void f() {
diff --git a/pkg/analyzer/test/src/summary/summary_common.dart b/pkg/analyzer/test/src/summary/summary_common.dart
index 7f362ae..9d51fd8 100644
--- a/pkg/analyzer/test/src/summary/summary_common.dart
+++ b/pkg/analyzer/test/src/summary/summary_common.dart
@@ -1303,6 +1303,19 @@
     checkDocumentationComment(cls.documentationComment, text);
   }
 
+  test_class_documented_tripleSlash() {
+    if (!includeInformative) return;
+    String text = '''
+/// aaa
+/// bbbb
+/// cc
+class C {}''';
+    UnlinkedClass cls = serializeClassText(text);
+    UnlinkedDocumentationComment comment = cls.documentationComment;
+    expect(comment, isNotNull);
+    expect(comment.text, '/// aaa\n/// bbbb\n/// cc');
+  }
+
   test_class_documented_with_references() {
     if (!includeInformative) return;
     String text = '''
diff --git a/pkg/analyzer/test/src/task/strong/checker_test.dart b/pkg/analyzer/test/src/task/strong/checker_test.dart
index 8ebcd1c..e8f9b0e 100644
--- a/pkg/analyzer/test/src/task/strong/checker_test.dart
+++ b/pkg/analyzer/test/src/task/strong/checker_test.dart
@@ -1301,9 +1301,10 @@
   }
 
   void test_functionTypingAndSubtyping_dynamicFunctions_closuresAreNotFuzzy() {
-    // Regression test for
+    // Regression test for definite function cases
     // https://github.com/dart-lang/sdk/issues/26118
     // https://github.com/dart-lang/sdk/issues/26156
+    // https://github.com/dart-lang/sdk/issues/28087
     checkFile('''
 void takesF(void f(int x)) {}
 
@@ -1313,20 +1314,27 @@
 void updateOpt([_]) {}
 void updateOptNum([num x]) {}
 
+class Callable {
+  void call(_) {}
+}
+
 class A {
   TakesInt f;
   A(TakesInt g) {
     f = update;
     f = updateOpt;
     f = updateOptNum;
+    f = new Callable();
   }
   TakesInt g(bool a, bool b) {
     if (a) {
       return update;
     } else if (b) {
       return updateOpt;
-    } else {
+    } else if (a) {
       return updateOptNum;
+    } else {
+      return new Callable();
     }
   }
 }
@@ -1335,13 +1343,16 @@
   takesF(update);
   takesF(updateOpt);
   takesF(updateOptNum);
+  takesF(new Callable());
   TakesInt f;
   f = update;
   f = updateOpt;
   f = updateOptNum;
+  f = new Callable();
   new A(update);
   new A(updateOpt);
   new A(updateOptNum);
+  new A(new Callable());
 }
 
 void test1() {
diff --git a/pkg/compiler/lib/src/constant_system_dart.dart b/pkg/compiler/lib/src/constant_system_dart.dart
index b0e7ce7..cc12636 100644
--- a/pkg/compiler/lib/src/constant_system_dart.dart
+++ b/pkg/compiler/lib/src/constant_system_dart.dart
@@ -203,6 +203,14 @@
   apply(left, right) => left % right;
 }
 
+class RemainderOperation extends ArithmeticNumOperation {
+  final String name = 'remainder';
+  const RemainderOperation();
+  // Not a defined constant operation.
+  num foldNums(num left, num right) => null;
+  apply(left, right) => left.remainder(right);
+}
+
 class TruncatingDivideOperation extends ArithmeticNumOperation {
   final String name = '~/';
   const TruncatingDivideOperation();
@@ -406,6 +414,7 @@
   final multiply = const MultiplyOperation();
   final negate = const NegateOperation();
   final not = const NotOperation();
+  final remainder = const RemainderOperation();
   final shiftLeft = const ShiftLeftOperation();
   final shiftRight = const ShiftRightOperation();
   final subtract = const SubtractOperation();
diff --git a/pkg/compiler/lib/src/constants/constant_system.dart b/pkg/compiler/lib/src/constants/constant_system.dart
index b8c964e..14d0941 100644
--- a/pkg/compiler/lib/src/constants/constant_system.dart
+++ b/pkg/compiler/lib/src/constants/constant_system.dart
@@ -48,6 +48,7 @@
   BinaryOperation get multiply;
   UnaryOperation get negate;
   UnaryOperation get not;
+  BinaryOperation get remainder;
   BinaryOperation get shiftLeft;
   BinaryOperation get shiftRight;
   BinaryOperation get subtract;
diff --git a/pkg/compiler/lib/src/dump_info.dart b/pkg/compiler/lib/src/dump_info.dart
index 5bda2f3..fcf1293 100644
--- a/pkg/compiler/lib/src/dump_info.dart
+++ b/pkg/compiler/lib/src/dump_info.dart
@@ -262,7 +262,7 @@
     // TODO(sigmund): why all these checks?
     if (element.isInstanceMember &&
         !element.isAbstract &&
-        closedWorld.allFunctions.contains(element)) {
+        closedWorld.allFunctions.contains(element as MemberElement)) {
       returnType = '${element.type.returnType}';
     }
     String inferredReturnType = '${_resultOf(element).returnType}';
diff --git a/pkg/compiler/lib/src/elements/resolution_types.dart b/pkg/compiler/lib/src/elements/resolution_types.dart
index 42012e2..19fd8c8 100644
--- a/pkg/compiler/lib/src/elements/resolution_types.dart
+++ b/pkg/compiler/lib/src/elements/resolution_types.dart
@@ -365,7 +365,7 @@
   }
 }
 
-abstract class GenericType extends ResolutionDartType {
+abstract class GenericType<T extends GenericType> extends ResolutionDartType {
   final TypeDeclarationElement element;
   final List<ResolutionDartType> typeArguments;
 
@@ -391,9 +391,9 @@
   }
 
   /// Creates a new instance of this type using the provided type arguments.
-  GenericType createInstantiation(List<ResolutionDartType> newTypeArguments);
+  T createInstantiation(List<ResolutionDartType> newTypeArguments);
 
-  ResolutionDartType subst(
+  T subst(
       List<ResolutionDartType> arguments, List<ResolutionDartType> parameters) {
     if (typeArguments.isEmpty) {
       // Return fast on non-generic types.
@@ -482,7 +482,8 @@
   }
 }
 
-class ResolutionInterfaceType extends GenericType implements InterfaceType {
+class ResolutionInterfaceType extends GenericType<ResolutionInterfaceType>
+    implements InterfaceType {
   int _hashCode;
 
   ResolutionInterfaceType(ClassElement element,
@@ -843,7 +844,7 @@
 bool _typeContainsMethodTypeVariableType(ResolutionDartType type) =>
     type.containsMethodTypeVariableType;
 
-class ResolutionTypedefType extends GenericType {
+class ResolutionTypedefType extends GenericType<ResolutionTypedefType> {
   ResolutionDartType _unaliased;
 
   ResolutionTypedefType(TypedefElement element,
diff --git a/pkg/compiler/lib/src/elements/types.dart b/pkg/compiler/lib/src/elements/types.dart
index 0e97957..3d564b3 100644
--- a/pkg/compiler/lib/src/elements/types.dart
+++ b/pkg/compiler/lib/src/elements/types.dart
@@ -63,6 +63,7 @@
 
 abstract class InterfaceType extends DartType {
   ClassEntity get element;
+  List<DartType> get typeArguments;
 }
 
 abstract class TypeVariableType extends DartType {
diff --git a/pkg/compiler/lib/src/enqueue.dart b/pkg/compiler/lib/src/enqueue.dart
index 8b89336..db112d0 100644
--- a/pkg/compiler/lib/src/enqueue.dart
+++ b/pkg/compiler/lib/src/enqueue.dart
@@ -14,8 +14,6 @@
 import 'common.dart';
 import 'compiler.dart' show Compiler, GlobalDependencyRegistry;
 import 'options.dart';
-import 'elements/resolution_types.dart'
-    show ResolutionDartType, ResolutionInterfaceType;
 import 'elements/elements.dart'
     show
         AnalyzableElement,
@@ -25,8 +23,9 @@
         Entity,
         MemberElement;
 import 'elements/entities.dart';
+import 'elements/resolution_types.dart'
+    show ResolutionDartType, ResolutionInterfaceType;
 import 'native/native.dart' as native;
-import 'types/types.dart' show TypeMaskStrategy;
 import 'universe/world_builder.dart';
 import 'universe/use.dart'
     show DynamicUse, StaticUse, StaticUseKind, TypeUse, TypeUseKind;
@@ -34,7 +33,6 @@
     show ImpactStrategy, ImpactUseCase, WorldImpact, WorldImpactVisitor;
 import 'util/enumset.dart';
 import 'util/util.dart' show Setlet;
-import 'world.dart' show OpenWorld;
 
 class EnqueueTask extends CompilerTask {
   ResolutionEnqueuer _resolution;
diff --git a/pkg/compiler/lib/src/inferrer/closure_tracer.dart b/pkg/compiler/lib/src/inferrer/closure_tracer.dart
index a757a7b..007d1c4 100644
--- a/pkg/compiler/lib/src/inferrer/closure_tracer.dart
+++ b/pkg/compiler/lib/src/inferrer/closure_tracer.dart
@@ -10,17 +10,21 @@
 import '../types/types.dart' show TypeMask;
 import '../universe/selector.dart' show Selector;
 import 'debug.dart' as debug;
+import 'inferrer_engine.dart';
 import 'node_tracer.dart';
 import 'type_graph_nodes.dart';
 
-class ClosureTracerVisitor extends TracerVisitor<ApplyableTypeInformation> {
+class ClosureTracerVisitor extends TracerVisitor {
   final Iterable<FunctionElement> tracedElements;
   final List<CallSiteTypeInformation> _callsToAnalyze =
       new List<CallSiteTypeInformation>();
 
-  ClosureTracerVisitor(this.tracedElements, tracedType, inferrer)
+  ClosureTracerVisitor(this.tracedElements, ApplyableTypeInformation tracedType,
+      InferrerEngine inferrer)
       : super(tracedType, inferrer);
 
+  ApplyableTypeInformation get tracedType => super.tracedType;
+
   void run() {
     analyze();
     if (!continueAnalyzing) return;
@@ -49,7 +53,10 @@
     Selector selector = info.selector;
     TypeMask mask = info.mask;
     tracedElements.forEach((FunctionElement functionElement) {
-      if (!selector.signatureApplies(functionElement)) return;
+      if (!selector.callStructure
+          .signatureApplies(functionElement.functionSignature)) {
+        return;
+      }
       inferrer.updateParameterAssignments(
           info, functionElement, info.arguments, selector, mask,
           remove: false, addToQueue: false);
diff --git a/pkg/compiler/lib/src/inferrer/inferrer_engine.dart b/pkg/compiler/lib/src/inferrer/inferrer_engine.dart
new file mode 100644
index 0000000..049a86a
--- /dev/null
+++ b/pkg/compiler/lib/src/inferrer/inferrer_engine.dart
@@ -0,0 +1,1051 @@
+// 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 '../common.dart';
+import '../common/names.dart';
+import '../compiler.dart';
+import '../constants/expressions.dart';
+import '../constants/values.dart';
+import '../core_types.dart';
+import '../elements/elements.dart';
+import '../js_backend/js_backend.dart';
+import '../native/behavior.dart' as native;
+import '../resolution/tree_elements.dart';
+import '../tree/nodes.dart' as ast;
+import '../types/constants.dart';
+import '../types/types.dart';
+import '../universe/call_structure.dart';
+import '../universe/selector.dart';
+import '../universe/side_effects.dart';
+import '../util/util.dart';
+import '../world.dart';
+import 'closure_tracer.dart';
+import 'debug.dart' as debug;
+import 'inferrer_visitor.dart';
+import 'list_tracer.dart';
+import 'map_tracer.dart';
+import 'simple_types_inferrer.dart';
+import 'type_graph_dump.dart';
+import 'type_graph_inferrer.dart';
+import 'type_graph_nodes.dart';
+import 'type_system.dart';
+
+/**
+ * An inferencing engine that computes a call graph of
+ * [TypeInformation] nodes by visiting the AST of the application, and
+ * then does the inferencing on the graph.
+ */
+class InferrerEngine {
+  final Map<Element, TypeInformation> defaultTypeOfParameter =
+      new Map<Element, TypeInformation>();
+  final List<CallSiteTypeInformation> allocatedCalls =
+      <CallSiteTypeInformation>[];
+  final WorkQueue workQueue = new WorkQueue();
+  final Element mainElement;
+  final Set<Element> analyzedElements = new Set<Element>();
+
+  /// The maximum number of times we allow a node in the graph to
+  /// change types. If a node reaches that limit, we give up
+  /// inferencing on it and give it the dynamic type.
+  final int MAX_CHANGE_COUNT = 6;
+
+  int overallRefineCount = 0;
+  int addedInGraph = 0;
+
+  final Compiler compiler;
+
+  /// The [ClosedWorld] on which inference reasoning is based.
+  final ClosedWorld closedWorld;
+
+  final ClosedWorldRefiner closedWorldRefiner;
+  final TypeSystem types;
+  final Map<ast.Node, TypeInformation> concreteTypes =
+      new Map<ast.Node, TypeInformation>();
+  final Set<Element> generativeConstructorsExposingThis = new Set<Element>();
+
+  /// Data computed internally within elements, like the type-mask of a send a
+  /// list allocation, or a for-in loop.
+  final Map<Element, GlobalTypeInferenceElementData> inTreeData =
+      new Map<Element, GlobalTypeInferenceElementData>();
+
+  InferrerEngine(this.compiler, ClosedWorld closedWorld,
+      this.closedWorldRefiner, this.mainElement)
+      : this.types = new TypeSystem(closedWorld),
+        this.closedWorld = closedWorld;
+
+  CommonElements get commonElements => closedWorld.commonElements;
+
+  /**
+   * Applies [f] to all elements in the universe that match
+   * [selector] and [mask]. If [f] returns false, aborts the iteration.
+   */
+  void forEachElementMatching(
+      Selector selector, TypeMask mask, bool f(Element element)) {
+    Iterable<Element> elements =
+        closedWorld.allFunctions.filter(selector, mask);
+    for (Element e in elements) {
+      if (!f(e.implementation)) return;
+    }
+  }
+
+  // TODO(johnniwinther): Make this private again.
+  GlobalTypeInferenceElementData dataOf(AstElement element) => inTreeData
+      .putIfAbsent(element, () => new GlobalTypeInferenceElementData());
+
+  /**
+   * Update [sideEffects] with the side effects of [callee] being
+   * called with [selector].
+   */
+  void updateSideEffects(
+      SideEffects sideEffects, Selector selector, Element callee) {
+    if (callee.isField) {
+      if (callee.isInstanceMember) {
+        if (selector.isSetter) {
+          sideEffects.setChangesInstanceProperty();
+        } else if (selector.isGetter) {
+          sideEffects.setDependsOnInstancePropertyStore();
+        } else {
+          sideEffects.setAllSideEffects();
+          sideEffects.setDependsOnSomething();
+        }
+      } else {
+        if (selector.isSetter) {
+          sideEffects.setChangesStaticProperty();
+        } else if (selector.isGetter) {
+          sideEffects.setDependsOnStaticPropertyStore();
+        } else {
+          sideEffects.setAllSideEffects();
+          sideEffects.setDependsOnSomething();
+        }
+      }
+    } else if (callee.isGetter && !selector.isGetter) {
+      sideEffects.setAllSideEffects();
+      sideEffects.setDependsOnSomething();
+    } else {
+      sideEffects.add(closedWorldRefiner.getCurrentlyKnownSideEffects(callee));
+    }
+  }
+
+  /**
+   * Returns the type for [nativeBehavior]. See documentation on
+   * [native.NativeBehavior].
+   */
+  TypeInformation typeOfNativeBehavior(native.NativeBehavior nativeBehavior) {
+    if (nativeBehavior == null) return types.dynamicType;
+    List typesReturned = nativeBehavior.typesReturned;
+    if (typesReturned.isEmpty) return types.dynamicType;
+    TypeInformation returnType;
+    for (var type in typesReturned) {
+      TypeInformation mappedType;
+      if (type == native.SpecialType.JsObject) {
+        mappedType = types.nonNullExact(commonElements.objectClass);
+      } else if (type == commonElements.stringType) {
+        mappedType = types.stringType;
+      } else if (type == commonElements.intType) {
+        mappedType = types.intType;
+      } else if (type == commonElements.numType ||
+          type == commonElements.doubleType) {
+        // Note: the backend double class is specifically for non-integer
+        // doubles, and a native behavior returning 'double' does not guarantee
+        // a non-integer return type, so we return the number type for those.
+        mappedType = types.numType;
+      } else if (type == commonElements.boolType) {
+        mappedType = types.boolType;
+      } else if (type == commonElements.nullType) {
+        mappedType = types.nullType;
+      } else if (type.isVoid) {
+        mappedType = types.nullType;
+      } else if (type.isDynamic) {
+        return types.dynamicType;
+      } else {
+        mappedType = types.nonNullSubtype(type.element);
+      }
+      returnType = types.computeLUB(returnType, mappedType);
+      if (returnType == types.dynamicType) {
+        break;
+      }
+    }
+    return returnType;
+  }
+
+  // TODO(johnniwinther): Pass the [ResolvedAst] instead of [owner].
+  void updateSelectorInTree(
+      AstElement owner, Spannable node, Selector selector, TypeMask mask) {
+    ast.Node astNode = node;
+    GlobalTypeInferenceElementData data = dataOf(owner);
+    if (astNode.asSendSet() != null) {
+      if (selector.isSetter || selector.isIndexSet) {
+        data.setTypeMask(node, mask);
+      } else if (selector.isGetter || selector.isIndex) {
+        data.setGetterTypeMaskInComplexSendSet(node, mask);
+      } else {
+        assert(selector.isOperator);
+        data.setOperatorTypeMaskInComplexSendSet(node, mask);
+      }
+    } else if (astNode.asSend() != null) {
+      data.setTypeMask(node, mask);
+    } else {
+      assert(astNode.asForIn() != null);
+      if (selector == Selectors.iterator) {
+        data.setIteratorTypeMask(node, mask);
+      } else if (selector == Selectors.current) {
+        data.setCurrentTypeMask(node, mask);
+      } else {
+        assert(selector == Selectors.moveNext);
+        data.setMoveNextTypeMask(node, mask);
+      }
+    }
+  }
+
+  bool isNativeElement(Element element) {
+    return compiler.backend.isNative(element);
+  }
+
+  bool checkIfExposesThis(Element element) {
+    element = element.implementation;
+    return generativeConstructorsExposingThis.contains(element);
+  }
+
+  void recordExposesThis(Element element, bool exposesThis) {
+    element = element.implementation;
+    if (exposesThis) {
+      generativeConstructorsExposingThis.add(element);
+    }
+  }
+
+  JavaScriptBackend get backend => compiler.backend;
+  Annotations get annotations => backend.annotations;
+  DiagnosticReporter get reporter => compiler.reporter;
+  CommonMasks get commonMasks => closedWorld.commonMasks;
+
+  /**
+   * A set of selector names that [List] implements, that we know return
+   * their element type.
+   */
+  final Set<Selector> returnsListElementTypeSet =
+      new Set<Selector>.from(<Selector>[
+    new Selector.getter(const PublicName('first')),
+    new Selector.getter(const PublicName('last')),
+    new Selector.getter(const PublicName('single')),
+    new Selector.call(const PublicName('singleWhere'), CallStructure.ONE_ARG),
+    new Selector.call(const PublicName('elementAt'), CallStructure.ONE_ARG),
+    new Selector.index(),
+    new Selector.call(const PublicName('removeAt'), CallStructure.ONE_ARG),
+    new Selector.call(const PublicName('removeLast'), CallStructure.NO_ARGS)
+  ]);
+
+  bool returnsListElementType(Selector selector, TypeMask mask) {
+    return mask != null &&
+        mask.isContainer &&
+        returnsListElementTypeSet.contains(selector);
+  }
+
+  bool returnsMapValueType(Selector selector, TypeMask mask) {
+    return mask != null && mask.isMap && selector.isIndex;
+  }
+
+  void analyzeListAndEnqueue(ListTypeInformation info) {
+    if (info.analyzed) return;
+    info.analyzed = true;
+
+    ListTracerVisitor tracer = new ListTracerVisitor(info, this);
+    bool succeeded = tracer.run();
+    if (!succeeded) return;
+
+    info.bailedOut = false;
+    info.elementType.inferred = true;
+    TypeMask fixedListType = commonMasks.fixedListType;
+    if (info.originalType.forwardTo == fixedListType) {
+      info.checksGrowable = tracer.callsGrowableMethod;
+    }
+    tracer.assignments.forEach(info.elementType.addAssignment);
+    // Enqueue the list for later refinement
+    workQueue.add(info);
+    workQueue.add(info.elementType);
+  }
+
+  void analyzeMapAndEnqueue(MapTypeInformation info) {
+    if (info.analyzed) return;
+    info.analyzed = true;
+    MapTracerVisitor tracer = new MapTracerVisitor(info, this);
+
+    bool succeeded = tracer.run();
+    if (!succeeded) return;
+
+    info.bailedOut = false;
+    for (int i = 0; i < tracer.keyAssignments.length; ++i) {
+      TypeInformation newType = info.addEntryAssignment(
+          tracer.keyAssignments[i], tracer.valueAssignments[i]);
+      if (newType != null) workQueue.add(newType);
+    }
+    for (TypeInformation map in tracer.mapAssignments) {
+      workQueue.addAll(info.addMapAssignment(map));
+    }
+
+    info.markAsInferred();
+    workQueue.add(info.keyType);
+    workQueue.add(info.valueType);
+    workQueue.addAll(info.typeInfoMap.values);
+    workQueue.add(info);
+  }
+
+  void runOverAllElements() {
+    if (compiler.disableTypeInference) return;
+    if (compiler.options.verbose) {
+      compiler.progress.reset();
+    }
+    sortResolvedAsts().forEach((ResolvedAst resolvedAst) {
+      if (compiler.shouldPrintProgress) {
+        reporter.log('Added $addedInGraph elements in inferencing graph.');
+        compiler.progress.reset();
+      }
+      // This also forces the creation of the [ElementTypeInformation] to ensure
+      // it is in the graph.
+      types.withMember(
+          resolvedAst.element.implementation, () => analyze(resolvedAst, null));
+    });
+    reporter.log('Added $addedInGraph elements in inferencing graph.');
+
+    TypeGraphDump dump = debug.PRINT_GRAPH ? new TypeGraphDump(this) : null;
+
+    dump?.beforeAnalysis();
+    buildWorkQueue();
+    refine();
+
+    // Try to infer element types of lists and compute their escape information.
+    types.allocatedLists.values.forEach((ListTypeInformation info) {
+      analyzeListAndEnqueue(info);
+    });
+
+    // Try to infer the key and value types for maps and compute the values'
+    // escape information.
+    types.allocatedMaps.values.forEach((MapTypeInformation info) {
+      analyzeMapAndEnqueue(info);
+    });
+
+    Set<FunctionElement> bailedOutOn = new Set<FunctionElement>();
+
+    // Trace closures to potentially infer argument types.
+    types.allocatedClosures.forEach((info) {
+      void trace(
+          Iterable<FunctionElement> elements, ClosureTracerVisitor tracer) {
+        tracer.run();
+        if (!tracer.continueAnalyzing) {
+          elements.forEach((FunctionElement e) {
+            closedWorldRefiner.registerMightBePassedToApply(e);
+            if (debug.VERBOSE) print("traced closure $e as ${true} (bail)");
+            e.functionSignature.forEachParameter((parameter) {
+              types
+                  .getInferredTypeOf(parameter)
+                  .giveUp(this, clearAssignments: false);
+            });
+          });
+          bailedOutOn.addAll(elements);
+          return;
+        }
+        elements
+            .where((e) => !bailedOutOn.contains(e))
+            .forEach((FunctionElement e) {
+          e.functionSignature.forEachParameter((parameter) {
+            var info = types.getInferredTypeOf(parameter);
+            info.maybeResume();
+            workQueue.add(info);
+          });
+          if (tracer.tracedType.mightBePassedToFunctionApply) {
+            closedWorldRefiner.registerMightBePassedToApply(e);
+          }
+          if (debug.VERBOSE) {
+            print("traced closure $e as "
+                "${closedWorldRefiner
+                .getCurrentlyKnownMightBePassedToApply(e)}");
+          }
+        });
+      }
+
+      if (info is ClosureTypeInformation) {
+        Iterable<FunctionElement> elements = [info.element];
+        trace(elements, new ClosureTracerVisitor(elements, info, this));
+      } else if (info is CallSiteTypeInformation) {
+        if (info is StaticCallSiteTypeInformation &&
+            info.selector != null &&
+            info.selector.isCall) {
+          // This is a constructor call to a class with a call method. So we
+          // need to trace the call method here.
+          assert(info.calledElement.isConstructor);
+          ClassElement cls = info.calledElement.enclosingClass;
+          FunctionElement callMethod = cls.lookupMember(Identifiers.call);
+          assert(invariant(cls, callMethod != null));
+          Iterable<FunctionElement> elements = [callMethod];
+          trace(elements, new ClosureTracerVisitor(elements, info, this));
+        } else {
+          // We only are interested in functions here, as other targets
+          // of this closure call are not a root to trace but an intermediate
+          // for some other function.
+          Iterable<FunctionElement> elements = new List<FunctionElement>.from(
+              info.callees.where((e) => e.isFunction));
+          trace(elements, new ClosureTracerVisitor(elements, info, this));
+        }
+      } else {
+        assert(info is ElementTypeInformation);
+        trace([info.element],
+            new StaticTearOffClosureTracerVisitor(info.element, info, this));
+      }
+    });
+
+    dump?.beforeTracing();
+
+    // Reset all nodes that use lists/maps that have been inferred, as well
+    // as nodes that use elements fetched from these lists/maps. The
+    // workset for a new run of the analysis will be these nodes.
+    Set<TypeInformation> seenTypes = new Set<TypeInformation>();
+    while (!workQueue.isEmpty) {
+      TypeInformation info = workQueue.remove();
+      if (seenTypes.contains(info)) continue;
+      // If the node cannot be reset, we do not need to update its users either.
+      if (!info.reset(this)) continue;
+      seenTypes.add(info);
+      workQueue.addAll(info.users);
+    }
+
+    workQueue.addAll(seenTypes);
+    refine();
+
+    if (debug.PRINT_SUMMARY) {
+      types.allocatedLists.values.forEach((ListTypeInformation info) {
+        print('${info.type} '
+            'for ${info.originalType.allocationNode} '
+            'at ${info.originalType.allocationElement} '
+            'after ${info.refineCount}');
+      });
+      types.allocatedMaps.values.forEach((MapTypeInformation info) {
+        print('${info.type} '
+            'for ${info.originalType.allocationNode} '
+            'at ${info.originalType.allocationElement} '
+            'after ${info.refineCount}');
+      });
+      types.allocatedClosures.forEach((TypeInformation info) {
+        if (info is ElementTypeInformation) {
+          print('${types.getInferredSignatureOf(info.element)} for '
+              '${info.element}');
+        } else if (info is ClosureTypeInformation) {
+          print('${types.getInferredSignatureOf(info.element)} for '
+              '${info.element}');
+        } else if (info is DynamicCallSiteTypeInformation) {
+          for (Element target in info.targets) {
+            if (target is FunctionElement) {
+              print('${types.getInferredSignatureOf(target)} for ${target}');
+            } else {
+              print('${types.getInferredTypeOf(target).type} for ${target}');
+            }
+          }
+        } else if (info is StaticCallSiteTypeInformation) {
+          ClassElement cls = info.calledElement.enclosingClass;
+          FunctionElement callMethod = cls.lookupMember(Identifiers.call);
+          print('${types.getInferredSignatureOf(callMethod)} for ${cls}');
+        } else {
+          print('${info.type} for some unknown kind of closure');
+        }
+      });
+      analyzedElements.forEach((Element elem) {
+        TypeInformation type = types.getInferredTypeOf(elem);
+        print('${elem} :: ${type} from ${type.assignments} ');
+      });
+    }
+    dump?.afterAnalysis();
+
+    reporter.log('Inferred $overallRefineCount types.');
+
+    processLoopInformation();
+  }
+
+  void analyze(ResolvedAst resolvedAst, ArgumentsTypes arguments) {
+    AstElement element = resolvedAst.element.implementation;
+    if (analyzedElements.contains(element)) return;
+    analyzedElements.add(element);
+
+    SimpleTypeInferrerVisitor visitor =
+        new SimpleTypeInferrerVisitor(element, resolvedAst, compiler, this);
+    TypeInformation type;
+    reporter.withCurrentElement(element, () {
+      type = visitor.run();
+    });
+    addedInGraph++;
+
+    if (element.isField) {
+      VariableElement fieldElement = element;
+      ast.Node node = resolvedAst.node;
+      ast.Node initializer = resolvedAst.body;
+      if (element.isFinal || element.isConst) {
+        // If [element] is final and has an initializer, we record
+        // the inferred type.
+        if (resolvedAst.body != null) {
+          if (type is! ListTypeInformation && type is! MapTypeInformation) {
+            // For non-container types, the constant handler does
+            // constant folding that could give more precise results.
+            ConstantExpression constant = fieldElement.constant;
+            if (constant != null) {
+              ConstantValue value =
+                  compiler.backend.constants.getConstantValue(constant);
+              if (value != null) {
+                if (value.isFunction) {
+                  FunctionConstantValue functionConstant = value;
+                  MethodElement function = functionConstant.element;
+                  type = types.allocateClosure(node, function);
+                } else {
+                  // Although we might find a better type, we have to keep
+                  // the old type around to ensure that we get a complete view
+                  // of the type graph and do not drop any flow edges.
+                  TypeMask refinedType = computeTypeMask(closedWorld, value);
+                  assert(TypeMask.assertIsNormalized(refinedType, closedWorld));
+                  type = new NarrowTypeInformation(type, refinedType);
+                  types.allocatedTypes.add(type);
+                }
+              } else {
+                assert(invariant(
+                    fieldElement,
+                    fieldElement.isInstanceMember ||
+                        constant.isImplicit ||
+                        constant.isPotential,
+                    message: "Constant expression without value: "
+                        "${constant.toStructuredText()}."));
+              }
+            }
+          }
+          recordType(element, type);
+        } else if (!element.isInstanceMember) {
+          recordType(element, types.nullType);
+        }
+      } else if (initializer == null) {
+        // Only update types of static fields if there is no
+        // assignment. Instance fields are dealt with in the constructor.
+        if (Elements.isStaticOrTopLevelField(element)) {
+          recordTypeOfNonFinalField(node, element, type);
+        }
+      } else {
+        recordTypeOfNonFinalField(node, element, type);
+      }
+      if (Elements.isStaticOrTopLevelField(element) &&
+          resolvedAst.body != null &&
+          !element.isConst) {
+        var argument = resolvedAst.body;
+        // TODO(13429): We could do better here by using the
+        // constant handler to figure out if it's a lazy field or not.
+        if (argument.asSend() != null ||
+            (argument.asNewExpression() != null && !argument.isConst)) {
+          recordType(element, types.nullType);
+        }
+      }
+    } else {
+      recordReturnType(element, type);
+    }
+  }
+
+  void processLoopInformation() {
+    allocatedCalls.forEach((info) {
+      if (!info.inLoop) return;
+      if (info is StaticCallSiteTypeInformation) {
+        closedWorldRefiner.addFunctionCalledInLoop(info.calledElement);
+      } else if (info.mask != null && !info.mask.containsAll(closedWorld)) {
+        // For instance methods, we only register a selector called in a
+        // loop if it is a typed selector, to avoid marking too many
+        // methods as being called from within a loop. This cuts down
+        // on the code bloat.
+        info.targets.forEach(closedWorldRefiner.addFunctionCalledInLoop);
+      }
+    });
+  }
+
+  void refine() {
+    while (!workQueue.isEmpty) {
+      if (compiler.shouldPrintProgress) {
+        reporter.log('Inferred $overallRefineCount types.');
+        compiler.progress.reset();
+      }
+      TypeInformation info = workQueue.remove();
+      TypeMask oldType = info.type;
+      TypeMask newType = info.refine(this);
+      // Check that refinement has not accidentially changed the type.
+      assert(oldType == info.type);
+      if (info.abandonInferencing) info.doNotEnqueue = true;
+      if ((info.type = newType) != oldType) {
+        overallRefineCount++;
+        info.refineCount++;
+        if (info.refineCount > MAX_CHANGE_COUNT) {
+          if (debug.ANOMALY_WARN) {
+            print("ANOMALY WARNING: max refinement reached for $info");
+          }
+          info.giveUp(this);
+          info.type = info.refine(this);
+          info.doNotEnqueue = true;
+        }
+        workQueue.addAll(info.users);
+        if (info.hasStableType(this)) {
+          info.stabilize(this);
+        }
+      }
+    }
+  }
+
+  void buildWorkQueue() {
+    workQueue.addAll(types.typeInformations.values);
+    workQueue.addAll(types.allocatedTypes);
+    workQueue.addAll(types.allocatedClosures);
+    workQueue.addAll(allocatedCalls);
+  }
+
+  /**
+   * Update the assignments to parameters in the graph. [remove] tells
+   * wheter assignments must be added or removed. If [init] is false,
+   * parameters are added to the work queue.
+   */
+  void updateParameterAssignments(TypeInformation caller, Element callee,
+      ArgumentsTypes arguments, Selector selector, TypeMask mask,
+      {bool remove, bool addToQueue: true}) {
+    if (callee.name == Identifiers.noSuchMethod_) return;
+    if (callee.isField) {
+      if (selector.isSetter) {
+        ElementTypeInformation info = types.getInferredTypeOf(callee);
+        if (remove) {
+          info.removeAssignment(arguments.positional[0]);
+        } else {
+          info.addAssignment(arguments.positional[0]);
+        }
+        if (addToQueue) workQueue.add(info);
+      }
+    } else if (callee.isGetter) {
+      return;
+    } else if (selector != null && selector.isGetter) {
+      // We are tearing a function off and thus create a closure.
+      assert(callee.isFunction);
+      MemberTypeInformation info = types.getInferredTypeOf(callee);
+      if (remove) {
+        info.closurizedCount--;
+      } else {
+        info.closurizedCount++;
+        if (Elements.isStaticOrTopLevel(callee)) {
+          types.allocatedClosures.add(info);
+        } else {
+          // We add the call-site type information here so that we
+          // can benefit from further refinement of the selector.
+          types.allocatedClosures.add(caller);
+        }
+        FunctionElement function = callee.implementation;
+        FunctionSignature signature = function.functionSignature;
+        signature.forEachParameter((Element parameter) {
+          ParameterTypeInformation info = types.getInferredTypeOf(parameter);
+          info.tagAsTearOffClosureParameter(this);
+          if (addToQueue) workQueue.add(info);
+        });
+      }
+    } else {
+      FunctionElement function = callee.implementation;
+      FunctionSignature signature = function.functionSignature;
+      int parameterIndex = 0;
+      bool visitingRequiredParameter = true;
+      signature.forEachParameter((Element parameter) {
+        if (signature.hasOptionalParameters &&
+            parameter == signature.optionalParameters.first) {
+          visitingRequiredParameter = false;
+        }
+        TypeInformation type = visitingRequiredParameter
+            ? arguments.positional[parameterIndex]
+            : signature.optionalParametersAreNamed
+                ? arguments.named[parameter.name]
+                : parameterIndex < arguments.positional.length
+                    ? arguments.positional[parameterIndex]
+                    : null;
+        if (type == null) type = getDefaultTypeOfParameter(parameter);
+        TypeInformation info = types.getInferredTypeOf(parameter);
+        if (remove) {
+          info.removeAssignment(type);
+        } else {
+          info.addAssignment(type);
+        }
+        parameterIndex++;
+        if (addToQueue) workQueue.add(info);
+      });
+    }
+  }
+
+  /**
+   * Sets the type of a parameter's default value to [type]. If the global
+   * mapping in [defaultTypeOfParameter] already contains a type, it must be
+   * a [PlaceholderTypeInformation], which will be replaced. All its uses are
+   * updated.
+   */
+  void setDefaultTypeOfParameter(
+      ParameterElement parameter, TypeInformation type) {
+    assert(parameter.functionDeclaration.isImplementation);
+    TypeInformation existing = defaultTypeOfParameter[parameter];
+    defaultTypeOfParameter[parameter] = type;
+    TypeInformation info = types.getInferredTypeOf(parameter);
+    if (existing != null && existing is PlaceholderTypeInformation) {
+      // Replace references to [existing] to use [type] instead.
+      if (parameter.functionDeclaration.isInstanceMember) {
+        ParameterAssignments assignments = info.assignments;
+        assignments.replace(existing, type);
+      } else {
+        List<TypeInformation> assignments = info.assignments;
+        for (int i = 0; i < assignments.length; i++) {
+          if (assignments[i] == existing) {
+            assignments[i] = type;
+          }
+        }
+      }
+      // Also forward all users.
+      type.addUsersOf(existing);
+    } else {
+      assert(existing == null);
+    }
+  }
+
+  /**
+   * Returns the [TypeInformation] node for the default value of a parameter.
+   * If this is queried before it is set by [setDefaultTypeOfParameter], a
+   * [PlaceholderTypeInformation] is returned, which will later be replaced
+   * by the actual node when [setDefaultTypeOfParameter] is called.
+   *
+   * Invariant: After graph construction, no [PlaceholderTypeInformation] nodes
+   *            should be present and a default type for each parameter should
+   *            exist.
+   */
+  TypeInformation getDefaultTypeOfParameter(Element parameter) {
+    return defaultTypeOfParameter.putIfAbsent(parameter, () {
+      return new PlaceholderTypeInformation(types.currentMember);
+    });
+  }
+
+  /**
+   * This helper breaks abstractions but is currently required to work around
+   * the wrong modeling of default values of optional parameters of
+   * synthetic constructors.
+   *
+   * TODO(johnniwinther): Remove once default values of synthetic parameters
+   * are fixed.
+   */
+  bool hasAlreadyComputedTypeOfParameterDefault(Element parameter) {
+    TypeInformation seen = defaultTypeOfParameter[parameter];
+    return (seen != null && seen is! PlaceholderTypeInformation);
+  }
+
+  /**
+   * Returns the type of [element].
+   */
+  TypeInformation typeOfElement(Element element) {
+    if (element is FunctionElement) return types.functionType;
+    return types.getInferredTypeOf(element);
+  }
+
+  /**
+   * Returns the return type of [element].
+   */
+  TypeInformation returnTypeOfElement(Element element) {
+    if (element is! FunctionElement) return types.dynamicType;
+    return types.getInferredTypeOf(element);
+  }
+
+  /**
+   * Records that [node] sets final field [element] to be of type [type].
+   *
+   * [nodeHolder] is the element holder of [node].
+   */
+  void recordTypeOfFinalField(
+      Spannable node, Element analyzed, Element element, TypeInformation type) {
+    types.getInferredTypeOf(element).addAssignment(type);
+  }
+
+  /**
+   * Records that [node] sets non-final field [element] to be of type
+   * [type].
+   */
+  void recordTypeOfNonFinalField(
+      Spannable node, Element element, TypeInformation type) {
+    types.getInferredTypeOf(element).addAssignment(type);
+  }
+
+  /**
+   * Records that [element] is of type [type].
+   */
+  void recordType(Element element, TypeInformation type) {
+    types.getInferredTypeOf(element).addAssignment(type);
+  }
+
+  /**
+   * Records that the return type [element] is of type [type].
+   */
+  void recordReturnType(Element element, TypeInformation type) {
+    TypeInformation info = types.getInferredTypeOf(element);
+    if (element.name == '==') {
+      // Even if x.== doesn't return a bool, 'x == null' evaluates to 'false'.
+      info.addAssignment(types.boolType);
+    }
+    // TODO(ngeoffray): Clean up. We do these checks because
+    // [SimpleTypesInferrer] deals with two different inferrers.
+    if (type == null) return;
+    if (info.assignments.isEmpty) info.addAssignment(type);
+  }
+
+  /**
+   * Notifies to the inferrer that [analyzedElement] can have return
+   * type [newType]. [currentType] is the type the [InferrerVisitor]
+   * currently found.
+   *
+   * Returns the new type for [analyzedElement].
+   */
+  TypeInformation addReturnTypeFor(
+      Element element, TypeInformation unused, TypeInformation newType) {
+    TypeInformation type = types.getInferredTypeOf(element);
+    // TODO(ngeoffray): Clean up. We do this check because
+    // [SimpleTypesInferrer] deals with two different inferrers.
+    if (element.isGenerativeConstructor) return type;
+    type.addAssignment(newType);
+    return type;
+  }
+
+  /**
+   * Registers that [caller] calls [callee] at location [node], with
+   * [selector], and [arguments]. Note that [selector] is null for
+   * forwarding constructors.
+   *
+   * [sideEffects] will be updated to incorporate [callee]'s side
+   * effects.
+   *
+   * [inLoop] tells whether the call happens in a loop.
+   */
+  TypeInformation registerCalledElement(
+      Spannable node,
+      Selector selector,
+      TypeMask mask,
+      Element caller,
+      Element callee,
+      ArgumentsTypes arguments,
+      SideEffects sideEffects,
+      bool inLoop) {
+    CallSiteTypeInformation info = new StaticCallSiteTypeInformation(
+        types.currentMember,
+        node,
+        caller,
+        callee,
+        selector,
+        mask,
+        arguments,
+        inLoop);
+    // If this class has a 'call' method then we have essentially created a
+    // closure here. Register it as such so that it is traced.
+    if (selector != null && selector.isCall && callee.isConstructor) {
+      ClassElement cls = callee.enclosingClass.declaration;
+      if (cls.callType != null) {
+        types.allocatedClosures.add(info);
+      }
+    }
+    info.addToGraph(this);
+    allocatedCalls.add(info);
+    updateSideEffects(sideEffects, selector, callee);
+    return info;
+  }
+
+  /**
+   * Registers that [caller] calls [selector] with [receiverType] as
+   * receiver, and [arguments].
+   *
+   * [sideEffects] will be updated to incorporate the potential
+   * callees' side effects.
+   *
+   * [inLoop] tells whether the call happens in a loop.
+   */
+  TypeInformation registerCalledSelector(
+      ast.Node node,
+      Selector selector,
+      TypeMask mask,
+      TypeInformation receiverType,
+      Element caller,
+      ArgumentsTypes arguments,
+      SideEffects sideEffects,
+      bool inLoop) {
+    if (selector.isClosureCall) {
+      return registerCalledClosure(node, selector, mask, receiverType, caller,
+          arguments, sideEffects, inLoop);
+    }
+
+    closedWorld.allFunctions.filter(selector, mask).forEach((callee) {
+      updateSideEffects(sideEffects, selector, callee);
+    });
+
+    CallSiteTypeInformation info = new DynamicCallSiteTypeInformation(
+        types.currentMember,
+        node,
+        caller,
+        selector,
+        mask,
+        receiverType,
+        arguments,
+        inLoop);
+
+    info.addToGraph(this);
+    allocatedCalls.add(info);
+    return info;
+  }
+
+  /**
+   * Registers a call to await with an expression of type [argumentType] as
+   * argument.
+   */
+  TypeInformation registerAwait(ast.Node node, TypeInformation argument) {
+    AwaitTypeInformation info =
+        new AwaitTypeInformation(types.currentMember, node);
+    info.addAssignment(argument);
+    types.allocatedTypes.add(info);
+    return info;
+  }
+
+  /**
+   * Registers that [caller] calls [closure] with [arguments].
+   *
+   * [sideEffects] will be updated to incorporate the potential
+   * callees' side effects.
+   *
+   * [inLoop] tells whether the call happens in a loop.
+   */
+  TypeInformation registerCalledClosure(
+      ast.Node node,
+      Selector selector,
+      TypeMask mask,
+      TypeInformation closure,
+      Element caller,
+      ArgumentsTypes arguments,
+      SideEffects sideEffects,
+      bool inLoop) {
+    sideEffects.setDependsOnSomething();
+    sideEffects.setAllSideEffects();
+    CallSiteTypeInformation info = new ClosureCallSiteTypeInformation(
+        types.currentMember,
+        node,
+        caller,
+        selector,
+        mask,
+        closure,
+        arguments,
+        inLoop);
+    info.addToGraph(this);
+    allocatedCalls.add(info);
+    return info;
+  }
+
+  // Sorts the resolved elements by size. We do this for this inferrer
+  // to get the same results for [ListTracer] compared to the
+  // [SimpleTypesInferrer].
+  Iterable<ResolvedAst> sortResolvedAsts() {
+    int max = 0;
+    Map<int, Setlet<ResolvedAst>> methodSizes = <int, Setlet<ResolvedAst>>{};
+    compiler.enqueuer.resolution.processedEntities
+        .forEach((AstElement element) {
+      ResolvedAst resolvedAst = element.resolvedAst;
+      element = element.implementation;
+      if (element.impliesType) return;
+      assert(invariant(
+          element,
+          element.isField ||
+              element.isFunction ||
+              element.isConstructor ||
+              element.isGetter ||
+              element.isSetter,
+          message: 'Unexpected element kind: ${element.kind}'));
+      if (element.isAbstract) return;
+      // Put the other operators in buckets by length, later to be added in
+      // length order.
+      int length = 0;
+      if (resolvedAst.kind == ResolvedAstKind.PARSED) {
+        TreeElementMapping mapping = resolvedAst.elements;
+        length = mapping.getSelectorCount();
+      }
+      max = length > max ? length : max;
+      Setlet<ResolvedAst> set =
+          methodSizes.putIfAbsent(length, () => new Setlet<ResolvedAst>());
+      set.add(resolvedAst);
+    });
+
+    List<ResolvedAst> result = <ResolvedAst>[];
+    for (int i = 0; i <= max; i++) {
+      Setlet<ResolvedAst> set = methodSizes[i];
+      if (set != null) result.addAll(set);
+    }
+    return result;
+  }
+
+  void clear() {
+    void cleanup(TypeInformation info) => info.cleanup();
+
+    allocatedCalls.forEach(cleanup);
+    allocatedCalls.clear();
+
+    defaultTypeOfParameter.clear();
+
+    types.typeInformations.values.forEach(cleanup);
+
+    types.allocatedTypes.forEach(cleanup);
+    types.allocatedTypes.clear();
+
+    types.concreteTypes.clear();
+
+    types.allocatedClosures.forEach(cleanup);
+    types.allocatedClosures.clear();
+
+    analyzedElements.clear();
+    generativeConstructorsExposingThis.clear();
+
+    types.allocatedMaps.values.forEach(cleanup);
+    types.allocatedLists.values.forEach(cleanup);
+  }
+
+  Iterable<Element> getCallersOf(Element element) {
+    if (compiler.disableTypeInference) {
+      throw new UnsupportedError(
+          "Cannot query the type inferrer when type inference is disabled.");
+    }
+    MemberTypeInformation info = types.getInferredTypeOf(element);
+    return info.callers;
+  }
+
+  /**
+   * Returns the type of [element] when being called with [selector].
+   */
+  TypeInformation typeOfElementWithSelector(
+      Element element, Selector selector) {
+    if (element.name == Identifiers.noSuchMethod_ &&
+        selector.name != element.name) {
+      // An invocation can resolve to a [noSuchMethod], in which case
+      // we get the return type of [noSuchMethod].
+      return returnTypeOfElement(element);
+    } else if (selector.isGetter) {
+      if (element.isFunction) {
+        // [functionType] is null if the inferrer did not run.
+        return types.functionType == null
+            ? types.dynamicType
+            : types.functionType;
+      } else if (element.isField) {
+        return typeOfElement(element);
+      } else if (Elements.isUnresolved(element)) {
+        return types.dynamicType;
+      } else {
+        assert(element.isGetter);
+        return returnTypeOfElement(element);
+      }
+    } else if (element.isGetter || element.isField) {
+      assert(selector.isCall || selector.isSetter);
+      return types.dynamicType;
+    } else {
+      return returnTypeOfElement(element);
+    }
+  }
+
+  /**
+   * Records that the captured variable [local] is read.
+   */
+  void recordCapturedLocalRead(Local local) {}
+
+  /**
+   * Records that the variable [local] is being updated.
+   */
+  void recordLocalUpdate(Local local, TypeInformation type) {}
+}
diff --git a/pkg/compiler/lib/src/inferrer/inferrer_visitor.dart b/pkg/compiler/lib/src/inferrer/inferrer_visitor.dart
index 20ae0de..96aedd9 100644
--- a/pkg/compiler/lib/src/inferrer/inferrer_visitor.dart
+++ b/pkg/compiler/lib/src/inferrer/inferrer_visitor.dart
@@ -23,124 +23,9 @@
 import '../universe/selector.dart' show Selector;
 import '../util/util.dart';
 import '../world.dart' show ClosedWorld;
-
-/**
- * The interface [InferrerVisitor] will use when working on types.
- */
-abstract class TypeSystem<T> {
-  T get dynamicType;
-  T get nullType;
-  T get intType;
-  T get uint31Type;
-  T get uint32Type;
-  T get positiveIntType;
-  T get doubleType;
-  T get numType;
-  T get boolType;
-  T get functionType;
-  T get listType;
-  T get constListType;
-  T get fixedListType;
-  T get growableListType;
-  T get mapType;
-  T get constMapType;
-  T get stringType;
-  T get typeType;
-  T get syncStarIterableType;
-  T get asyncFutureType; // Subtype of Future returned by async methods.
-  T get asyncStarStreamType;
-
-  T stringLiteralType(DartString value);
-  T boolLiteralType(LiteralBool value);
-
-  T nonNullSubtype(ClassElement type);
-  T nonNullSubclass(ClassElement type);
-  T nonNullExact(ClassElement type);
-  T nonNullEmpty();
-  bool isNull(T type);
-  TypeMask newTypedSelector(T receiver, TypeMask mask);
-
-  T allocateList(T type, Node node, Element enclosing,
-      [T elementType, int length]);
-
-  T allocateMap(T type, Node node, Element element,
-      [List<T> keyType, List<T> valueType]);
-
-  T allocateClosure(Node node, Element element);
-
-  /**
-   * Returns the least upper bound between [firstType] and
-   * [secondType].
-   */
-  T computeLUB(T firstType, T secondType);
-
-  /**
-   * Returns the intersection between [T] and [annotation].
-   * [isNullable] indicates whether the annotation implies a null
-   * type.
-   */
-  T narrowType(T type, ResolutionDartType annotation, {bool isNullable: true});
-
-  /**
-   * Returns the non-nullable type [T].
-   */
-  T narrowNotNull(T type);
-
-  /**
-   * Returns a new type that unions [firstInput] and [secondInput].
-   */
-  T allocateDiamondPhi(T firstInput, T secondInput);
-
-  /**
-   * Returns a new type for holding the potential types of [element].
-   * [inputType] is the first incoming type of the phi.
-   */
-  T allocatePhi(Node node, Local variable, T inputType);
-
-  /**
-   * Returns a new type for holding the potential types of [element].
-   * [inputType] is the first incoming type of the phi. [allocateLoopPhi]
-   * only differs from [allocatePhi] in that it allows the underlying
-   * implementation of [TypeSystem] to differentiate Phi nodes due to loops
-   * from other merging uses.
-   */
-  T allocateLoopPhi(Node node, Local variable, T inputType);
-
-  /**
-   * Simplies the phi representing [element] and of the type
-   * [phiType]. For example, if this phi has one incoming input, an
-   * implementation of this method could just return that incoming
-   * input type.
-   */
-  T simplifyPhi(Node node, Local variable, T phiType);
-
-  /**
-   * Adds [newType] as an input of [phiType].
-   */
-  T addPhiInput(Local variable, T phiType, T newType);
-
-  /**
-   * Returns `true` if `selector` should be updated to reflect the new
-   * `receiverType`.
-   */
-  bool selectorNeedsUpdate(T receiverType, TypeMask mask);
-
-  /**
-   * Returns a new receiver type for this [selector] applied to
-   * [receiverType].
-   *
-   * The option [isConditional] is true when [selector] was seen in a
-   * conditional send (e.g.  `a?.selector`), in which case the returned type may
-   * be null.
-   */
-  T refineReceiver(
-      Selector selector, TypeMask mask, T receiverType, bool isConditional);
-
-  /**
-   * Returns the internal inferrer representation for [mask].
-   */
-  T getConcreteTypeFor(TypeMask mask);
-}
+import 'inferrer_engine.dart';
+import 'type_graph_nodes.dart';
+import 'type_system.dart';
 
 /**
  * A variable scope holds types for variables. It has a link to a
@@ -149,11 +34,11 @@
  * The inferrer makes sure updates get merged into the parent scope,
  * once the control flow block has been visited.
  */
-class VariableScope<T> {
-  Map<Local, T> variables;
+class VariableScope {
+  Map<Local, TypeInformation> variables;
 
   /// The parent of this scope. Null for the root scope.
-  final VariableScope<T> parent;
+  final VariableScope parent;
 
   /// The [Node] that created this scope.
   final Node block;
@@ -162,44 +47,45 @@
       : this.variables = null,
         this.parent = parent;
 
-  VariableScope.deepCopyOf(VariableScope<T> other)
+  VariableScope.deepCopyOf(VariableScope other)
       : variables = other.variables == null
             ? null
-            : new Map<Local, T>.from(other.variables),
+            : new Map<Local, TypeInformation>.from(other.variables),
         block = other.block,
         parent = other.parent == null
             ? null
-            : new VariableScope<T>.deepCopyOf(other.parent);
+            : new VariableScope.deepCopyOf(other.parent);
 
-  VariableScope.topLevelCopyOf(VariableScope<T> other)
+  VariableScope.topLevelCopyOf(VariableScope other)
       : variables = other.variables == null
             ? null
-            : new Map<Local, T>.from(other.variables),
+            : new Map<Local, TypeInformation>.from(other.variables),
         block = other.block,
         parent = other.parent;
 
-  T operator [](Local variable) {
-    T result;
+  TypeInformation operator [](Local variable) {
+    TypeInformation result;
     if (variables == null || (result = variables[variable]) == null) {
       return parent == null ? null : parent[variable];
     }
     return result;
   }
 
-  void operator []=(Local variable, T mask) {
+  void operator []=(Local variable, TypeInformation mask) {
     assert(mask != null);
     if (variables == null) {
-      variables = new Map<Local, T>();
+      variables = new Map<Local, TypeInformation>();
     }
     variables[variable] = mask;
   }
 
-  void forEachOwnLocal(void f(Local variable, T type)) {
+  void forEachOwnLocal(void f(Local variable, TypeInformation type)) {
     if (variables == null) return;
     variables.forEach(f);
   }
 
-  void forEachLocalUntilNode(Node node, void f(Local variable, T type),
+  void forEachLocalUntilNode(
+      Node node, void f(Local variable, TypeInformation type),
       [Setlet<Local> seenLocals]) {
     if (seenLocals == null) seenLocals = new Setlet<Local>();
     if (variables != null) {
@@ -213,7 +99,7 @@
     if (parent != null) parent.forEachLocalUntilNode(node, f, seenLocals);
   }
 
-  void forEachLocal(void f(Local variable, T type)) {
+  void forEachLocal(void f(Local variable, TypeInformation type)) {
     forEachLocalUntilNode(null, f);
   }
 
@@ -228,48 +114,48 @@
   }
 }
 
-class FieldInitializationScope<T> {
-  final TypeSystem<T> types;
-  Map<Element, T> fields;
+class FieldInitializationScope {
+  final TypeSystem types;
+  Map<Element, TypeInformation> fields;
   bool isThisExposed;
 
   FieldInitializationScope(this.types) : isThisExposed = false;
 
-  FieldInitializationScope.internalFrom(FieldInitializationScope<T> other)
+  FieldInitializationScope.internalFrom(FieldInitializationScope other)
       : types = other.types,
         isThisExposed = other.isThisExposed;
 
-  factory FieldInitializationScope.from(FieldInitializationScope<T> other) {
+  factory FieldInitializationScope.from(FieldInitializationScope other) {
     if (other == null) return null;
-    return new FieldInitializationScope<T>.internalFrom(other);
+    return new FieldInitializationScope.internalFrom(other);
   }
 
-  void updateField(Element field, T type) {
+  void updateField(Element field, TypeInformation type) {
     if (isThisExposed) return;
-    if (fields == null) fields = new Map<Element, T>();
+    if (fields == null) fields = new Map<Element, TypeInformation>();
     fields[field] = type;
   }
 
-  T readField(Element field) {
+  TypeInformation readField(Element field) {
     return fields == null ? null : fields[field];
   }
 
-  void forEach(void f(Element element, T type)) {
+  void forEach(void f(Element element, TypeInformation type)) {
     if (fields == null) return;
     fields.forEach(f);
   }
 
-  void mergeDiamondFlow(FieldInitializationScope<T> thenScope,
-      FieldInitializationScope<T> elseScope) {
+  void mergeDiamondFlow(
+      FieldInitializationScope thenScope, FieldInitializationScope elseScope) {
     // Quick bailout check. If [isThisExposed] is true, we know the
-    // code following won't do anything.
+    // code following won'TypeInformation do anything.
     if (isThisExposed) return;
     if (elseScope == null || elseScope.fields == null) {
       elseScope = this;
     }
 
-    thenScope.forEach((Element field, T type) {
-      T otherType = elseScope.readField(field);
+    thenScope.forEach((Element field, TypeInformation type) {
+      TypeInformation otherType = elseScope.readField(field);
       if (otherType == null) return;
       updateField(field, types.allocateDiamondPhi(type, otherType));
     });
@@ -280,13 +166,13 @@
 /**
  * Placeholder for inferred arguments types on sends.
  */
-class ArgumentsTypes<T> extends IterableMixin<T> {
-  final List<T> positional;
-  final Map<String, T> named;
+class ArgumentsTypes extends IterableMixin<TypeInformation> {
+  final List<TypeInformation> positional;
+  final Map<String, TypeInformation> named;
   ArgumentsTypes(this.positional, named)
       : this.named = (named == null || named.isEmpty) ? const {} : named {
-    assert(this.positional.every((T type) => type != null));
-    assert(this.named.values.every((T type) => type != null));
+    assert(this.positional.every((TypeInformation type) => type != null));
+    assert(this.named.values.every((TypeInformation type) => type != null));
   }
 
   ArgumentsTypes.empty()
@@ -295,7 +181,7 @@
 
   int get length => positional.length + named.length;
 
-  Iterator<T> get iterator => new ArgumentsTypesIterator(this);
+  Iterator<TypeInformation> get iterator => new ArgumentsTypesIterator(this);
 
   String toString() => "{ positional = $positional, named = $named }";
 
@@ -315,32 +201,33 @@
 
   bool hasNoArguments() => positional.isEmpty && named.isEmpty;
 
-  void forEach(void f(T type)) {
+  void forEach(void f(TypeInformation type)) {
     positional.forEach(f);
     named.values.forEach(f);
   }
 
-  bool every(bool f(T type)) {
+  bool every(bool f(TypeInformation type)) {
     return positional.every(f) && named.values.every(f);
   }
 
-  bool contains(T type) {
+  bool contains(TypeInformation type) {
     return positional.contains(type) || named.containsValue(type);
   }
 }
 
-class ArgumentsTypesIterator<T> implements Iterator<T> {
-  final Iterator<T> positional;
-  final Iterator<T> named;
+class ArgumentsTypesIterator implements Iterator<TypeInformation> {
+  final Iterator<TypeInformation> positional;
+  final Iterator<TypeInformation> named;
   bool _iteratePositional = true;
 
-  ArgumentsTypesIterator(ArgumentsTypes<T> iteratee)
+  ArgumentsTypesIterator(ArgumentsTypes iteratee)
       : positional = iteratee.positional.iterator,
         named = iteratee.named.values.iterator;
 
-  Iterator<T> get _currentIterator => _iteratePositional ? positional : named;
+  Iterator<TypeInformation> get _currentIterator =>
+      _iteratePositional ? positional : named;
 
-  T get current => _currentIterator.current;
+  TypeInformation get current => _currentIterator.current;
 
   bool moveNext() {
     if (_iteratePositional && positional.moveNext()) {
@@ -351,44 +238,18 @@
   }
 }
 
-abstract class MinimalInferrerEngine<T> {
-  /**
-   * Returns the type of [element].
-   */
-  T typeOfElement(Element element);
-
-  /**
-   * Records that [node] sets non-final field [element] to be of type
-   * [type].
-   */
-  void recordTypeOfNonFinalField(Node node, Element field, T type);
-
-  /**
-   * Records that the captured variable [local] is read.
-   */
-  void recordCapturedLocalRead(Local local);
-
-  /**
-   * Records that the variable [local] is being updated.
-   */
-  void recordLocalUpdate(Local local, T type);
-
-  /// The [ClosedWorld] on which inference reasoning is based.
-  ClosedWorld get closedWorld;
-}
-
 /**
  * Placeholder for inferred types of local variables.
  */
-class LocalsHandler<T> {
+class LocalsHandler {
   final CompilerOptions options;
-  final TypeSystem<T> types;
-  final MinimalInferrerEngine<T> inferrer;
-  final VariableScope<T> locals;
+  final TypeSystem types;
+  final InferrerEngine inferrer;
+  final VariableScope locals;
   final Map<Local, Element> captured;
   final Map<Local, Element> capturedAndBoxed;
-  final FieldInitializationScope<T> fieldScope;
-  LocalsHandler<T> tryBlock;
+  final FieldInitializationScope fieldScope;
+  LocalsHandler tryBlock;
   bool seenReturnOrThrow = false;
   bool seenBreakOrContinue = false;
 
@@ -400,15 +261,15 @@
 
   LocalsHandler(this.inferrer, this.types, this.options, Node block,
       [this.fieldScope])
-      : locals = new VariableScope<T>(block),
+      : locals = new VariableScope(block),
         captured = new Map<Local, Element>(),
         capturedAndBoxed = new Map<Local, Element>(),
         tryBlock = null;
 
-  LocalsHandler.from(LocalsHandler<T> other, Node block,
+  LocalsHandler.from(LocalsHandler other, Node block,
       {bool useOtherTryBlock: true})
-      : locals = new VariableScope<T>(block, other.locals),
-        fieldScope = new FieldInitializationScope<T>.from(other.fieldScope),
+      : locals = new VariableScope(block, other.locals),
+        fieldScope = new FieldInitializationScope.from(other.fieldScope),
         captured = other.captured,
         capturedAndBoxed = other.capturedAndBoxed,
         types = other.types,
@@ -417,9 +278,9 @@
     tryBlock = useOtherTryBlock ? other.tryBlock : this;
   }
 
-  LocalsHandler.deepCopyOf(LocalsHandler<T> other)
-      : locals = new VariableScope<T>.deepCopyOf(other.locals),
-        fieldScope = new FieldInitializationScope<T>.from(other.fieldScope),
+  LocalsHandler.deepCopyOf(LocalsHandler other)
+      : locals = new VariableScope.deepCopyOf(other.locals),
+        fieldScope = new FieldInitializationScope.from(other.fieldScope),
         captured = other.captured,
         capturedAndBoxed = other.capturedAndBoxed,
         tryBlock = other.tryBlock,
@@ -427,9 +288,9 @@
         inferrer = other.inferrer,
         options = other.options;
 
-  LocalsHandler.topLevelCopyOf(LocalsHandler<T> other)
-      : locals = new VariableScope<T>.topLevelCopyOf(other.locals),
-        fieldScope = new FieldInitializationScope<T>.from(other.fieldScope),
+  LocalsHandler.topLevelCopyOf(LocalsHandler other)
+      : locals = new VariableScope.topLevelCopyOf(other.locals),
+        fieldScope = new FieldInitializationScope.from(other.fieldScope),
         captured = other.captured,
         capturedAndBoxed = other.capturedAndBoxed,
         tryBlock = other.tryBlock,
@@ -437,7 +298,7 @@
         inferrer = other.inferrer,
         options = other.options;
 
-  T use(Local local) {
+  TypeInformation use(Local local) {
     if (capturedAndBoxed.containsKey(local)) {
       return inferrer.typeOfElement(capturedAndBoxed[local]);
     } else {
@@ -448,13 +309,13 @@
     }
   }
 
-  void update(LocalElement local, T type, Node node) {
+  void update(LocalElement local, TypeInformation type, Node node) {
     assert(type != null);
     if (options.trustTypeAnnotations || options.enableTypeAssertions) {
       type = types.narrowType(type, local.type);
     }
     updateLocal() {
-      T currentType = locals[local];
+      TypeInformation currentType = locals[local];
 
       SendSet send = node != null ? node.asSendSet() : null;
       if (send != null && send.isIfNullAssignment && currentType != null) {
@@ -475,15 +336,16 @@
     if (capturedAndBoxed.containsKey(local)) {
       inferrer.recordTypeOfNonFinalField(node, capturedAndBoxed[local], type);
     } else if (inTryBlock) {
-      // We don't know if an assignment in a try block
+      // We don'TypeInformation know if an assignment in a try block
       // will be executed, so all assigments in that block are
       // potential types after we have left it. We update the parent
       // of the try block so that, at exit of the try block, we get
       // the right phi for it.
-      T existing = tryBlock.locals.parent[local];
+      TypeInformation existing = tryBlock.locals.parent[local];
       if (existing != null) {
-        T phiType = types.allocatePhi(tryBlock.locals.block, local, existing);
-        T inputType = types.addPhiInput(local, phiType, type);
+        TypeInformation phiType =
+            types.allocatePhi(tryBlock.locals.block, local, existing);
+        TypeInformation inputType = types.addPhiInput(local, phiType, type);
         tryBlock.locals.parent[local] = inputType;
       }
       // Update the current handler unconditionnally with the new
@@ -502,8 +364,7 @@
     capturedAndBoxed[local] = field;
   }
 
-  void mergeDiamondFlow(
-      LocalsHandler<T> thenBranch, LocalsHandler<T> elseBranch) {
+  void mergeDiamondFlow(LocalsHandler thenBranch, LocalsHandler elseBranch) {
     if (fieldScope != null && elseBranch != null) {
       fieldScope.mergeDiamondFlow(thenBranch.fieldScope, elseBranch.fieldScope);
     }
@@ -515,18 +376,18 @@
         elseBranch.seenBreakOrContinue;
     if (aborts) return;
 
-    void mergeOneBranch(LocalsHandler<T> other) {
-      other.locals.forEachOwnLocal((Local local, T type) {
-        T myType = locals[local];
+    void mergeOneBranch(LocalsHandler other) {
+      other.locals.forEachOwnLocal((Local local, TypeInformation type) {
+        TypeInformation myType = locals[local];
         if (myType == null) return; // Variable is only defined in [other].
         if (type == myType) return;
         locals[local] = types.allocateDiamondPhi(myType, type);
       });
     }
 
-    void inPlaceUpdateOneBranch(LocalsHandler<T> other) {
-      other.locals.forEachOwnLocal((Local local, T type) {
-        T myType = locals[local];
+    void inPlaceUpdateOneBranch(LocalsHandler other) {
+      other.locals.forEachOwnLocal((Local local, TypeInformation type) {
+        TypeInformation myType = locals[local];
         if (myType == null) return; // Variable is only defined in [other].
         if (type == myType) return;
         locals[local] = type;
@@ -542,10 +403,10 @@
       inPlaceUpdateOneBranch(thenBranch);
     } else {
       void mergeLocal(Local local) {
-        T myType = locals[local];
+        TypeInformation myType = locals[local];
         if (myType == null) return;
-        T elseType = elseBranch.locals[local];
-        T thenType = thenBranch.locals[local];
+        TypeInformation elseType = elseBranch.locals[local];
+        TypeInformation thenType = thenBranch.locals[local];
         if (thenType == elseType) {
           locals[local] = thenType;
         } else {
@@ -594,7 +455,7 @@
    * where [:this:] is the [LocalsHandler] for the paths through the
    * labeled statement that do not break out.
    */
-  void mergeAfterBreaks(List<LocalsHandler<T>> handlers,
+  void mergeAfterBreaks(List<LocalsHandler> handlers,
       {bool keepOwnLocals: true}) {
     Node level = locals.block;
     // Use a separate locals handler to perform the merge in, so that Phi
@@ -612,7 +473,7 @@
     // [merged] to update the Phi nodes with original values.
     if (keepOwnLocals && !seenReturnOrThrow) {
       for (Local variable in seenLocals) {
-        T originalType = locals[variable];
+        TypeInformation originalType = locals[variable];
         if (originalType != null) {
           merged.locals[variable] = types.addPhiInput(
               variable, merged.locals[variable], originalType);
@@ -621,7 +482,7 @@
     }
     // Clean up Phi nodes with single input and store back result into
     // actual locals handler.
-    merged.locals.forEachOwnLocal((Local variable, T type) {
+    merged.locals.forEachOwnLocal((Local variable, TypeInformation type) {
       locals[variable] = types.simplifyPhi(level, variable, type);
     });
     seenReturnOrThrow =
@@ -634,13 +495,13 @@
    * unless the local is already present in the set [seen]. This effectively
    * overwrites the current type knowledge in this handler.
    */
-  bool mergeHandler(LocalsHandler<T> other, [Set<Local> seen]) {
+  bool mergeHandler(LocalsHandler other, [Set<Local> seen]) {
     if (other.seenReturnOrThrow) return false;
     bool changed = false;
     other.locals.forEachLocalUntilNode(locals.block, (local, otherType) {
-      T myType = locals[local];
+      TypeInformation myType = locals[local];
       if (myType == null) return;
-      T newType;
+      TypeInformation newType;
       if (seen != null && !seen.contains(local)) {
         newType = types.allocatePhi(locals.block, local, otherType);
         seen.add(local);
@@ -659,7 +520,7 @@
    * Merge all [LocalsHandler] in [handlers] into this handler.
    * Returns whether a local in this handler has changed.
    */
-  bool mergeAll(List<LocalsHandler<T>> handlers) {
+  bool mergeAll(List<LocalsHandler> handlers) {
     bool changed = false;
     assert(!seenReturnOrThrow);
     handlers.forEach((other) {
@@ -669,8 +530,8 @@
   }
 
   void startLoop(Node loop) {
-    locals.forEachLocal((Local variable, T type) {
-      T newType = types.allocateLoopPhi(loop, variable, type);
+    locals.forEachLocal((Local variable, TypeInformation type) {
+      TypeInformation newType = types.allocateLoopPhi(loop, variable, type);
       if (newType != type) {
         locals[variable] = newType;
       }
@@ -678,828 +539,15 @@
   }
 
   void endLoop(Node loop) {
-    locals.forEachLocal((Local variable, T type) {
-      T newType = types.simplifyPhi(loop, variable, type);
+    locals.forEachLocal((Local variable, TypeInformation type) {
+      TypeInformation newType = types.simplifyPhi(loop, variable, type);
       if (newType != type) {
         locals[variable] = newType;
       }
     });
   }
 
-  void updateField(Element element, T type) {
+  void updateField(Element element, TypeInformation type) {
     fieldScope.updateField(element, type);
   }
 }
-
-abstract class InferrerVisitor<T, E extends MinimalInferrerEngine<T>>
-    extends Visitor<T>
-    with
-        SemanticSendResolvedMixin<T, dynamic>,
-        CompoundBulkMixin<T, dynamic>,
-        SetIfNullBulkMixin<T, dynamic>,
-        PrefixBulkMixin<T, dynamic>,
-        PostfixBulkMixin<T, dynamic>,
-        ErrorBulkMixin<T, dynamic>,
-        NewBulkMixin<T, dynamic>,
-        SetBulkMixin<T, dynamic>
-    implements SemanticSendVisitor<T, dynamic> {
-  final Compiler compiler;
-  final AstElement analyzedElement;
-  final ResolvedAst resolvedAst;
-  final TypeSystem<T> types;
-  final E inferrer;
-  final Map<JumpTarget, List<LocalsHandler<T>>> breaksFor =
-      new Map<JumpTarget, List<LocalsHandler<T>>>();
-  final Map<JumpTarget, List<LocalsHandler>> continuesFor =
-      new Map<JumpTarget, List<LocalsHandler<T>>>();
-  LocalsHandler<T> locals;
-  final List<T> cascadeReceiverStack = new List<T>();
-
-  TreeElements get elements => resolvedAst.elements;
-
-  bool accumulateIsChecks = false;
-  bool conditionIsSimple = false;
-  List<Send> isChecks;
-  int loopLevel = 0;
-
-  bool get inLoop => loopLevel > 0;
-  bool get isThisExposed {
-    return analyzedElement.isGenerativeConstructor
-        ? locals.fieldScope.isThisExposed
-        : true;
-  }
-
-  void set isThisExposed(value) {
-    if (analyzedElement.isGenerativeConstructor) {
-      locals.fieldScope.isThisExposed = value;
-    }
-  }
-
-  InferrerVisitor(AstElement analyzedElement, this.resolvedAst, this.inferrer,
-      this.types, this.compiler,
-      [LocalsHandler<T> handler])
-      : this.analyzedElement = analyzedElement,
-        this.locals = handler {
-    if (handler != null) return;
-    Node node;
-    if (resolvedAst.kind == ResolvedAstKind.PARSED) {
-      node = resolvedAst.node;
-    }
-    FieldInitializationScope<T> fieldScope =
-        analyzedElement.isGenerativeConstructor
-            ? new FieldInitializationScope<T>(types)
-            : null;
-    locals = new LocalsHandler<T>(
-        inferrer, types, compiler.options, node, fieldScope);
-  }
-
-  DiagnosticReporter get reporter => compiler.reporter;
-
-  ClosedWorld get closedWorld => inferrer.closedWorld;
-
-  @override
-  SemanticSendVisitor get sendVisitor => this;
-
-  @override
-  T apply(Node node, _) => visit(node);
-
-  T handleSendSet(SendSet node);
-
-  T handleDynamicInvoke(Send node);
-
-  T visitAssert(Assert node) {
-    // Avoid pollution from assert statement unless enabled.
-    if (!compiler.options.enableUserAssertions) {
-      return null;
-    }
-    List<Send> tests = <Send>[];
-    bool simpleCondition = handleCondition(node.condition, tests);
-    LocalsHandler<T> saved = locals;
-    locals = new LocalsHandler<T>.from(locals, node);
-    updateIsChecks(tests, usePositive: true);
-
-    LocalsHandler<T> thenLocals = locals;
-    locals = new LocalsHandler<T>.from(saved, node);
-    if (simpleCondition) updateIsChecks(tests, usePositive: false);
-    visit(node.message);
-    locals.seenReturnOrThrow = true;
-    saved.mergeDiamondFlow(thenLocals, locals);
-    locals = saved;
-    return null;
-  }
-
-  T visitAsyncForIn(AsyncForIn node);
-
-  T visitSyncForIn(SyncForIn node);
-
-  T visitReturn(Return node);
-
-  T visitFunctionExpression(FunctionExpression node);
-
-  @override
-  T bulkHandleSet(SendSet node, _) {
-    return handleSendSet(node);
-  }
-
-  @override
-  T bulkHandleCompound(SendSet node, _) {
-    return handleSendSet(node);
-  }
-
-  @override
-  T bulkHandleSetIfNull(SendSet node, _) {
-    return handleSendSet(node);
-  }
-
-  @override
-  T bulkHandlePrefix(SendSet node, _) {
-    return handleSendSet(node);
-  }
-
-  @override
-  T bulkHandlePostfix(SendSet node, _) {
-    return handleSendSet(node);
-  }
-
-  @override
-  T bulkHandleError(Node node, ErroneousElement error, _) {
-    return types.dynamicType;
-  }
-
-  T visitNode(Node node) {
-    return node.visitChildren(this);
-  }
-
-  T visit(Node node) {
-    return node == null ? null : node.accept(this);
-  }
-
-  T visitFunctionDeclaration(FunctionDeclaration node) {
-    locals.update(elements[node], types.functionType, node);
-    return visit(node.function);
-  }
-
-  T visitLiteralString(LiteralString node) {
-    return types.stringLiteralType(node.dartString);
-  }
-
-  T visitStringInterpolation(StringInterpolation node) {
-    node.visitChildren(this);
-    return types.stringType;
-  }
-
-  T visitStringJuxtaposition(StringJuxtaposition node) {
-    node.visitChildren(this);
-    return types.stringType;
-  }
-
-  T visitLiteralBool(LiteralBool node) {
-    return types.boolLiteralType(node);
-  }
-
-  T visitLiteralDouble(LiteralDouble node) {
-    ConstantSystem constantSystem = compiler.backend.constantSystem;
-    // The JavaScript backend may turn this literal into an integer at
-    // runtime.
-    return types.getConcreteTypeFor(
-        computeTypeMask(closedWorld, constantSystem.createDouble(node.value)));
-  }
-
-  T visitLiteralInt(LiteralInt node) {
-    ConstantSystem constantSystem = compiler.backend.constantSystem;
-    // The JavaScript backend may turn this literal into a double at
-    // runtime.
-    return types.getConcreteTypeFor(
-        computeTypeMask(closedWorld, constantSystem.createInt(node.value)));
-  }
-
-  T visitLiteralList(LiteralList node) {
-    node.visitChildren(this);
-    return node.isConst ? types.constListType : types.growableListType;
-  }
-
-  T visitLiteralMap(LiteralMap node) {
-    node.visitChildren(this);
-    return node.isConst ? types.constMapType : types.mapType;
-  }
-
-  T visitLiteralNull(LiteralNull node) {
-    return types.nullType;
-  }
-
-  T visitLiteralSymbol(LiteralSymbol node) {
-    // TODO(kasperl): We should be able to tell that the type of a literal
-    // symbol is always a non-null exact symbol implementation -- not just
-    // any non-null subtype of the symbol interface.
-    return types.nonNullSubtype(closedWorld.commonElements.symbolClass);
-  }
-
-  @override
-  void previsitDeferredAccess(Send node, PrefixElement prefix, _) {
-    // Deferred access does not affect inference.
-  }
-
-  T handleTypeLiteralGet() {
-    return types.typeType;
-  }
-
-  T handleTypeLiteralInvoke(NodeList arguments) {
-    return types.dynamicType;
-  }
-
-  @override
-  T bulkHandleNode(Node node, String message, _) {
-    return internalError(node, message.replaceAll('#', '$node'));
-  }
-
-  @override
-  T visitConstantGet(Send node, ConstantExpression constant, _) {
-    return bulkHandleNode(node, "Constant read `#` unhandled.", _);
-  }
-
-  @override
-  T visitConstantInvoke(Send node, ConstantExpression constant,
-      NodeList arguments, CallStructure callStructure, _) {
-    return bulkHandleNode(node, "Constant invoke `#` unhandled.", _);
-  }
-
-  T visitClassTypeLiteralGet(Send node, ConstantExpression constant, _) {
-    return handleTypeLiteralGet();
-  }
-
-  T visitClassTypeLiteralInvoke(Send node, ConstantExpression constant,
-      NodeList arguments, CallStructure callStructure, _) {
-    return handleTypeLiteralInvoke(arguments);
-  }
-
-  T visitTypedefTypeLiteralGet(Send node, ConstantExpression constant, _) {
-    return handleTypeLiteralGet();
-  }
-
-  T visitTypedefTypeLiteralInvoke(Send node, ConstantExpression constant,
-      NodeList arguments, CallStructure callStructure, _) {
-    return handleTypeLiteralInvoke(arguments);
-  }
-
-  T visitTypeVariableTypeLiteralGet(Send node, TypeVariableElement element, _) {
-    return handleTypeLiteralGet();
-  }
-
-  T visitTypeVariableTypeLiteralInvoke(Send node, TypeVariableElement element,
-      NodeList arguments, CallStructure callStructure, _) {
-    return handleTypeLiteralInvoke(arguments);
-  }
-
-  T visitDynamicTypeLiteralGet(Send node, ConstantExpression constant, _) {
-    return handleTypeLiteralGet();
-  }
-
-  T visitDynamicTypeLiteralInvoke(Send node, ConstantExpression constant,
-      NodeList arguments, CallStructure callStructure, _) {
-    return handleTypeLiteralInvoke(arguments);
-  }
-
-  bool isThisOrSuper(Node node) => node.isThis() || node.isSuper();
-
-  Element get outermostElement {
-    return analyzedElement.outermostEnclosingMemberOrTopLevel.implementation;
-  }
-
-  T _thisType;
-  T get thisType {
-    if (_thisType != null) return _thisType;
-    ClassElement cls = outermostElement.enclosingClass;
-    if (closedWorld.isUsedAsMixin(cls)) {
-      return _thisType = types.nonNullSubtype(cls);
-    } else {
-      return _thisType = types.nonNullSubclass(cls);
-    }
-  }
-
-  @override
-  T visitThisGet(Identifier node, _) {
-    return thisType;
-  }
-
-  T visitIdentifier(Identifier node) {
-    if (node.isThis()) {
-      return thisType;
-    } else if (node.isSuper()) {
-      return internalError(node, 'Unexpected expression $node.');
-    } else {
-      Element element = elements[node];
-      if (Elements.isLocal(element)) {
-        LocalElement local = element;
-        return locals.use(local);
-      }
-      return null;
-    }
-  }
-
-  void potentiallyAddIsCheck(Send node) {
-    if (!accumulateIsChecks) return;
-    if (!Elements.isLocal(elements[node.receiver])) return;
-    isChecks.add(node);
-  }
-
-  void potentiallyAddNullCheck(Send node, Node receiver) {
-    if (!accumulateIsChecks) return;
-    if (!Elements.isLocal(elements[receiver])) return;
-    isChecks.add(node);
-  }
-
-  void updateIsChecks(List<Node> tests, {bool usePositive}) {
-    void narrow(Element element, ResolutionDartType type, Node node) {
-      if (element is LocalElement) {
-        T existing = locals.use(element);
-        T newType = types.narrowType(existing, type, isNullable: false);
-        locals.update(element, newType, node);
-      }
-    }
-
-    if (tests == null) return;
-    for (Send node in tests) {
-      if (node.isTypeTest) {
-        if (node.isIsNotCheck) {
-          if (usePositive) continue;
-        } else {
-          if (!usePositive) continue;
-        }
-        ResolutionDartType type =
-            elements.getType(node.typeAnnotationFromIsCheckOrCast);
-        narrow(elements[node.receiver], type, node);
-      } else {
-        Element receiverElement = elements[node.receiver];
-        Element argumentElement = elements[node.arguments.first];
-        String operator = node.selector.asOperator().source;
-        if ((operator == '==' && usePositive) ||
-            (operator == '!=' && !usePositive)) {
-          // Type the elements as null.
-          if (Elements.isLocal(receiverElement)) {
-            locals.update(receiverElement, types.nullType, node);
-          }
-          if (Elements.isLocal(argumentElement)) {
-            locals.update(argumentElement, types.nullType, node);
-          }
-        } else {
-          // Narrow the elements to a non-null type.
-          ResolutionDartType objectType = closedWorld.commonElements.objectType;
-          if (Elements.isLocal(receiverElement)) {
-            narrow(receiverElement, objectType, node);
-          }
-          if (Elements.isLocal(argumentElement)) {
-            narrow(argumentElement, objectType, node);
-          }
-        }
-      }
-    }
-  }
-
-  @override
-  T visitIndex(Send node, Node receiver, Node index, _) {
-    return handleDynamicInvoke(node);
-  }
-
-  @override
-  T visitDynamicPropertyInvoke(
-      Send node, Node receiver, NodeList arguments, Selector selector, _) {
-    return handleDynamicInvoke(node);
-  }
-
-  @override
-  T visitIfNotNullDynamicPropertyInvoke(
-      Send node, Node receiver, NodeList arguments, Selector selector, _) {
-    return handleDynamicInvoke(node);
-  }
-
-  @override
-  T visitThisPropertyInvoke(
-      Send node, NodeList arguments, Selector selector, _) {
-    return handleDynamicInvoke(node);
-  }
-
-  @override
-  T visitIfNull(Send node, Node left, Node right, _) {
-    T firstType = visit(left);
-    T secondType = visit(right);
-    return types.allocateDiamondPhi(types.narrowNotNull(firstType), secondType);
-  }
-
-  @override
-  T visitLogicalAnd(Send node, Node left, Node right, _) {
-    conditionIsSimple = false;
-    bool oldAccumulateIsChecks = accumulateIsChecks;
-    List<Send> oldIsChecks = isChecks;
-    if (!accumulateIsChecks) {
-      accumulateIsChecks = true;
-      isChecks = <Send>[];
-    }
-    visit(left);
-    LocalsHandler<T> saved = locals;
-    locals = new LocalsHandler<T>.from(locals, node);
-    updateIsChecks(isChecks, usePositive: true);
-    LocalsHandler<T> narrowed;
-    if (oldAccumulateIsChecks) {
-      narrowed = new LocalsHandler<T>.topLevelCopyOf(locals);
-    } else {
-      accumulateIsChecks = false;
-      isChecks = oldIsChecks;
-    }
-    visit(right);
-    if (oldAccumulateIsChecks) {
-      bool invalidatedInRightHandSide(Send test) {
-        Element receiver = elements[test.receiver];
-        if (receiver is LocalElement) {
-          return narrowed.locals[receiver] != locals.locals[receiver];
-        }
-        return false;
-      }
-
-      isChecks.removeWhere(invalidatedInRightHandSide);
-    }
-    saved.mergeDiamondFlow(locals, null);
-    locals = saved;
-    return types.boolType;
-  }
-
-  @override
-  T visitLogicalOr(Send node, Node left, Node right, _) {
-    conditionIsSimple = false;
-    List<Send> tests = <Send>[];
-    bool isSimple = handleCondition(left, tests);
-    LocalsHandler<T> saved = locals;
-    locals = new LocalsHandler<T>.from(locals, node);
-    if (isSimple) updateIsChecks(tests, usePositive: false);
-    bool oldAccumulateIsChecks = accumulateIsChecks;
-    accumulateIsChecks = false;
-    visit(right);
-    accumulateIsChecks = oldAccumulateIsChecks;
-    saved.mergeDiamondFlow(locals, null);
-    locals = saved;
-    return types.boolType;
-  }
-
-  @override
-  T visitNot(Send node, Node expression, _) {
-    bool oldAccumulateIsChecks = accumulateIsChecks;
-    accumulateIsChecks = false;
-    visit(expression);
-    accumulateIsChecks = oldAccumulateIsChecks;
-    return types.boolType;
-  }
-
-  @override
-  T visitIs(Send node, Node expression, ResolutionDartType type, _) {
-    potentiallyAddIsCheck(node);
-    visit(expression);
-    return types.boolType;
-  }
-
-  @override
-  T visitIsNot(Send node, Node expression, ResolutionDartType type, _) {
-    potentiallyAddIsCheck(node);
-    visit(expression);
-    return types.boolType;
-  }
-
-  @override
-  T visitAs(Send node, Node expression, ResolutionDartType type, _) {
-    T receiverType = visit(expression);
-    return types.narrowType(receiverType, type);
-  }
-
-  @override
-  T visitUnary(Send node, UnaryOperator operator, Node expression, _) {
-    return handleDynamicInvoke(node);
-  }
-
-  @override
-  T visitNotEquals(Send node, Node left, Node right, _) {
-    handleDynamicInvoke(node);
-    return types.boolType;
-  }
-
-  @override
-  T visitEquals(Send node, Node left, Node right, _) {
-    return handleDynamicInvoke(node);
-  }
-
-  @override
-  T visitBinary(Send node, Node left, BinaryOperator operator, Node right, _) {
-    return handleDynamicInvoke(node);
-  }
-
-  // Because some nodes just visit their children, we may end up
-  // visiting a type annotation, that may contain a send in case of a
-  // prefixed type. Therefore we explicitly visit the type annotation
-  // to avoid confusing the [ResolvedVisitor].
-  visitTypeAnnotation(TypeAnnotation node) {}
-
-  T visitConditional(Conditional node) {
-    List<Send> tests = <Send>[];
-    bool simpleCondition = handleCondition(node.condition, tests);
-    LocalsHandler<T> saved = locals;
-    locals = new LocalsHandler<T>.from(locals, node);
-    updateIsChecks(tests, usePositive: true);
-    T firstType = visit(node.thenExpression);
-    LocalsHandler<T> thenLocals = locals;
-    locals = new LocalsHandler<T>.from(saved, node);
-    if (simpleCondition) updateIsChecks(tests, usePositive: false);
-    T secondType = visit(node.elseExpression);
-    saved.mergeDiamondFlow(thenLocals, locals);
-    locals = saved;
-    T type = types.allocateDiamondPhi(firstType, secondType);
-    return type;
-  }
-
-  T visitVariableDefinitions(VariableDefinitions node) {
-    for (Link<Node> link = node.definitions.nodes;
-        !link.isEmpty;
-        link = link.tail) {
-      Node definition = link.head;
-      if (definition is Identifier) {
-        locals.update(elements[definition], types.nullType, node);
-      } else {
-        assert(definition.asSendSet() != null);
-        handleSendSet(definition);
-      }
-    }
-    return null;
-  }
-
-  bool handleCondition(Node node, List<Send> tests) {
-    bool oldConditionIsSimple = conditionIsSimple;
-    bool oldAccumulateIsChecks = accumulateIsChecks;
-    List<Send> oldIsChecks = isChecks;
-    accumulateIsChecks = true;
-    conditionIsSimple = true;
-    isChecks = tests;
-    visit(node);
-    bool simpleCondition = conditionIsSimple;
-    accumulateIsChecks = oldAccumulateIsChecks;
-    isChecks = oldIsChecks;
-    conditionIsSimple = oldConditionIsSimple;
-    return simpleCondition;
-  }
-
-  T visitIf(If node) {
-    List<Send> tests = <Send>[];
-    bool simpleCondition = handleCondition(node.condition, tests);
-    LocalsHandler<T> saved = locals;
-    locals = new LocalsHandler<T>.from(locals, node);
-    updateIsChecks(tests, usePositive: true);
-    visit(node.thenPart);
-    LocalsHandler<T> thenLocals = locals;
-    locals = new LocalsHandler<T>.from(saved, node);
-    if (simpleCondition) updateIsChecks(tests, usePositive: false);
-    visit(node.elsePart);
-    saved.mergeDiamondFlow(thenLocals, locals);
-    locals = saved;
-    return null;
-  }
-
-  void setupBreaksAndContinues(JumpTarget element) {
-    if (element == null) return;
-    if (element.isContinueTarget) continuesFor[element] = <LocalsHandler>[];
-    if (element.isBreakTarget) breaksFor[element] = <LocalsHandler>[];
-  }
-
-  void clearBreaksAndContinues(JumpTarget element) {
-    continuesFor.remove(element);
-    breaksFor.remove(element);
-  }
-
-  List<LocalsHandler<T>> getBreaks(JumpTarget element) {
-    List<LocalsHandler<T>> list = <LocalsHandler<T>>[locals];
-    if (element == null) return list;
-    if (!element.isBreakTarget) return list;
-    return list..addAll(breaksFor[element]);
-  }
-
-  List<LocalsHandler<T>> getLoopBackEdges(JumpTarget element) {
-    List<LocalsHandler<T>> list = <LocalsHandler<T>>[locals];
-    if (element == null) return list;
-    if (!element.isContinueTarget) return list;
-    return list..addAll(continuesFor[element]);
-  }
-
-  T handleLoop(Node node, void logic()) {
-    loopLevel++;
-    bool changed = false;
-    JumpTarget target = elements.getTargetDefinition(node);
-    LocalsHandler<T> saved = locals;
-    saved.startLoop(node);
-    do {
-      // Setup (and clear in case of multiple iterations of the loop)
-      // the lists of breaks and continues seen in the loop.
-      setupBreaksAndContinues(target);
-      locals = new LocalsHandler<T>.from(saved, node);
-      logic();
-      changed = saved.mergeAll(getLoopBackEdges(target));
-    } while (changed);
-    loopLevel--;
-    saved.endLoop(node);
-    bool keepOwnLocals = node.asDoWhile() == null;
-    saved.mergeAfterBreaks(getBreaks(target), keepOwnLocals: keepOwnLocals);
-    locals = saved;
-    clearBreaksAndContinues(target);
-    return null;
-  }
-
-  T visitWhile(While node) {
-    return handleLoop(node, () {
-      List<Send> tests = <Send>[];
-      handleCondition(node.condition, tests);
-      updateIsChecks(tests, usePositive: true);
-      visit(node.body);
-    });
-  }
-
-  T visitDoWhile(DoWhile node) {
-    return handleLoop(node, () {
-      visit(node.body);
-      List<Send> tests = <Send>[];
-      handleCondition(node.condition, tests);
-      updateIsChecks(tests, usePositive: true);
-    });
-  }
-
-  T visitFor(For node) {
-    visit(node.initializer);
-    return handleLoop(node, () {
-      List<Send> tests = <Send>[];
-      handleCondition(node.condition, tests);
-      updateIsChecks(tests, usePositive: true);
-      visit(node.body);
-      visit(node.update);
-    });
-  }
-
-  T visitTryStatement(TryStatement node) {
-    LocalsHandler<T> saved = locals;
-    locals = new LocalsHandler<T>.from(locals, node, useOtherTryBlock: false);
-    visit(node.tryBlock);
-    saved.mergeDiamondFlow(locals, null);
-    locals = saved;
-    for (Node catchBlock in node.catchBlocks) {
-      saved = locals;
-      locals = new LocalsHandler<T>.from(locals, catchBlock);
-      visit(catchBlock);
-      saved.mergeDiamondFlow(locals, null);
-      locals = saved;
-    }
-    visit(node.finallyBlock);
-    return null;
-  }
-
-  T visitThrow(Throw node) {
-    node.visitChildren(this);
-    locals.seenReturnOrThrow = true;
-    return types.nonNullEmpty();
-  }
-
-  T visitCatchBlock(CatchBlock node) {
-    Node exception = node.exception;
-    if (exception != null) {
-      ResolutionDartType type = elements.getType(node.type);
-      T mask = type == null || type.treatAsDynamic || type.isTypeVariable
-          ? types.dynamicType
-          : types.nonNullSubtype(type.element);
-      locals.update(elements[exception], mask, node);
-    }
-    Node trace = node.trace;
-    if (trace != null) {
-      locals.update(elements[trace], types.dynamicType, node);
-    }
-    visit(node.block);
-    return null;
-  }
-
-  T visitParenthesizedExpression(ParenthesizedExpression node) {
-    return visit(node.expression);
-  }
-
-  T visitBlock(Block node) {
-    if (node.statements != null) {
-      for (Node statement in node.statements) {
-        visit(statement);
-        if (locals.aborts) break;
-      }
-    }
-    return null;
-  }
-
-  T visitLabeledStatement(LabeledStatement node) {
-    Statement body = node.statement;
-    if (body is Loop ||
-        body is SwitchStatement ||
-        Elements.isUnusedLabel(node, elements)) {
-      // Loops and switches handle their own labels.
-      visit(body);
-    } else {
-      JumpTarget targetElement = elements.getTargetDefinition(body);
-      setupBreaksAndContinues(targetElement);
-      visit(body);
-      locals.mergeAfterBreaks(getBreaks(targetElement));
-      clearBreaksAndContinues(targetElement);
-    }
-    return null;
-  }
-
-  T visitBreakStatement(BreakStatement node) {
-    JumpTarget target = elements.getTargetOf(node);
-    locals.seenBreakOrContinue = true;
-    // Do a deep-copy of the locals, because the code following the
-    // break will change them.
-    breaksFor[target].add(new LocalsHandler<T>.deepCopyOf(locals));
-    return null;
-  }
-
-  T visitContinueStatement(ContinueStatement node) {
-    JumpTarget target = elements.getTargetOf(node);
-    locals.seenBreakOrContinue = true;
-    // Do a deep-copy of the locals, because the code following the
-    // continue will change them.
-    continuesFor[target].add(new LocalsHandler<T>.deepCopyOf(locals));
-    return null;
-  }
-
-  internalError(Spannable node, String reason) {
-    reporter.internalError(node, reason);
-  }
-
-  T visitSwitchStatement(SwitchStatement node) {
-    visit(node.parenthesizedExpression);
-
-    setupBreaksAndContinues(elements.getTargetDefinition(node));
-    if (Elements.switchStatementHasContinue(node, elements)) {
-      void forEachLabeledCase(void action(JumpTarget target)) {
-        for (SwitchCase switchCase in node.cases) {
-          for (Node labelOrCase in switchCase.labelsAndCases) {
-            if (labelOrCase.asLabel() == null) continue;
-            LabelDefinition labelElement =
-                elements.getLabelDefinition(labelOrCase);
-            if (labelElement != null) {
-              action(labelElement.target);
-            }
-          }
-        }
-      }
-
-      forEachLabeledCase((JumpTarget target) {
-        setupBreaksAndContinues(target);
-      });
-
-      // If the switch statement has a continue, we conservatively
-      // visit all cases and update [locals] until we have reached a
-      // fixed point.
-      bool changed;
-      locals.startLoop(node);
-      do {
-        changed = false;
-        for (Node switchCase in node.cases) {
-          LocalsHandler<T> saved = locals;
-          locals = new LocalsHandler<T>.from(locals, switchCase);
-          visit(switchCase);
-          changed = saved.mergeAll([locals]) || changed;
-          locals = saved;
-        }
-      } while (changed);
-      locals.endLoop(node);
-
-      forEachLabeledCase((JumpTarget target) {
-        clearBreaksAndContinues(target);
-      });
-    } else {
-      LocalsHandler<T> saved = locals;
-      List<LocalsHandler<T>> localsToMerge = <LocalsHandler<T>>[];
-      bool hasDefaultCase = false;
-
-      for (SwitchCase switchCase in node.cases) {
-        if (switchCase.isDefaultCase) {
-          hasDefaultCase = true;
-        }
-        locals = new LocalsHandler<T>.from(saved, switchCase);
-        visit(switchCase);
-        localsToMerge.add(locals);
-      }
-      saved.mergeAfterBreaks(localsToMerge, keepOwnLocals: !hasDefaultCase);
-      locals = saved;
-    }
-    clearBreaksAndContinues(elements.getTargetDefinition(node));
-    return null;
-  }
-
-  T visitCascadeReceiver(CascadeReceiver node) {
-    var type = visit(node.expression);
-    cascadeReceiverStack.add(type);
-    return type;
-  }
-
-  T visitCascade(Cascade node) {
-    // Ignore the result of the cascade send and return the type of the cascade
-    // receiver.
-    visit(node.expression);
-    return cascadeReceiverStack.removeLast();
-  }
-}
diff --git a/pkg/compiler/lib/src/inferrer/list_tracer.dart b/pkg/compiler/lib/src/inferrer/list_tracer.dart
index 575a8c9..96fc9d6 100644
--- a/pkg/compiler/lib/src/inferrer/list_tracer.dart
+++ b/pkg/compiler/lib/src/inferrer/list_tracer.dart
@@ -130,7 +130,7 @@
   'checkGrowable',
 ]);
 
-class ListTracerVisitor extends TracerVisitor<ListTypeInformation> {
+class ListTracerVisitor extends TracerVisitor {
   // The [Set] of found assignments to the list.
   Set<TypeInformation> assignments = new Setlet<TypeInformation>();
   bool callsGrowableMethod = false;
diff --git a/pkg/compiler/lib/src/inferrer/map_tracer.dart b/pkg/compiler/lib/src/inferrer/map_tracer.dart
index 0abb2ca..3693663e 100644
--- a/pkg/compiler/lib/src/inferrer/map_tracer.dart
+++ b/pkg/compiler/lib/src/inferrer/map_tracer.dart
@@ -31,7 +31,7 @@
   "remove"
 ]);
 
-class MapTracerVisitor extends TracerVisitor<MapTypeInformation> {
+class MapTracerVisitor extends TracerVisitor {
   // These lists are used to keep track of newly discovered assignments to
   // the map. Note that elements at corresponding indices are expected to
   // belong to the same assignment operation.
diff --git a/pkg/compiler/lib/src/inferrer/node_tracer.dart b/pkg/compiler/lib/src/inferrer/node_tracer.dart
index 72c6965..5261780 100644
--- a/pkg/compiler/lib/src/inferrer/node_tracer.dart
+++ b/pkg/compiler/lib/src/inferrer/node_tracer.dart
@@ -10,7 +10,7 @@
 import '../types/types.dart' show ContainerTypeMask, MapTypeMask;
 import '../util/util.dart' show Setlet;
 import 'debug.dart' as debug;
-import 'type_graph_inferrer.dart' show TypeGraphInferrerEngine;
+import 'inferrer_engine.dart';
 import 'type_graph_nodes.dart';
 
 // A set of selectors we know do not escape the elements inside the
@@ -72,16 +72,15 @@
 ]);
 
 /// Common logic to trace a value through the type inference graph nodes.
-abstract class TracerVisitor<T extends TypeInformation>
-    implements TypeInformationVisitor {
-  final T tracedType;
-  final TypeGraphInferrerEngine inferrer;
+abstract class TracerVisitor implements TypeInformationVisitor {
+  final TypeInformation tracedType;
+  final InferrerEngine inferrer;
   final Compiler compiler;
 
   static const int MAX_ANALYSIS_COUNT = 16;
   final Setlet<Element> analyzedElements = new Setlet<Element>();
 
-  TracerVisitor(this.tracedType, TypeGraphInferrerEngine inferrer)
+  TracerVisitor(this.tracedType, InferrerEngine inferrer)
       : this.inferrer = inferrer,
         this.compiler = inferrer.compiler;
 
diff --git a/pkg/compiler/lib/src/inferrer/simple_types_inferrer.dart b/pkg/compiler/lib/src/inferrer/simple_types_inferrer.dart
index 2f7abd5..476b0fc 100644
--- a/pkg/compiler/lib/src/inferrer/simple_types_inferrer.dart
+++ b/pkg/compiler/lib/src/inferrer/simple_types_inferrer.dart
@@ -8,307 +8,29 @@
 import '../common.dart';
 import '../common/names.dart' show Identifiers, Selectors;
 import '../compiler.dart' show Compiler;
+import '../constants/constant_system.dart';
+import '../constants/expressions.dart';
 import '../constants/values.dart' show ConstantValue, IntConstantValue;
-import '../core_types.dart' show CommonElements;
 import '../elements/resolution_types.dart' show ResolutionDartType;
 import '../elements/elements.dart';
 import '../js_backend/backend_helpers.dart';
 import '../js_backend/js_backend.dart' as js;
 import '../native/native.dart' as native;
 import '../resolution/operators.dart' as op;
+import '../resolution/semantic_visitor.dart';
+import '../resolution/tree_elements.dart' show TreeElements;
 import '../tree/tree.dart' as ast;
+import '../types/constants.dart' show computeTypeMask;
 import '../types/types.dart' show TypeMask, GlobalTypeInferenceElementData;
 import '../universe/call_structure.dart' show CallStructure;
 import '../universe/selector.dart' show Selector;
 import '../universe/side_effects.dart' show SideEffects;
 import '../util/util.dart' show Link, Setlet;
-import '../world.dart' show ClosedWorld, ClosedWorldRefiner;
+import '../world.dart' show ClosedWorld;
+import 'inferrer_engine.dart';
 import 'inferrer_visitor.dart';
-
-/**
- * Common super class used by [SimpleTypeInferrerVisitor] to propagate
- * type information about visited nodes, as well as to request type
- * information of elements.
- */
-abstract class InferrerEngine<T, V extends TypeSystem>
-    implements MinimalInferrerEngine<T> {
-  final Compiler compiler;
-  final ClosedWorld closedWorld;
-  final ClosedWorldRefiner closedWorldRefiner;
-  final V types;
-  final Map<ast.Node, T> concreteTypes = new Map<ast.Node, T>();
-  final Set<Element> generativeConstructorsExposingThis = new Set<Element>();
-
-  /// Data computed internally within elements, like the type-mask of a send a
-  /// list allocation, or a for-in loop.
-  final Map<Element, GlobalTypeInferenceElementData> inTreeData =
-      new Map<Element, GlobalTypeInferenceElementData>();
-
-  InferrerEngine(
-      this.compiler, this.closedWorld, this.closedWorldRefiner, this.types);
-
-  CommonElements get commonElements => closedWorld.commonElements;
-
-  /**
-   * Records the default type of parameter [parameter].
-   */
-  void setDefaultTypeOfParameter(ParameterElement parameter, T type);
-
-  /**
-   * This helper breaks abstractions but is currently required to work around
-   * the wrong modelling of default values of optional parameters of
-   * synthetic constructors.
-   *
-   * TODO(johnniwinther): Remove once default values of synthetic parameters
-   * are fixed.
-   */
-  bool hasAlreadyComputedTypeOfParameterDefault(ParameterElement paramemter);
-
-  /**
-   * Returns the type of [element].
-   */
-  T typeOfElement(Element element);
-
-  /**
-   * Returns the return type of [element].
-   */
-  T returnTypeOfElement(Element element);
-
-  /**
-   * Records that [node] sets final field [element] to be of type [type].
-   *
-   * [nodeHolder] is the element holder of [node].
-   */
-  void recordTypeOfFinalField(
-      ast.Node node, Element nodeHolder, Element field, T type);
-
-  /**
-   * Records that [node] sets non-final field [element] to be of type
-   * [type].
-   */
-  void recordTypeOfNonFinalField(Spannable node, Element field, T type);
-
-  /**
-   * Records that [element] is of type [type].
-   */
-  void recordType(Element element, T type);
-
-  /**
-   * Records that the return type [element] is of type [type].
-   */
-  void recordReturnType(Element element, T type);
-
-  /**
-   * Registers that [caller] calls [callee] at location [node], with
-   * [selector], and [arguments]. Note that [selector] is null for
-   * forwarding constructors.
-   *
-   * [sideEffects] will be updated to incorporate [callee]'s side
-   * effects.
-   *
-   * [inLoop] tells whether the call happens in a loop.
-   */
-  T registerCalledElement(
-      Spannable node,
-      Selector selector,
-      TypeMask mask,
-      Element caller,
-      Element callee,
-      ArgumentsTypes<T> arguments,
-      SideEffects sideEffects,
-      bool inLoop);
-
-  /**
-   * Registers that [caller] calls [selector] with [receiverType] as
-   * receiver, and [arguments].
-   *
-   * [sideEffects] will be updated to incorporate the potential
-   * callees' side effects.
-   *
-   * [inLoop] tells whether the call happens in a loop.
-   */
-  T registerCalledSelector(
-      ast.Node node,
-      Selector selector,
-      TypeMask mask,
-      T receiverType,
-      Element caller,
-      ArgumentsTypes<T> arguments,
-      SideEffects sideEffects,
-      bool inLoop);
-
-  /**
-   * Registers that [caller] calls [closure] with [arguments].
-   *
-   * [sideEffects] will be updated to incorporate the potential
-   * callees' side effects.
-   *
-   * [inLoop] tells whether the call happens in a loop.
-   */
-  T registerCalledClosure(
-      ast.Node node,
-      Selector selector,
-      TypeMask mask,
-      T closure,
-      Element caller,
-      ArgumentsTypes<T> arguments,
-      SideEffects sideEffects,
-      bool inLoop);
-
-  /**
-   * Registers a call to await with an expression of type [argumentType] as
-   * argument.
-   */
-  T registerAwait(ast.Node node, T argumentType);
-
-  /**
-   * Notifies to the inferrer that [analyzedElement] can have return
-   * type [newType]. [currentType] is the type the [InferrerVisitor]
-   * currently found.
-   *
-   * Returns the new type for [analyzedElement].
-   */
-  T addReturnTypeFor(Element analyzedElement, T currentType, T newType);
-
-  /**
-   * Applies [f] to all elements in the universe that match
-   * [selector] and [mask]. If [f] returns false, aborts the iteration.
-   */
-  void forEachElementMatching(
-      Selector selector, TypeMask mask, bool f(Element element)) {
-    Iterable<Element> elements =
-        closedWorld.allFunctions.filter(selector, mask);
-    for (Element e in elements) {
-      if (!f(e.implementation)) return;
-    }
-  }
-
-  GlobalTypeInferenceElementData _dataOf(AstElement element) => inTreeData
-      .putIfAbsent(element, () => new GlobalTypeInferenceElementData());
-
-  /**
-   * Update [sideEffects] with the side effects of [callee] being
-   * called with [selector].
-   */
-  void updateSideEffects(
-      SideEffects sideEffects, Selector selector, Element callee) {
-    if (callee.isField) {
-      if (callee.isInstanceMember) {
-        if (selector.isSetter) {
-          sideEffects.setChangesInstanceProperty();
-        } else if (selector.isGetter) {
-          sideEffects.setDependsOnInstancePropertyStore();
-        } else {
-          sideEffects.setAllSideEffects();
-          sideEffects.setDependsOnSomething();
-        }
-      } else {
-        if (selector.isSetter) {
-          sideEffects.setChangesStaticProperty();
-        } else if (selector.isGetter) {
-          sideEffects.setDependsOnStaticPropertyStore();
-        } else {
-          sideEffects.setAllSideEffects();
-          sideEffects.setDependsOnSomething();
-        }
-      }
-    } else if (callee.isGetter && !selector.isGetter) {
-      sideEffects.setAllSideEffects();
-      sideEffects.setDependsOnSomething();
-    } else {
-      sideEffects.add(closedWorldRefiner.getCurrentlyKnownSideEffects(callee));
-    }
-  }
-
-  /**
-   * Returns the type for [nativeBehavior]. See documentation on
-   * [native.NativeBehavior].
-   */
-  T typeOfNativeBehavior(native.NativeBehavior nativeBehavior) {
-    if (nativeBehavior == null) return types.dynamicType;
-    List typesReturned = nativeBehavior.typesReturned;
-    if (typesReturned.isEmpty) return types.dynamicType;
-    T returnType;
-    for (var type in typesReturned) {
-      T mappedType;
-      if (type == native.SpecialType.JsObject) {
-        mappedType = types.nonNullExact(commonElements.objectClass);
-      } else if (type == commonElements.stringType) {
-        mappedType = types.stringType;
-      } else if (type == commonElements.intType) {
-        mappedType = types.intType;
-      } else if (type == commonElements.numType ||
-          type == commonElements.doubleType) {
-        // Note: the backend double class is specifically for non-integer
-        // doubles, and a native behavior returning 'double' does not guarantee
-        // a non-integer return type, so we return the number type for those.
-        mappedType = types.numType;
-      } else if (type == commonElements.boolType) {
-        mappedType = types.boolType;
-      } else if (type == commonElements.nullType) {
-        mappedType = types.nullType;
-      } else if (type.isVoid) {
-        mappedType = types.nullType;
-      } else if (type.isDynamic) {
-        return types.dynamicType;
-      } else {
-        mappedType = types.nonNullSubtype(type.element);
-      }
-      returnType = types.computeLUB(returnType, mappedType);
-      if (returnType == types.dynamicType) {
-        break;
-      }
-    }
-    return returnType;
-  }
-
-  // TODO(johnniwinther): Pass the [ResolvedAst] instead of [owner].
-  void updateSelectorInTree(
-      AstElement owner, Spannable node, Selector selector, TypeMask mask) {
-    ast.Node astNode = node;
-    GlobalTypeInferenceElementData data = _dataOf(owner);
-    if (astNode.asSendSet() != null) {
-      if (selector.isSetter || selector.isIndexSet) {
-        data.setTypeMask(node, mask);
-      } else if (selector.isGetter || selector.isIndex) {
-        data.setGetterTypeMaskInComplexSendSet(node, mask);
-      } else {
-        assert(selector.isOperator);
-        data.setOperatorTypeMaskInComplexSendSet(node, mask);
-      }
-    } else if (astNode.asSend() != null) {
-      data.setTypeMask(node, mask);
-    } else {
-      assert(astNode.asForIn() != null);
-      if (selector == Selectors.iterator) {
-        data.setIteratorTypeMask(node, mask);
-      } else if (selector == Selectors.current) {
-        data.setCurrentTypeMask(node, mask);
-      } else {
-        assert(selector == Selectors.moveNext);
-        data.setMoveNextTypeMask(node, mask);
-      }
-    }
-  }
-
-  bool isNativeElement(Element element) {
-    return compiler.backend.isNative(element);
-  }
-
-  void analyze(ResolvedAst resolvedAst, ArgumentsTypes arguments);
-
-  bool checkIfExposesThis(Element element) {
-    element = element.implementation;
-    return generativeConstructorsExposingThis.contains(element);
-  }
-
-  void recordExposesThis(Element element, bool exposesThis) {
-    element = element.implementation;
-    if (exposesThis) {
-      generativeConstructorsExposingThis.add(element);
-    }
-  }
-}
+import 'type_graph_nodes.dart';
+import 'type_system.dart';
 
 /// [SimpleTypeInferrerVisitor] can be thought of as a type-inference graph
 /// builder for a single element.
@@ -319,35 +41,66 @@
 ///
 /// This visitor is parameterized by an [InferenceEngine], which internally
 /// decides how to represent inference nodes.
-class SimpleTypeInferrerVisitor<T>
-    extends InferrerVisitor<T, InferrerEngine<T, TypeSystem<T>>> {
-  T returnType;
+class SimpleTypeInferrerVisitor extends ast.Visitor<TypeInformation>
+    with
+        SemanticSendResolvedMixin<TypeInformation, dynamic>,
+        CompoundBulkMixin<TypeInformation, dynamic>,
+        SetIfNullBulkMixin<TypeInformation, dynamic>,
+        PrefixBulkMixin<TypeInformation, dynamic>,
+        PostfixBulkMixin<TypeInformation, dynamic>,
+        ErrorBulkMixin<TypeInformation, dynamic>,
+        NewBulkMixin<TypeInformation, dynamic>,
+        SetBulkMixin<TypeInformation, dynamic>
+    implements SemanticSendVisitor<TypeInformation, dynamic> {
+  final Compiler compiler;
+  final AstElement analyzedElement;
+  final ResolvedAst resolvedAst;
+  final TypeSystem types;
+  final Map<JumpTarget, List<LocalsHandler>> breaksFor =
+      new Map<JumpTarget, List<LocalsHandler>>();
+  final Map<JumpTarget, List<LocalsHandler>> continuesFor =
+      new Map<JumpTarget, List<LocalsHandler>>();
+  LocalsHandler locals;
+  final List<TypeInformation> cascadeReceiverStack =
+      new List<TypeInformation>();
+
+  TypeInformation returnType;
   bool visitingInitializers = false;
   bool isConstructorRedirect = false;
   bool seenSuperConstructorCall = false;
   SideEffects sideEffects = new SideEffects.empty();
   final Element outermostElement;
-  final InferrerEngine<T, TypeSystem<T>> inferrer;
+  final InferrerEngine inferrer;
   final Setlet<Entity> capturedVariables = new Setlet<Entity>();
   final GlobalTypeInferenceElementData inTreeData;
 
   SimpleTypeInferrerVisitor.internal(
       AstElement analyzedElement,
-      ResolvedAst resolvedAst,
+      this.resolvedAst,
       this.outermostElement,
-      inferrer,
-      compiler,
-      locals)
-      : super(analyzedElement, resolvedAst, inferrer, inferrer.types, compiler,
-            locals),
+      InferrerEngine inferrer,
+      this.compiler,
+      this.locals)
+      : this.analyzedElement = analyzedElement,
         this.inferrer = inferrer,
-        this.inTreeData = inferrer._dataOf(analyzedElement) {
+        this.types = inferrer.types,
+        this.inTreeData = inferrer.dataOf(analyzedElement) {
     assert(outermostElement != null);
+    if (locals != null) return;
+    ast.Node node;
+    if (resolvedAst.kind == ResolvedAstKind.PARSED) {
+      node = resolvedAst.node;
+    }
+    FieldInitializationScope fieldScope =
+        analyzedElement.isGenerativeConstructor
+            ? new FieldInitializationScope(types)
+            : null;
+    locals =
+        new LocalsHandler(inferrer, types, compiler.options, node, fieldScope);
   }
 
   SimpleTypeInferrerVisitor(Element element, ResolvedAst resolvedAst,
-      Compiler compiler, InferrerEngine<T, TypeSystem<T>> inferrer,
-      [LocalsHandler<T> handler])
+      Compiler compiler, InferrerEngine inferrer, [LocalsHandler handler])
       : this.internal(
             element,
             resolvedAst,
@@ -356,6 +109,771 @@
             compiler,
             handler);
 
+  TreeElements get elements => resolvedAst.elements;
+
+  bool accumulateIsChecks = false;
+  bool conditionIsSimple = false;
+  List<ast.Send> isChecks;
+  int loopLevel = 0;
+
+  bool get inLoop => loopLevel > 0;
+  bool get isThisExposed {
+    return analyzedElement.isGenerativeConstructor
+        ? locals.fieldScope.isThisExposed
+        : true;
+  }
+
+  void set isThisExposed(value) {
+    if (analyzedElement.isGenerativeConstructor) {
+      locals.fieldScope.isThisExposed = value;
+    }
+  }
+
+  DiagnosticReporter get reporter => compiler.reporter;
+
+  ClosedWorld get closedWorld => inferrer.closedWorld;
+
+  @override
+  SemanticSendVisitor get sendVisitor => this;
+
+  @override
+  TypeInformation apply(ast.Node node, _) => visit(node);
+
+  TypeInformation visitAssert(ast.Assert node) {
+    // Avoid pollution from assert statement unless enabled.
+    if (!compiler.options.enableUserAssertions) {
+      return null;
+    }
+    List<ast.Send> tests = <ast.Send>[];
+    bool simpleCondition = handleCondition(node.condition, tests);
+    LocalsHandler saved = locals;
+    locals = new LocalsHandler.from(locals, node);
+    updateIsChecks(tests, usePositive: true);
+
+    LocalsHandler thenLocals = locals;
+    locals = new LocalsHandler.from(saved, node);
+    if (simpleCondition) updateIsChecks(tests, usePositive: false);
+    visit(node.message);
+    locals.seenReturnOrThrow = true;
+    saved.mergeDiamondFlow(thenLocals, locals);
+    locals = saved;
+    return null;
+  }
+
+  @override
+  TypeInformation bulkHandleSet(ast.SendSet node, _) {
+    return handleSendSet(node);
+  }
+
+  @override
+  TypeInformation bulkHandleCompound(ast.SendSet node, _) {
+    return handleSendSet(node);
+  }
+
+  @override
+  TypeInformation bulkHandleSetIfNull(ast.SendSet node, _) {
+    return handleSendSet(node);
+  }
+
+  @override
+  TypeInformation bulkHandlePrefix(ast.SendSet node, _) {
+    return handleSendSet(node);
+  }
+
+  @override
+  TypeInformation bulkHandlePostfix(ast.SendSet node, _) {
+    return handleSendSet(node);
+  }
+
+  @override
+  TypeInformation bulkHandleError(ast.Node node, ErroneousElement error, _) {
+    return types.dynamicType;
+  }
+
+  TypeInformation visitNode(ast.Node node) {
+    return node.visitChildren(this);
+  }
+
+  TypeInformation visit(ast.Node node) {
+    return node == null ? null : node.accept(this);
+  }
+
+  TypeInformation visitLiteralString(ast.LiteralString node) {
+    return types.stringLiteralType(node.dartString);
+  }
+
+  TypeInformation visitStringJuxtaposition(ast.StringJuxtaposition node) {
+    node.visitChildren(this);
+    return types.stringType;
+  }
+
+  TypeInformation visitLiteralBool(ast.LiteralBool node) {
+    return types.boolLiteralType(node);
+  }
+
+  TypeInformation visitLiteralDouble(ast.LiteralDouble node) {
+    ConstantSystem constantSystem = compiler.backend.constantSystem;
+    // The JavaScript backend may turn this literal into an integer at
+    // runtime.
+    return types.getConcreteTypeFor(
+        computeTypeMask(closedWorld, constantSystem.createDouble(node.value)));
+  }
+
+  TypeInformation visitLiteralInt(ast.LiteralInt node) {
+    ConstantSystem constantSystem = compiler.backend.constantSystem;
+    // The JavaScript backend may turn this literal into a double at
+    // runtime.
+    return types.getConcreteTypeFor(
+        computeTypeMask(closedWorld, constantSystem.createInt(node.value)));
+  }
+
+  TypeInformation visitLiteralNull(ast.LiteralNull node) {
+    return types.nullType;
+  }
+
+  TypeInformation visitLiteralSymbol(ast.LiteralSymbol node) {
+    // TODO(kasperl): We should be able to tell that the type of a literal
+    // symbol is always a non-null exact symbol implementation -- not just
+    // any non-null subtype of the symbol interface.
+    return types.nonNullSubtype(closedWorld.commonElements.symbolClass);
+  }
+
+  @override
+  void previsitDeferredAccess(ast.Send node, PrefixElement prefix, _) {
+    // Deferred access does not affect inference.
+  }
+
+  TypeInformation handleTypeLiteralGet() {
+    return types.typeType;
+  }
+
+  @override
+  TypeInformation bulkHandleNode(ast.Node node, String message, _) {
+    return internalError(node, message.replaceAll('#', '$node'));
+  }
+
+  @override
+  TypeInformation visitConstantGet(
+      ast.Send node, ConstantExpression constant, _) {
+    return bulkHandleNode(node, "Constant read `#` unhandled.", _);
+  }
+
+  @override
+  TypeInformation visitConstantInvoke(
+      ast.Send node,
+      ConstantExpression constant,
+      ast.NodeList arguments,
+      CallStructure callStructure,
+      _) {
+    return bulkHandleNode(node, "Constant invoke `#` unhandled.", _);
+  }
+
+  TypeInformation visitClassTypeLiteralGet(
+      ast.Send node, ConstantExpression constant, _) {
+    return handleTypeLiteralGet();
+  }
+
+  TypeInformation visitClassTypeLiteralInvoke(
+      ast.Send node,
+      ConstantExpression constant,
+      ast.NodeList arguments,
+      CallStructure callStructure,
+      _) {
+    return handleTypeLiteralInvoke(arguments);
+  }
+
+  TypeInformation visitTypedefTypeLiteralGet(
+      ast.Send node, ConstantExpression constant, _) {
+    return handleTypeLiteralGet();
+  }
+
+  TypeInformation visitTypedefTypeLiteralInvoke(
+      ast.Send node,
+      ConstantExpression constant,
+      ast.NodeList arguments,
+      CallStructure callStructure,
+      _) {
+    return handleTypeLiteralInvoke(arguments);
+  }
+
+  TypeInformation visitTypeVariableTypeLiteralGet(
+      ast.Send node, TypeVariableElement element, _) {
+    return handleTypeLiteralGet();
+  }
+
+  TypeInformation visitTypeVariableTypeLiteralInvoke(
+      ast.Send node,
+      TypeVariableElement element,
+      ast.NodeList arguments,
+      CallStructure callStructure,
+      _) {
+    return handleTypeLiteralInvoke(arguments);
+  }
+
+  TypeInformation visitDynamicTypeLiteralGet(
+      ast.Send node, ConstantExpression constant, _) {
+    return handleTypeLiteralGet();
+  }
+
+  TypeInformation visitDynamicTypeLiteralInvoke(
+      ast.Send node,
+      ConstantExpression constant,
+      ast.NodeList arguments,
+      CallStructure callStructure,
+      _) {
+    return handleTypeLiteralInvoke(arguments);
+  }
+
+  TypeInformation _thisType;
+  TypeInformation get thisType {
+    if (_thisType != null) return _thisType;
+    ClassElement cls = outermostElement.enclosingClass;
+    if (closedWorld.isUsedAsMixin(cls)) {
+      return _thisType = types.nonNullSubtype(cls);
+    } else {
+      return _thisType = types.nonNullSubclass(cls);
+    }
+  }
+
+  @override
+  TypeInformation visitThisGet(ast.Identifier node, _) {
+    return thisType;
+  }
+
+  TypeInformation visitIdentifier(ast.Identifier node) {
+    if (node.isThis()) {
+      return thisType;
+    } else if (node.isSuper()) {
+      return internalError(node, 'Unexpected expression $node.');
+    } else {
+      Element element = elements[node];
+      if (Elements.isLocal(element)) {
+        LocalElement local = element;
+        return locals.use(local);
+      }
+      return null;
+    }
+  }
+
+  void potentiallyAddIsCheck(ast.Send node) {
+    if (!accumulateIsChecks) return;
+    if (!Elements.isLocal(elements[node.receiver])) return;
+    isChecks.add(node);
+  }
+
+  void potentiallyAddNullCheck(ast.Send node, ast.Node receiver) {
+    if (!accumulateIsChecks) return;
+    if (!Elements.isLocal(elements[receiver])) return;
+    isChecks.add(node);
+  }
+
+  void updateIsChecks(List<ast.Node> tests, {bool usePositive}) {
+    void narrow(Element element, ResolutionDartType type, ast.Node node) {
+      if (element is LocalElement) {
+        TypeInformation existing = locals.use(element);
+        TypeInformation newType =
+            types.narrowType(existing, type, isNullable: false);
+        locals.update(element, newType, node);
+      }
+    }
+
+    if (tests == null) return;
+    for (ast.Send node in tests) {
+      if (node.isTypeTest) {
+        if (node.isIsNotCheck) {
+          if (usePositive) continue;
+        } else {
+          if (!usePositive) continue;
+        }
+        ResolutionDartType type =
+            elements.getType(node.typeAnnotationFromIsCheckOrCast);
+        narrow(elements[node.receiver], type, node);
+      } else {
+        Element receiverElement = elements[node.receiver];
+        Element argumentElement = elements[node.arguments.first];
+        String operator = node.selector.asOperator().source;
+        if ((operator == '==' && usePositive) ||
+            (operator == '!=' && !usePositive)) {
+          // Type the elements as null.
+          if (Elements.isLocal(receiverElement)) {
+            locals.update(receiverElement, types.nullType, node);
+          }
+          if (Elements.isLocal(argumentElement)) {
+            locals.update(argumentElement, types.nullType, node);
+          }
+        } else {
+          // Narrow the elements to a non-null type.
+          ResolutionDartType objectType = closedWorld.commonElements.objectType;
+          if (Elements.isLocal(receiverElement)) {
+            narrow(receiverElement, objectType, node);
+          }
+          if (Elements.isLocal(argumentElement)) {
+            narrow(argumentElement, objectType, node);
+          }
+        }
+      }
+    }
+  }
+
+  @override
+  TypeInformation visitIndex(
+      ast.Send node, ast.Node receiver, ast.Node index, _) {
+    return handleDynamicInvoke(node);
+  }
+
+  @override
+  TypeInformation visitDynamicPropertyInvoke(ast.Send node, ast.Node receiver,
+      ast.NodeList arguments, Selector selector, _) {
+    return handleDynamicInvoke(node);
+  }
+
+  @override
+  TypeInformation visitIfNotNullDynamicPropertyInvoke(ast.Send node,
+      ast.Node receiver, ast.NodeList arguments, Selector selector, _) {
+    return handleDynamicInvoke(node);
+  }
+
+  @override
+  TypeInformation visitThisPropertyInvoke(
+      ast.Send node, ast.NodeList arguments, Selector selector, _) {
+    return handleDynamicInvoke(node);
+  }
+
+  @override
+  TypeInformation visitIfNull(ast.Send node, ast.Node left, ast.Node right, _) {
+    TypeInformation firstType = visit(left);
+    TypeInformation secondType = visit(right);
+    return types.allocateDiamondPhi(types.narrowNotNull(firstType), secondType);
+  }
+
+  @override
+  TypeInformation visitLogicalAnd(
+      ast.Send node, ast.Node left, ast.Node right, _) {
+    conditionIsSimple = false;
+    bool oldAccumulateIsChecks = accumulateIsChecks;
+    List<ast.Send> oldIsChecks = isChecks;
+    if (!accumulateIsChecks) {
+      accumulateIsChecks = true;
+      isChecks = <ast.Send>[];
+    }
+    visit(left);
+    LocalsHandler saved = locals;
+    locals = new LocalsHandler.from(locals, node);
+    updateIsChecks(isChecks, usePositive: true);
+    LocalsHandler narrowed;
+    if (oldAccumulateIsChecks) {
+      narrowed = new LocalsHandler.topLevelCopyOf(locals);
+    } else {
+      accumulateIsChecks = false;
+      isChecks = oldIsChecks;
+    }
+    visit(right);
+    if (oldAccumulateIsChecks) {
+      bool invalidatedInRightHandSide(ast.Send test) {
+        Element receiver = elements[test.receiver];
+        if (receiver is LocalElement) {
+          return narrowed.locals[receiver] != locals.locals[receiver];
+        }
+        return false;
+      }
+
+      isChecks.removeWhere(invalidatedInRightHandSide);
+    }
+    saved.mergeDiamondFlow(locals, null);
+    locals = saved;
+    return types.boolType;
+  }
+
+  @override
+  TypeInformation visitLogicalOr(
+      ast.Send node, ast.Node left, ast.Node right, _) {
+    conditionIsSimple = false;
+    List<ast.Send> tests = <ast.Send>[];
+    bool isSimple = handleCondition(left, tests);
+    LocalsHandler saved = locals;
+    locals = new LocalsHandler.from(locals, node);
+    if (isSimple) updateIsChecks(tests, usePositive: false);
+    bool oldAccumulateIsChecks = accumulateIsChecks;
+    accumulateIsChecks = false;
+    visit(right);
+    accumulateIsChecks = oldAccumulateIsChecks;
+    saved.mergeDiamondFlow(locals, null);
+    locals = saved;
+    return types.boolType;
+  }
+
+  @override
+  TypeInformation visitNot(ast.Send node, ast.Node expression, _) {
+    bool oldAccumulateIsChecks = accumulateIsChecks;
+    accumulateIsChecks = false;
+    visit(expression);
+    accumulateIsChecks = oldAccumulateIsChecks;
+    return types.boolType;
+  }
+
+  @override
+  TypeInformation visitIs(
+      ast.Send node, ast.Node expression, ResolutionDartType type, _) {
+    potentiallyAddIsCheck(node);
+    visit(expression);
+    return types.boolType;
+  }
+
+  @override
+  TypeInformation visitIsNot(
+      ast.Send node, ast.Node expression, ResolutionDartType type, _) {
+    potentiallyAddIsCheck(node);
+    visit(expression);
+    return types.boolType;
+  }
+
+  @override
+  TypeInformation visitAs(
+      ast.Send node, ast.Node expression, ResolutionDartType type, _) {
+    TypeInformation receiverType = visit(expression);
+    return types.narrowType(receiverType, type);
+  }
+
+  @override
+  TypeInformation visitUnary(
+      ast.Send node, op.UnaryOperator operator, ast.Node expression, _) {
+    return handleDynamicInvoke(node);
+  }
+
+  @override
+  TypeInformation visitNotEquals(
+      ast.Send node, ast.Node left, ast.Node right, _) {
+    handleDynamicInvoke(node);
+    return types.boolType;
+  }
+
+  @override
+  TypeInformation visitEquals(ast.Send node, ast.Node left, ast.Node right, _) {
+    return handleDynamicInvoke(node);
+  }
+
+  @override
+  TypeInformation visitBinary(ast.Send node, ast.Node left,
+      op.BinaryOperator operator, ast.Node right, _) {
+    return handleDynamicInvoke(node);
+  }
+
+  // Because some nodes just visit their children, we may end up
+  // visiting a type annotation, that may contain a send in case of a
+  // prefixed type. Therefore we explicitly visit the type annotation
+  // to avoid confusing the [ResolvedVisitor].
+  visitTypeAnnotation(ast.TypeAnnotation node) {}
+
+  TypeInformation visitConditional(ast.Conditional node) {
+    List<ast.Send> tests = <ast.Send>[];
+    bool simpleCondition = handleCondition(node.condition, tests);
+    LocalsHandler saved = locals;
+    locals = new LocalsHandler.from(locals, node);
+    updateIsChecks(tests, usePositive: true);
+    TypeInformation firstType = visit(node.thenExpression);
+    LocalsHandler thenLocals = locals;
+    locals = new LocalsHandler.from(saved, node);
+    if (simpleCondition) updateIsChecks(tests, usePositive: false);
+    TypeInformation secondType = visit(node.elseExpression);
+    saved.mergeDiamondFlow(thenLocals, locals);
+    locals = saved;
+    TypeInformation type = types.allocateDiamondPhi(firstType, secondType);
+    return type;
+  }
+
+  TypeInformation visitVariableDefinitions(ast.VariableDefinitions node) {
+    for (Link<ast.Node> link = node.definitions.nodes;
+        !link.isEmpty;
+        link = link.tail) {
+      ast.Node definition = link.head;
+      if (definition is ast.Identifier) {
+        locals.update(elements[definition], types.nullType, node);
+      } else {
+        assert(definition.asSendSet() != null);
+        handleSendSet(definition);
+      }
+    }
+    return null;
+  }
+
+  bool handleCondition(ast.Node node, List<ast.Send> tests) {
+    bool oldConditionIsSimple = conditionIsSimple;
+    bool oldAccumulateIsChecks = accumulateIsChecks;
+    List<ast.Send> oldIsChecks = isChecks;
+    accumulateIsChecks = true;
+    conditionIsSimple = true;
+    isChecks = tests;
+    visit(node);
+    bool simpleCondition = conditionIsSimple;
+    accumulateIsChecks = oldAccumulateIsChecks;
+    isChecks = oldIsChecks;
+    conditionIsSimple = oldConditionIsSimple;
+    return simpleCondition;
+  }
+
+  TypeInformation visitIf(ast.If node) {
+    List<ast.Send> tests = <ast.Send>[];
+    bool simpleCondition = handleCondition(node.condition, tests);
+    LocalsHandler saved = locals;
+    locals = new LocalsHandler.from(locals, node);
+    updateIsChecks(tests, usePositive: true);
+    visit(node.thenPart);
+    LocalsHandler thenLocals = locals;
+    locals = new LocalsHandler.from(saved, node);
+    if (simpleCondition) updateIsChecks(tests, usePositive: false);
+    visit(node.elsePart);
+    saved.mergeDiamondFlow(thenLocals, locals);
+    locals = saved;
+    return null;
+  }
+
+  void setupBreaksAndContinues(JumpTarget element) {
+    if (element == null) return;
+    if (element.isContinueTarget) continuesFor[element] = <LocalsHandler>[];
+    if (element.isBreakTarget) breaksFor[element] = <LocalsHandler>[];
+  }
+
+  void clearBreaksAndContinues(JumpTarget element) {
+    continuesFor.remove(element);
+    breaksFor.remove(element);
+  }
+
+  List<LocalsHandler> getBreaks(JumpTarget element) {
+    List<LocalsHandler> list = <LocalsHandler>[locals];
+    if (element == null) return list;
+    if (!element.isBreakTarget) return list;
+    return list..addAll(breaksFor[element]);
+  }
+
+  List<LocalsHandler> getLoopBackEdges(JumpTarget element) {
+    List<LocalsHandler> list = <LocalsHandler>[locals];
+    if (element == null) return list;
+    if (!element.isContinueTarget) return list;
+    return list..addAll(continuesFor[element]);
+  }
+
+  TypeInformation handleLoop(ast.Node node, void logic()) {
+    loopLevel++;
+    bool changed = false;
+    JumpTarget target = elements.getTargetDefinition(node);
+    LocalsHandler saved = locals;
+    saved.startLoop(node);
+    do {
+      // Setup (and clear in case of multiple iterations of the loop)
+      // the lists of breaks and continues seen in the loop.
+      setupBreaksAndContinues(target);
+      locals = new LocalsHandler.from(saved, node);
+      logic();
+      changed = saved.mergeAll(getLoopBackEdges(target));
+    } while (changed);
+    loopLevel--;
+    saved.endLoop(node);
+    bool keepOwnLocals = node.asDoWhile() == null;
+    saved.mergeAfterBreaks(getBreaks(target), keepOwnLocals: keepOwnLocals);
+    locals = saved;
+    clearBreaksAndContinues(target);
+    return null;
+  }
+
+  TypeInformation visitWhile(ast.While node) {
+    return handleLoop(node, () {
+      List<ast.Send> tests = <ast.Send>[];
+      handleCondition(node.condition, tests);
+      updateIsChecks(tests, usePositive: true);
+      visit(node.body);
+    });
+  }
+
+  TypeInformation visitDoWhile(ast.DoWhile node) {
+    return handleLoop(node, () {
+      visit(node.body);
+      List<ast.Send> tests = <ast.Send>[];
+      handleCondition(node.condition, tests);
+      updateIsChecks(tests, usePositive: true);
+    });
+  }
+
+  TypeInformation visitFor(ast.For node) {
+    visit(node.initializer);
+    return handleLoop(node, () {
+      List<ast.Send> tests = <ast.Send>[];
+      handleCondition(node.condition, tests);
+      updateIsChecks(tests, usePositive: true);
+      visit(node.body);
+      visit(node.update);
+    });
+  }
+
+  TypeInformation visitTryStatement(ast.TryStatement node) {
+    LocalsHandler saved = locals;
+    locals = new LocalsHandler.from(locals, node, useOtherTryBlock: false);
+    visit(node.tryBlock);
+    saved.mergeDiamondFlow(locals, null);
+    locals = saved;
+    for (ast.Node catchBlock in node.catchBlocks) {
+      saved = locals;
+      locals = new LocalsHandler.from(locals, catchBlock);
+      visit(catchBlock);
+      saved.mergeDiamondFlow(locals, null);
+      locals = saved;
+    }
+    visit(node.finallyBlock);
+    return null;
+  }
+
+  TypeInformation visitThrow(ast.Throw node) {
+    node.visitChildren(this);
+    locals.seenReturnOrThrow = true;
+    return types.nonNullEmpty();
+  }
+
+  TypeInformation visitCatchBlock(ast.CatchBlock node) {
+    ast.Node exception = node.exception;
+    if (exception != null) {
+      ResolutionDartType type = elements.getType(node.type);
+      TypeInformation mask =
+          type == null || type.treatAsDynamic || type.isTypeVariable
+              ? types.dynamicType
+              : types.nonNullSubtype(type.element);
+      locals.update(elements[exception], mask, node);
+    }
+    ast.Node trace = node.trace;
+    if (trace != null) {
+      locals.update(elements[trace], types.dynamicType, node);
+    }
+    visit(node.block);
+    return null;
+  }
+
+  TypeInformation visitParenthesizedExpression(
+      ast.ParenthesizedExpression node) {
+    return visit(node.expression);
+  }
+
+  TypeInformation visitBlock(ast.Block node) {
+    if (node.statements != null) {
+      for (ast.Node statement in node.statements) {
+        visit(statement);
+        if (locals.aborts) break;
+      }
+    }
+    return null;
+  }
+
+  TypeInformation visitLabeledStatement(ast.LabeledStatement node) {
+    ast.Statement body = node.statement;
+    if (body is ast.Loop ||
+        body is ast.SwitchStatement ||
+        Elements.isUnusedLabel(node, elements)) {
+      // Loops and switches handle their own labels.
+      visit(body);
+    } else {
+      JumpTarget targetElement = elements.getTargetDefinition(body);
+      setupBreaksAndContinues(targetElement);
+      visit(body);
+      locals.mergeAfterBreaks(getBreaks(targetElement));
+      clearBreaksAndContinues(targetElement);
+    }
+    return null;
+  }
+
+  TypeInformation visitBreakStatement(ast.BreakStatement node) {
+    JumpTarget target = elements.getTargetOf(node);
+    locals.seenBreakOrContinue = true;
+    // Do a deep-copy of the locals, because the code following the
+    // break will change them.
+    breaksFor[target].add(new LocalsHandler.deepCopyOf(locals));
+    return null;
+  }
+
+  TypeInformation visitContinueStatement(ast.ContinueStatement node) {
+    JumpTarget target = elements.getTargetOf(node);
+    locals.seenBreakOrContinue = true;
+    // Do a deep-copy of the locals, because the code following the
+    // continue will change them.
+    continuesFor[target].add(new LocalsHandler.deepCopyOf(locals));
+    return null;
+  }
+
+  internalError(Spannable node, String reason) {
+    reporter.internalError(node, reason);
+  }
+
+  TypeInformation visitSwitchStatement(ast.SwitchStatement node) {
+    visit(node.parenthesizedExpression);
+
+    setupBreaksAndContinues(elements.getTargetDefinition(node));
+    if (Elements.switchStatementHasContinue(node, elements)) {
+      void forEachLabeledCase(void action(JumpTarget target)) {
+        for (ast.SwitchCase switchCase in node.cases) {
+          for (ast.Node labelOrCase in switchCase.labelsAndCases) {
+            if (labelOrCase.asLabel() == null) continue;
+            LabelDefinition labelElement =
+                elements.getLabelDefinition(labelOrCase);
+            if (labelElement != null) {
+              action(labelElement.target);
+            }
+          }
+        }
+      }
+
+      forEachLabeledCase((JumpTarget target) {
+        setupBreaksAndContinues(target);
+      });
+
+      // If the switch statement has a continue, we conservatively
+      // visit all cases and update [locals] until we have reached a
+      // fixed point.
+      bool changed;
+      locals.startLoop(node);
+      do {
+        changed = false;
+        for (ast.Node switchCase in node.cases) {
+          LocalsHandler saved = locals;
+          locals = new LocalsHandler.from(locals, switchCase);
+          visit(switchCase);
+          changed = saved.mergeAll([locals]) || changed;
+          locals = saved;
+        }
+      } while (changed);
+      locals.endLoop(node);
+
+      forEachLabeledCase((JumpTarget target) {
+        clearBreaksAndContinues(target);
+      });
+    } else {
+      LocalsHandler saved = locals;
+      List<LocalsHandler> localsToMerge = <LocalsHandler>[];
+      bool hasDefaultCase = false;
+
+      for (ast.SwitchCase switchCase in node.cases) {
+        if (switchCase.isDefaultCase) {
+          hasDefaultCase = true;
+        }
+        locals = new LocalsHandler.from(saved, switchCase);
+        visit(switchCase);
+        localsToMerge.add(locals);
+      }
+      saved.mergeAfterBreaks(localsToMerge, keepOwnLocals: !hasDefaultCase);
+      locals = saved;
+    }
+    clearBreaksAndContinues(elements.getTargetDefinition(node));
+    return null;
+  }
+
+  TypeInformation visitCascadeReceiver(ast.CascadeReceiver node) {
+    var type = visit(node.expression);
+    cascadeReceiverStack.add(type);
+    return type;
+  }
+
+  TypeInformation visitCascade(ast.Cascade node) {
+    // Ignore the result of the cascade send and return the type of the cascade
+    // receiver.
+    visit(node.expression);
+    return cascadeReceiverStack.removeLast();
+  }
+
   void analyzeSuperConstructorCall(
       AstElement target, ArgumentsTypes arguments) {
     ResolvedAst resolvedAst = target.resolvedAst;
@@ -363,7 +881,7 @@
     isThisExposed = isThisExposed || inferrer.checkIfExposesThis(target);
   }
 
-  T run() {
+  TypeInformation run() {
     var node;
     if (resolvedAst.kind == ResolvedAstKind.PARSED) {
       node = resolvedAst.node;
@@ -411,7 +929,7 @@
         visitor = new SimpleTypeInferrerVisitor(element.functionDeclaration,
             element.functionDeclaration.resolvedAst, compiler, inferrer);
       }
-      T type =
+      TypeInformation type =
           (defaultValue == null) ? types.nullType : visitor.visit(defaultValue);
       inferrer.setDefaultTypeOfParameter(element, type);
     });
@@ -425,7 +943,7 @@
     if (analyzedElement.isGenerativeConstructor) {
       isThisExposed = false;
       signature.forEachParameter((ParameterElement element) {
-        T parameterType = inferrer.typeOfElement(element);
+        TypeInformation parameterType = inferrer.typeOfElement(element);
         if (element.isInitializingFormal) {
           InitializingFormalElement initializingFormal = element;
           if (initializingFormal.fieldElement.isFinal) {
@@ -477,10 +995,10 @@
       }
       if (!isConstructorRedirect) {
         // Iterate over all instance fields, and give a null type to
-        // fields that we haven't initialized for sure.
+        // fields that we haven'TypeInformation initialized for sure.
         cls.forEachInstanceField((_, FieldElement field) {
           if (field.isFinal) return;
-          T type = locals.fieldScope.readField(field);
+          TypeInformation type = locals.fieldScope.readField(field);
           ResolvedAst resolvedAst = field.resolvedAst;
           if (type == null && resolvedAst.body == null) {
             inferrer.recordTypeOfNonFinalField(
@@ -512,7 +1030,7 @@
                 ? types.nonNullEmpty() // Body always throws.
                 : types.nullType;
           } else if (!locals.seenReturnOrThrow) {
-            // We haven't seen returns on all branches. So the method may
+            // We haven'TypeInformation seen returns on all branches. So the method may
             // also return null.
             returnType = inferrer.addReturnTypeFor(
                 analyzedElement, returnType, types.nullType);
@@ -545,19 +1063,19 @@
     return returnType;
   }
 
-  T visitFunctionExpression(ast.FunctionExpression node) {
+  TypeInformation visitFunctionExpression(ast.FunctionExpression node) {
     // We loose track of [this] in closures (see issue 20840). To be on
     // the safe side, we mark [this] as exposed here. We could do better by
     // analyzing the closure.
     // TODO(herhut): Analyze whether closure exposes this.
     isThisExposed = true;
     LocalFunctionElement element = elements.getFunctionDefinition(node);
-    // We don't put the closure in the work queue of the
+    // We don'TypeInformation put the closure in the work queue of the
     // inferrer, because it will share information with its enclosing
     // method, like for example the types of local variables.
     LocalsHandler closureLocals =
-        new LocalsHandler<T>.from(locals, node, useOtherTryBlock: false);
-    SimpleTypeInferrerVisitor visitor = new SimpleTypeInferrerVisitor<T>(
+        new LocalsHandler.from(locals, node, useOtherTryBlock: false);
+    SimpleTypeInferrerVisitor visitor = new SimpleTypeInferrerVisitor(
         element, element.resolvedAst, compiler, inferrer, closureLocals);
     visitor.run();
     inferrer.recordReturnType(element, visitor.returnType);
@@ -584,10 +1102,11 @@
     });
   }
 
-  T visitFunctionDeclaration(ast.FunctionDeclaration node) {
+  TypeInformation visitFunctionDeclaration(ast.FunctionDeclaration node) {
     LocalFunctionElement element =
         elements.getFunctionDefinition(node.function);
-    T type = inferrer.concreteTypes.putIfAbsent(node.function, () {
+    TypeInformation type =
+        inferrer.concreteTypes.putIfAbsent(node.function, () {
       return types.allocateClosure(node.function, element);
     });
     locals.update(element, type, node);
@@ -595,7 +1114,7 @@
     return type;
   }
 
-  T visitStringInterpolation(ast.StringInterpolation node) {
+  TypeInformation visitStringInterpolation(ast.StringInterpolation node) {
     // Interpolation could have any effects since it could call any toString()
     // method.
     // TODO(sra): This could be modelled by a call to toString() but with a
@@ -605,17 +1124,18 @@
     // to have all effects.  Effect annotations on JS code would be needed to
     // get the benefit.
     sideEffects.setAllSideEffects();
-    return super.visitStringInterpolation(node);
+    node.visitChildren(this);
+    return types.stringType;
   }
 
-  T visitLiteralList(ast.LiteralList node) {
-    // We only set the type once. We don't need to re-visit the children
+  TypeInformation visitLiteralList(ast.LiteralList node) {
+    // We only set the type once. We don'TypeInformation need to re-visit the children
     // when re-analyzing the node.
     return inferrer.concreteTypes.putIfAbsent(node, () {
-      T elementType;
+      TypeInformation elementType;
       int length = 0;
       for (ast.Node element in node.elements.nodes) {
-        T type = visit(element);
+        TypeInformation type = visit(element);
         elementType = elementType == null
             ? types.allocatePhi(null, null, type)
             : types.addPhiInput(null, elementType, type);
@@ -624,25 +1144,25 @@
       elementType = elementType == null
           ? types.nonNullEmpty()
           : types.simplifyPhi(null, null, elementType);
-      T containerType =
+      TypeInformation containerType =
           node.isConst ? types.constListType : types.growableListType;
       return types.allocateList(
           containerType, node, outermostElement, elementType, length);
     });
   }
 
-  T visitLiteralMap(ast.LiteralMap node) {
+  TypeInformation visitLiteralMap(ast.LiteralMap node) {
     return inferrer.concreteTypes.putIfAbsent(node, () {
       ast.NodeList entries = node.entries;
-      List<T> keyTypes = [];
-      List<T> valueTypes = [];
+      List keyTypes = [];
+      List valueTypes = [];
 
       for (ast.LiteralMapEntry entry in entries) {
         keyTypes.add(visit(entry.key));
         valueTypes.add(visit(entry.value));
       }
 
-      T type = node.isConst ? types.constMapType : types.mapType;
+      TypeInformation type = node.isConst ? types.constMapType : types.mapType;
       return types.allocateMap(
           type, node, outermostElement, keyTypes, valueTypes);
     });
@@ -693,7 +1213,7 @@
   }
 
   @override
-  T handleSendSet(ast.SendSet node) {
+  TypeInformation handleSendSet(ast.SendSet node) {
     Element element = elements[node];
     if (!Elements.isUnresolved(element) && element.impliesType) {
       node.visitChildren(this);
@@ -709,7 +1229,7 @@
     String op = node.assignmentOperator.source;
     bool isIncrementOrDecrement = op == '++' || op == '--';
 
-    T receiverType;
+    TypeInformation receiverType;
     bool isCallOnThis = false;
     if (node.receiver == null) {
       if (treatAsInstanceMember(element)) {
@@ -727,7 +1247,7 @@
       isCallOnThis = isThisOrSuper(node.receiver);
     }
 
-    T rhsType;
+    TypeInformation rhsType;
 
     if (isIncrementOrDecrement) {
       rhsType = types.uint31Type;
@@ -763,8 +1283,8 @@
           receiverType, rhsType, node.arguments.head);
     } else {
       // [foo ??= bar], [: foo++ :] or [: foo += 1 :].
-      T getterType;
-      T newType;
+      TypeInformation getterType;
+      TypeInformation newType;
 
       if (Elements.isMalformed(element)) return types.dynamicType;
 
@@ -791,17 +1311,17 @@
         Selector operatorSelector =
             elements.getOperatorSelectorInComplexSendSet(node);
         newType = handleDynamicSend(node, operatorSelector, operatorMask,
-            getterType, new ArgumentsTypes<T>([rhsType], null));
+            getterType, new ArgumentsTypes([rhsType], null));
       }
 
       if (Elements.isStaticOrTopLevelField(element)) {
         handleStaticSend(node, setterSelector, setterMask, element,
-            new ArgumentsTypes<T>([newType], null));
+            new ArgumentsTypes([newType], null));
       } else if (Elements.isUnresolved(element) ||
           element.isSetter ||
           element.isField) {
         handleDynamicSend(node, setterSelector, setterMask, receiverType,
-            new ArgumentsTypes<T>([newType], null));
+            new ArgumentsTypes([newType], null));
       } else if (element.isLocal) {
         locals.update(element, newType, node);
       }
@@ -811,8 +1331,11 @@
   }
 
   /// Handle compound index set, like `foo[0] += 42` or `foo[0]++`.
-  T handleCompoundIndexSet(
-      ast.SendSet node, T receiverType, T indexType, T rhsType) {
+  TypeInformation handleCompoundIndexSet(
+      ast.SendSet node,
+      TypeInformation receiverType,
+      TypeInformation indexType,
+      TypeInformation rhsType) {
     Selector getterSelector = elements.getGetterSelectorInComplexSendSet(node);
 
     TypeMask getterMask = inTreeData.typeOfGetter(node);
@@ -822,18 +1345,18 @@
     Selector setterSelector = elements.getSelector(node);
     TypeMask setterMask = inTreeData.typeOfSend(node);
 
-    T getterType = handleDynamicSend(node, getterSelector, getterMask,
-        receiverType, new ArgumentsTypes<T>([indexType], null));
+    TypeInformation getterType = handleDynamicSend(node, getterSelector,
+        getterMask, receiverType, new ArgumentsTypes([indexType], null));
 
-    T returnType;
+    TypeInformation returnType;
     if (node.isIfNullAssignment) {
       returnType = types.allocateDiamondPhi(getterType, rhsType);
     } else {
       returnType = handleDynamicSend(node, operatorSelector, operatorMask,
-          getterType, new ArgumentsTypes<T>([rhsType], null));
+          getterType, new ArgumentsTypes([rhsType], null));
     }
     handleDynamicSend(node, setterSelector, setterMask, receiverType,
-        new ArgumentsTypes<T>([indexType, returnType], null));
+        new ArgumentsTypes([indexType, returnType], null));
 
     if (node.isPostfix) {
       return getterType;
@@ -843,87 +1366,88 @@
   }
 
   /// Handle compound prefix/postfix operations, like `a[0]++`.
-  T handleCompoundPrefixPostfix(ast.Send node, T receiverType, T indexType) {
+  TypeInformation handleCompoundPrefixPostfix(
+      ast.Send node, TypeInformation receiverType, TypeInformation indexType) {
     return handleCompoundIndexSet(
         node, receiverType, indexType, types.uint31Type);
   }
 
   @override
-  T visitIndexPostfix(ast.Send node, ast.Node receiver, ast.Node index,
-      op.IncDecOperator operator, _) {
-    T receiverType = visit(receiver);
-    T indexType = visit(index);
+  TypeInformation visitIndexPostfix(ast.Send node, ast.Node receiver,
+      ast.Node index, op.IncDecOperator operator, _) {
+    TypeInformation receiverType = visit(receiver);
+    TypeInformation indexType = visit(index);
     return handleCompoundPrefixPostfix(node, receiverType, indexType);
   }
 
   @override
-  T visitIndexPrefix(ast.Send node, ast.Node receiver, ast.Node index,
-      op.IncDecOperator operator, _) {
-    T receiverType = visit(receiver);
-    T indexType = visit(index);
+  TypeInformation visitIndexPrefix(ast.Send node, ast.Node receiver,
+      ast.Node index, op.IncDecOperator operator, _) {
+    TypeInformation receiverType = visit(receiver);
+    TypeInformation indexType = visit(index);
     return handleCompoundPrefixPostfix(node, receiverType, indexType);
   }
 
   @override
-  T visitCompoundIndexSet(ast.SendSet node, ast.Node receiver, ast.Node index,
-      op.AssignmentOperator operator, ast.Node rhs, _) {
-    T receiverType = visit(receiver);
-    T indexType = visit(index);
-    T rhsType = visit(rhs);
+  TypeInformation visitCompoundIndexSet(ast.SendSet node, ast.Node receiver,
+      ast.Node index, op.AssignmentOperator operator, ast.Node rhs, _) {
+    TypeInformation receiverType = visit(receiver);
+    TypeInformation indexType = visit(index);
+    TypeInformation rhsType = visit(rhs);
     return handleCompoundIndexSet(node, receiverType, indexType, rhsType);
   }
 
   @override
-  T visitIndexSetIfNull(
+  TypeInformation visitIndexSetIfNull(
       ast.SendSet node, ast.Node receiver, ast.Node index, ast.Node rhs, _) {
-    T receiverType = visit(receiver);
-    T indexType = visit(index);
-    T rhsType = visit(rhs);
+    TypeInformation receiverType = visit(receiver);
+    TypeInformation indexType = visit(index);
+    TypeInformation rhsType = visit(rhs);
     return handleCompoundIndexSet(node, receiverType, indexType, rhsType);
   }
 
   @override
-  T visitSuperIndexPrefix(ast.Send node, MethodElement getter,
+  TypeInformation visitSuperIndexPrefix(ast.Send node, MethodElement getter,
       MethodElement setter, ast.Node index, op.IncDecOperator operator, _) {
-    T indexType = visit(index);
+    TypeInformation indexType = visit(index);
     return handleSuperIndexPrefixPostfix(node, getter, setter, indexType);
   }
 
   @override
-  T visitSuperIndexPostfix(ast.Send node, MethodElement getter,
+  TypeInformation visitSuperIndexPostfix(ast.Send node, MethodElement getter,
       MethodElement setter, ast.Node index, op.IncDecOperator operator, _) {
-    T indexType = visit(index);
+    TypeInformation indexType = visit(index);
     return handleSuperIndexPrefixPostfix(node, getter, setter, indexType);
   }
 
   /// Handle compound prefix/postfix operations, like `super[0]++`.
-  T handleSuperIndexPrefixPostfix(
-      ast.Send node, Element getter, Element setter, T indexType) {
+  TypeInformation handleSuperIndexPrefixPostfix(ast.Send node, Element getter,
+      Element setter, TypeInformation indexType) {
     return _handleSuperCompoundIndexSet(
         node, getter, setter, indexType, types.uint31Type);
   }
 
   /// Handle compound super index set, like `super[42] =+ 2`.
-  T handleSuperCompoundIndexSet(ast.SendSet node, Element getter,
+  TypeInformation handleSuperCompoundIndexSet(ast.SendSet node, Element getter,
       Element setter, ast.Node index, ast.Node rhs) {
-    T indexType = visit(index);
-    T rhsType = visit(rhs);
+    TypeInformation indexType = visit(index);
+    TypeInformation rhsType = visit(rhs);
     return _handleSuperCompoundIndexSet(
         node, getter, setter, indexType, rhsType);
   }
 
-  T _handleSuperCompoundIndexSet(ast.SendSet node, Element getter,
-      Element setter, T indexType, T rhsType) {
+  TypeInformation _handleSuperCompoundIndexSet(ast.SendSet node, Element getter,
+      Element setter, TypeInformation indexType, TypeInformation rhsType) {
     Selector getterSelector = elements.getGetterSelectorInComplexSendSet(node);
 
     TypeMask getterMask = inTreeData.typeOfGetter(node);
     Selector setterSelector = elements.getSelector(node);
     TypeMask setterMask = inTreeData.typeOfSend(node);
 
-    T getterType = handleSuperSend(node, getterSelector, getterMask, getter,
-        new ArgumentsTypes<T>([indexType], null));
+    TypeInformation getterType = handleSuperSend(node, getterSelector,
+        getterMask, getter, new ArgumentsTypes([indexType], null));
 
-    T returnType;
+    TypeInformation returnType;
     if (node.isIfNullAssignment) {
       returnType = types.allocateDiamondPhi(getterType, rhsType);
     } else {
@@ -931,16 +1455,16 @@
           elements.getOperatorSelectorInComplexSendSet(node);
       TypeMask operatorMask = inTreeData.typeOfOperator(node);
       returnType = handleDynamicSend(node, operatorSelector, operatorMask,
-          getterType, new ArgumentsTypes<T>([rhsType], null));
+          getterType, new ArgumentsTypes([rhsType], null));
     }
     handleSuperSend(node, setterSelector, setterMask, setter,
-        new ArgumentsTypes<T>([indexType, returnType], null));
+        new ArgumentsTypes([indexType, returnType], null));
 
     return node.isPostfix ? getterType : returnType;
   }
 
-  T handleSuperSend(ast.Node node, Selector selector, TypeMask mask,
-      Element element, ArgumentsTypes arguments) {
+  TypeInformation handleSuperSend(ast.Node node, Selector selector,
+      TypeMask mask, Element element, ArgumentsTypes arguments) {
     if (element.isMalformed) {
       return handleSuperNoSuchMethod(node, selector, mask, arguments);
     } else {
@@ -949,7 +1473,7 @@
   }
 
   @override
-  T visitSuperCompoundIndexSet(
+  TypeInformation visitSuperCompoundIndexSet(
       ast.SendSet node,
       MethodElement getter,
       MethodElement setter,
@@ -961,25 +1485,35 @@
   }
 
   @override
-  T visitSuperIndexSetIfNull(ast.SendSet node, MethodElement getter,
-      MethodElement setter, ast.Node index, ast.Node rhs, _) {
+  TypeInformation visitSuperIndexSetIfNull(
+      ast.SendSet node,
+      MethodElement getter,
+      MethodElement setter,
+      ast.Node index,
+      ast.Node rhs,
+      _) {
     return handleSuperCompoundIndexSet(node, getter, setter, index, rhs);
   }
 
   @override
-  T visitUnresolvedSuperCompoundIndexSet(ast.Send node, Element element,
-      ast.Node index, op.AssignmentOperator operator, ast.Node rhs, _) {
+  TypeInformation visitUnresolvedSuperCompoundIndexSet(
+      ast.Send node,
+      Element element,
+      ast.Node index,
+      op.AssignmentOperator operator,
+      ast.Node rhs,
+      _) {
     return handleSuperCompoundIndexSet(node, element, element, index, rhs);
   }
 
   @override
-  T visitUnresolvedSuperIndexSetIfNull(
+  TypeInformation visitUnresolvedSuperIndexSetIfNull(
       ast.Send node, Element element, ast.Node index, ast.Node rhs, _) {
     return handleSuperCompoundIndexSet(node, element, element, index, rhs);
   }
 
   @override
-  T visitUnresolvedSuperGetterCompoundIndexSet(
+  TypeInformation visitUnresolvedSuperGetterCompoundIndexSet(
       ast.SendSet node,
       Element element,
       MethodElement setter,
@@ -991,13 +1525,13 @@
   }
 
   @override
-  T visitUnresolvedSuperGetterIndexSetIfNull(ast.SendSet node, Element element,
-      MethodElement setter, ast.Node index, ast.Node rhs, _) {
+  TypeInformation visitUnresolvedSuperGetterIndexSetIfNull(ast.SendSet node,
+      Element element, MethodElement setter, ast.Node index, ast.Node rhs, _) {
     return handleSuperCompoundIndexSet(node, element, setter, index, rhs);
   }
 
   @override
-  T visitUnresolvedSuperSetterCompoundIndexSet(
+  TypeInformation visitUnresolvedSuperSetterCompoundIndexSet(
       ast.SendSet node,
       MethodElement getter,
       Element element,
@@ -1009,282 +1543,363 @@
   }
 
   @override
-  T visitUnresolvedSuperSetterIndexSetIfNull(ast.SendSet node,
+  TypeInformation visitUnresolvedSuperSetterIndexSetIfNull(ast.SendSet node,
       MethodElement getter, Element element, ast.Node index, ast.Node rhs, _) {
     return handleSuperCompoundIndexSet(node, getter, element, index, rhs);
   }
 
   @override
-  T visitUnresolvedSuperIndexPrefix(ast.Send node, Element element,
-      ast.Node index, op.IncDecOperator operator, _) {
-    T indexType = visit(index);
+  TypeInformation visitUnresolvedSuperIndexPrefix(ast.Send node,
+      Element element, ast.Node index, op.IncDecOperator operator, _) {
+    TypeInformation indexType = visit(index);
     return handleSuperIndexPrefixPostfix(node, element, element, indexType);
   }
 
   @override
-  T visitUnresolvedSuperGetterIndexPrefix(ast.SendSet node, Element element,
-      MethodElement setter, ast.Node index, op.IncDecOperator operator, _) {
-    T indexType = visit(index);
+  TypeInformation visitUnresolvedSuperGetterIndexPrefix(
+      ast.SendSet node,
+      Element element,
+      MethodElement setter,
+      ast.Node index,
+      op.IncDecOperator operator,
+      _) {
+    TypeInformation indexType = visit(index);
     return handleSuperIndexPrefixPostfix(node, element, setter, indexType);
   }
 
   @override
-  T visitUnresolvedSuperSetterIndexPrefix(
+  TypeInformation visitUnresolvedSuperSetterIndexPrefix(
       ast.SendSet node,
       MethodElement getter,
       Element element,
       ast.Node index,
       op.IncDecOperator operator,
       _) {
-    T indexType = visit(index);
+    TypeInformation indexType = visit(index);
     return handleSuperIndexPrefixPostfix(node, getter, element, indexType);
   }
 
   @override
-  T visitUnresolvedSuperIndexPostfix(ast.Send node, Element element,
-      ast.Node index, op.IncDecOperator operator, _) {
-    T indexType = visit(index);
+  TypeInformation visitUnresolvedSuperIndexPostfix(ast.Send node,
+      Element element, ast.Node index, op.IncDecOperator operator, _) {
+    TypeInformation indexType = visit(index);
     return handleSuperIndexPrefixPostfix(node, element, element, indexType);
   }
 
   @override
-  T visitUnresolvedSuperGetterIndexPostfix(ast.SendSet node, Element element,
-      MethodElement setter, ast.Node index, op.IncDecOperator operator, _) {
-    T indexType = visit(index);
+  TypeInformation visitUnresolvedSuperGetterIndexPostfix(
+      ast.SendSet node,
+      Element element,
+      MethodElement setter,
+      ast.Node index,
+      op.IncDecOperator operator,
+      _) {
+    TypeInformation indexType = visit(index);
     return handleSuperIndexPrefixPostfix(node, element, setter, indexType);
   }
 
   @override
-  T visitUnresolvedSuperSetterIndexPostfix(
+  TypeInformation visitUnresolvedSuperSetterIndexPostfix(
       ast.SendSet node,
       MethodElement getter,
       Element element,
       ast.Node index,
       op.IncDecOperator operator,
       _) {
-    T indexType = visit(index);
+    TypeInformation indexType = visit(index);
     return handleSuperIndexPrefixPostfix(node, getter, element, indexType);
   }
 
   @override
-  T visitSuperFieldCompound(ast.Send node, FieldElement field,
+  TypeInformation visitSuperFieldCompound(ast.Send node, FieldElement field,
       op.AssignmentOperator operator, ast.Node rhs, _) {
     return handleSuperCompound(node, field, field, rhs);
   }
 
   @override
-  T visitSuperFieldSetterCompound(ast.Send node, FieldElement field,
-      FunctionElement setter, op.AssignmentOperator operator, ast.Node rhs, _) {
+  TypeInformation visitSuperFieldSetterCompound(
+      ast.Send node,
+      FieldElement field,
+      FunctionElement setter,
+      op.AssignmentOperator operator,
+      ast.Node rhs,
+      _) {
     return handleSuperCompound(node, field, setter, rhs);
   }
 
   @override
-  T visitSuperGetterFieldCompound(ast.Send node, FunctionElement getter,
-      FieldElement field, op.AssignmentOperator operator, ast.Node rhs, _) {
+  TypeInformation visitSuperGetterFieldCompound(
+      ast.Send node,
+      FunctionElement getter,
+      FieldElement field,
+      op.AssignmentOperator operator,
+      ast.Node rhs,
+      _) {
     return handleSuperCompound(node, getter, field, rhs);
   }
 
   @override
-  T visitSuperGetterSetterCompound(ast.Send node, FunctionElement getter,
-      FunctionElement setter, op.AssignmentOperator operator, ast.Node rhs, _) {
+  TypeInformation visitSuperGetterSetterCompound(
+      ast.Send node,
+      FunctionElement getter,
+      FunctionElement setter,
+      op.AssignmentOperator operator,
+      ast.Node rhs,
+      _) {
     return handleSuperCompound(node, getter, setter, rhs);
   }
 
   @override
-  T visitSuperMethodSetterCompound(ast.Send node, FunctionElement method,
-      FunctionElement setter, op.AssignmentOperator operator, ast.Node rhs, _) {
+  TypeInformation visitSuperMethodSetterCompound(
+      ast.Send node,
+      FunctionElement method,
+      FunctionElement setter,
+      op.AssignmentOperator operator,
+      ast.Node rhs,
+      _) {
     return handleSuperCompound(node, method, setter, rhs);
   }
 
   @override
-  T visitUnresolvedSuperCompound(ast.Send node, Element element,
+  TypeInformation visitUnresolvedSuperCompound(ast.Send node, Element element,
       op.AssignmentOperator operator, ast.Node rhs, _) {
     return handleSuperCompound(node, element, element, rhs);
   }
 
   @override
-  T visitUnresolvedSuperGetterCompound(ast.Send node, Element getter,
-      SetterElement setter, op.AssignmentOperator operator, ast.Node rhs, _) {
+  TypeInformation visitUnresolvedSuperGetterCompound(
+      ast.Send node,
+      Element getter,
+      SetterElement setter,
+      op.AssignmentOperator operator,
+      ast.Node rhs,
+      _) {
     return handleSuperCompound(node, getter, setter, rhs);
   }
 
   @override
-  T visitUnresolvedSuperSetterCompound(ast.Send node, GetterElement getter,
-      Element setter, op.AssignmentOperator operator, ast.Node rhs, _) {
+  TypeInformation visitUnresolvedSuperSetterCompound(
+      ast.Send node,
+      GetterElement getter,
+      Element setter,
+      op.AssignmentOperator operator,
+      ast.Node rhs,
+      _) {
     return handleSuperCompound(node, getter, setter, rhs);
   }
 
   @override
-  T visitSuperFieldFieldSetIfNull(ast.Send node, FieldElement readField,
-      FieldElement writtenField, ast.Node rhs, _) {
+  TypeInformation visitSuperFieldFieldSetIfNull(ast.Send node,
+      FieldElement readField, FieldElement writtenField, ast.Node rhs, _) {
     return handleSuperCompound(node, readField, writtenField, rhs);
   }
 
   @override
-  T visitSuperFieldSetIfNull(
+  TypeInformation visitSuperFieldSetIfNull(
       ast.Send node, FieldElement field, ast.Node rhs, _) {
     return handleSuperCompound(node, field, field, rhs);
   }
 
   @override
-  T visitSuperFieldSetterSetIfNull(ast.Send node, FieldElement field,
-      FunctionElement setter, ast.Node rhs, _) {
+  TypeInformation visitSuperFieldSetterSetIfNull(ast.Send node,
+      FieldElement field, FunctionElement setter, ast.Node rhs, _) {
     return handleSuperCompound(node, field, setter, rhs);
   }
 
   @override
-  T visitSuperGetterFieldSetIfNull(ast.Send node, FunctionElement getter,
-      FieldElement field, ast.Node rhs, _) {
+  TypeInformation visitSuperGetterFieldSetIfNull(ast.Send node,
+      FunctionElement getter, FieldElement field, ast.Node rhs, _) {
     return handleSuperCompound(node, getter, field, rhs);
   }
 
   @override
-  T visitSuperGetterSetterSetIfNull(ast.Send node, FunctionElement getter,
-      FunctionElement setter, ast.Node rhs, _) {
+  TypeInformation visitSuperGetterSetterSetIfNull(ast.Send node,
+      FunctionElement getter, FunctionElement setter, ast.Node rhs, _) {
     return handleSuperCompound(node, getter, setter, rhs);
   }
 
   @override
-  T visitSuperMethodSetIfNull(
+  TypeInformation visitSuperMethodSetIfNull(
       ast.Send node, FunctionElement method, ast.Node rhs, _) {
     return handleSuperCompound(node, method, null, rhs);
   }
 
   @override
-  T visitSuperMethodSetterSetIfNull(ast.Send node, FunctionElement method,
-      FunctionElement setter, ast.Node rhs, _) {
+  TypeInformation visitSuperMethodSetterSetIfNull(ast.Send node,
+      FunctionElement method, FunctionElement setter, ast.Node rhs, _) {
     return handleSuperCompound(node, method, setter, rhs);
   }
 
-  T handleSuperCompound(
+  TypeInformation handleSuperCompound(
       ast.SendSet node, Element getter, Element setter, ast.Node rhs) {
-    T rhsType = visit(rhs);
+    TypeInformation rhsType = visit(rhs);
     return _handleSuperCompound(node, getter, setter, rhsType);
   }
 
   @override
-  T visitSuperFieldFieldPostfix(ast.SendSet node, FieldElement readField,
-      FieldElement writtenField, op.IncDecOperator operator, _) {
+  TypeInformation visitSuperFieldFieldPostfix(
+      ast.SendSet node,
+      FieldElement readField,
+      FieldElement writtenField,
+      op.IncDecOperator operator,
+      _) {
     return handleSuperPrefixPostfix(node, readField, writtenField);
   }
 
   @override
-  T visitSuperFieldFieldPrefix(ast.SendSet node, FieldElement readField,
-      FieldElement writtenField, op.IncDecOperator operator, _) {
+  TypeInformation visitSuperFieldFieldPrefix(
+      ast.SendSet node,
+      FieldElement readField,
+      FieldElement writtenField,
+      op.IncDecOperator operator,
+      _) {
     return handleSuperPrefixPostfix(node, readField, writtenField);
   }
 
   @override
-  T visitSuperFieldPostfix(
+  TypeInformation visitSuperFieldPostfix(
       ast.SendSet node, FieldElement field, op.IncDecOperator operator, _) {
     return handleSuperPrefixPostfix(node, field, field);
   }
 
   @override
-  T visitSuperFieldPrefix(
+  TypeInformation visitSuperFieldPrefix(
       ast.SendSet node, FieldElement field, op.IncDecOperator operator, _) {
     return handleSuperPrefixPostfix(node, field, field);
   }
 
   @override
-  T visitSuperFieldSetterPostfix(ast.SendSet node, FieldElement field,
-      FunctionElement setter, op.IncDecOperator operator, _) {
+  TypeInformation visitSuperFieldSetterPostfix(
+      ast.SendSet node,
+      FieldElement field,
+      FunctionElement setter,
+      op.IncDecOperator operator,
+      _) {
     return handleSuperPrefixPostfix(node, field, setter);
   }
 
   @override
-  T visitSuperFieldSetterPrefix(ast.SendSet node, FieldElement field,
-      FunctionElement setter, op.IncDecOperator operator, _) {
+  TypeInformation visitSuperFieldSetterPrefix(
+      ast.SendSet node,
+      FieldElement field,
+      FunctionElement setter,
+      op.IncDecOperator operator,
+      _) {
     return handleSuperPrefixPostfix(node, field, setter);
   }
 
   @override
-  T visitSuperGetterFieldPostfix(ast.SendSet node, FunctionElement getter,
-      FieldElement field, op.IncDecOperator operator, _) {
+  TypeInformation visitSuperGetterFieldPostfix(
+      ast.SendSet node,
+      FunctionElement getter,
+      FieldElement field,
+      op.IncDecOperator operator,
+      _) {
     return handleSuperPrefixPostfix(node, getter, field);
   }
 
   @override
-  T visitSuperGetterFieldPrefix(ast.SendSet node, FunctionElement getter,
-      FieldElement field, op.IncDecOperator operator, _) {
+  TypeInformation visitSuperGetterFieldPrefix(
+      ast.SendSet node,
+      FunctionElement getter,
+      FieldElement field,
+      op.IncDecOperator operator,
+      _) {
     return handleSuperPrefixPostfix(node, getter, field);
   }
 
   @override
-  T visitSuperGetterSetterPostfix(ast.SendSet node, FunctionElement getter,
-      FunctionElement setter, op.IncDecOperator operator, _) {
+  TypeInformation visitSuperGetterSetterPostfix(
+      ast.SendSet node,
+      FunctionElement getter,
+      FunctionElement setter,
+      op.IncDecOperator operator,
+      _) {
     return handleSuperPrefixPostfix(node, getter, setter);
   }
 
   @override
-  T visitSuperGetterSetterPrefix(ast.SendSet node, FunctionElement getter,
-      FunctionElement setter, op.IncDecOperator operator, _) {
+  TypeInformation visitSuperGetterSetterPrefix(
+      ast.SendSet node,
+      FunctionElement getter,
+      FunctionElement setter,
+      op.IncDecOperator operator,
+      _) {
     return handleSuperPrefixPostfix(node, getter, setter);
   }
 
   @override
-  T visitSuperMethodSetterPostfix(ast.SendSet node, FunctionElement method,
-      FunctionElement setter, op.IncDecOperator operator, _) {
+  TypeInformation visitSuperMethodSetterPostfix(
+      ast.SendSet node,
+      FunctionElement method,
+      FunctionElement setter,
+      op.IncDecOperator operator,
+      _) {
     return handleSuperPrefixPostfix(node, method, setter);
   }
 
   @override
-  T visitSuperMethodSetterPrefix(ast.SendSet node, FunctionElement method,
-      FunctionElement setter, op.IncDecOperator operator, _) {
+  TypeInformation visitSuperMethodSetterPrefix(
+      ast.SendSet node,
+      FunctionElement method,
+      FunctionElement setter,
+      op.IncDecOperator operator,
+      _) {
     return handleSuperPrefixPostfix(node, method, setter);
   }
 
   @override
-  T visitUnresolvedSuperPrefix(
+  TypeInformation visitUnresolvedSuperPrefix(
       ast.SendSet node, Element element, op.IncDecOperator operator, _) {
     return handleSuperPrefixPostfix(node, element, element);
   }
 
   @override
-  T visitUnresolvedSuperPostfix(
+  TypeInformation visitUnresolvedSuperPostfix(
       ast.SendSet node, Element element, op.IncDecOperator operator, _) {
     return handleSuperPrefixPostfix(node, element, element);
   }
 
   @override
-  T visitUnresolvedSuperGetterPrefix(ast.SendSet node, Element getter,
-      SetterElement setter, op.IncDecOperator operator, _) {
+  TypeInformation visitUnresolvedSuperGetterPrefix(ast.SendSet node,
+      Element getter, SetterElement setter, op.IncDecOperator operator, _) {
     return handleSuperPrefixPostfix(node, getter, setter);
   }
 
   @override
-  T visitUnresolvedSuperGetterPostfix(ast.SendSet node, Element getter,
-      SetterElement setter, op.IncDecOperator operator, _) {
+  TypeInformation visitUnresolvedSuperGetterPostfix(ast.SendSet node,
+      Element getter, SetterElement setter, op.IncDecOperator operator, _) {
     return handleSuperPrefixPostfix(node, getter, setter);
   }
 
   @override
-  T visitUnresolvedSuperSetterPrefix(ast.SendSet node, GetterElement getter,
-      Element setter, op.IncDecOperator operator, _) {
+  TypeInformation visitUnresolvedSuperSetterPrefix(ast.SendSet node,
+      GetterElement getter, Element setter, op.IncDecOperator operator, _) {
     return handleSuperPrefixPostfix(node, getter, setter);
   }
 
   @override
-  T visitUnresolvedSuperSetterPostfix(ast.SendSet node, GetterElement getter,
-      Element setter, op.IncDecOperator operator, _) {
+  TypeInformation visitUnresolvedSuperSetterPostfix(ast.SendSet node,
+      GetterElement getter, Element setter, op.IncDecOperator operator, _) {
     return handleSuperPrefixPostfix(node, getter, setter);
   }
 
-  T handleSuperPrefixPostfix(ast.SendSet node, Element getter, Element setter) {
+  TypeInformation handleSuperPrefixPostfix(
+      ast.SendSet node, Element getter, Element setter) {
     return _handleSuperCompound(node, getter, setter, types.uint31Type);
   }
 
-  T _handleSuperCompound(
-      ast.SendSet node, Element getter, Element setter, T rhsType) {
+  TypeInformation _handleSuperCompound(ast.SendSet node, Element getter,
+      Element setter, TypeInformation rhsType) {
     Selector getterSelector = elements.getGetterSelectorInComplexSendSet(node);
     TypeMask getterMask = inTreeData.typeOfGetter(node);
     Selector setterSelector = elements.getSelector(node);
     TypeMask setterMask = inTreeData.typeOfSend(node);
 
-    T getterType =
+    TypeInformation getterType =
         handleSuperSend(node, getterSelector, getterMask, getter, null);
 
-    T returnType;
+    TypeInformation returnType;
     if (node.isIfNullAssignment) {
       returnType = types.allocateDiamondPhi(getterType, rhsType);
     } else {
@@ -1292,65 +1907,66 @@
           elements.getOperatorSelectorInComplexSendSet(node);
       TypeMask operatorMask = inTreeData.typeOfOperator(node);
       returnType = handleDynamicSend(node, operatorSelector, operatorMask,
-          getterType, new ArgumentsTypes<T>([rhsType], null));
+          getterType, new ArgumentsTypes([rhsType], null));
     }
     handleSuperSend(node, setterSelector, setterMask, setter,
-        new ArgumentsTypes<T>([returnType], null));
+        new ArgumentsTypes([returnType], null));
 
     return node.isPostfix ? getterType : returnType;
   }
 
   /// Handle index set, like `foo[0] = 42`.
-  T handleIndexSet(ast.SendSet node, T receiverType, T indexType, T rhsType) {
+  TypeInformation handleIndexSet(ast.SendSet node, TypeInformation receiverType,
+      TypeInformation indexType, TypeInformation rhsType) {
     Selector setterSelector = elements.getSelector(node);
     TypeMask setterMask = inTreeData.typeOfSend(node);
     handleDynamicSend(node, setterSelector, setterMask, receiverType,
-        new ArgumentsTypes<T>([indexType, rhsType], null));
+        new ArgumentsTypes([indexType, rhsType], null));
     return rhsType;
   }
 
   @override
-  T visitIndexSet(
+  TypeInformation visitIndexSet(
       ast.SendSet node, ast.Node receiver, ast.Node index, ast.Node rhs, _) {
-    T receiverType = visit(receiver);
-    T indexType = visit(index);
-    T rhsType = visit(rhs);
+    TypeInformation receiverType = visit(receiver);
+    TypeInformation indexType = visit(index);
+    TypeInformation rhsType = visit(rhs);
     return handleIndexSet(node, receiverType, indexType, rhsType);
   }
 
   /// Handle super index set, like `super[42] = true`.
-  T handleSuperIndexSet(
+  TypeInformation handleSuperIndexSet(
       ast.SendSet node, Element element, ast.Node index, ast.Node rhs) {
-    T indexType = visit(index);
-    T rhsType = visit(rhs);
+    TypeInformation indexType = visit(index);
+    TypeInformation rhsType = visit(rhs);
     Selector setterSelector = elements.getSelector(node);
     TypeMask setterMask = inTreeData.typeOfSend(node);
     handleStaticSend(node, setterSelector, setterMask, element,
-        new ArgumentsTypes<T>([indexType, rhsType], null));
+        new ArgumentsTypes([indexType, rhsType], null));
     return rhsType;
   }
 
   @override
-  T visitSuperIndexSet(ast.SendSet node, FunctionElement function,
+  TypeInformation visitSuperIndexSet(ast.SendSet node, FunctionElement function,
       ast.Node index, ast.Node rhs, _) {
     return handleSuperIndexSet(node, function, index, rhs);
   }
 
   @override
-  T visitUnresolvedSuperIndexSet(
+  TypeInformation visitUnresolvedSuperIndexSet(
       ast.SendSet node, Element element, ast.Node index, ast.Node rhs, _) {
     return handleSuperIndexSet(node, element, index, rhs);
   }
 
-  T handlePlainAssignment(
+  TypeInformation handlePlainAssignment(
       ast.Node node,
       Element element,
       Selector setterSelector,
       TypeMask setterMask,
-      T receiverType,
-      T rhsType,
+      TypeInformation receiverType,
+      TypeInformation rhsType,
       ast.Node rhs) {
-    ArgumentsTypes arguments = new ArgumentsTypes<T>([rhsType], null);
+    ArgumentsTypes arguments = new ArgumentsTypes([rhsType], null);
     if (Elements.isMalformed(element)) {
       // Code will always throw.
     } else if (Elements.isStaticOrTopLevelField(element)) {
@@ -1396,7 +2012,7 @@
   }
 
   /// Handle a super access or invocation that results in a `noSuchMethod` call.
-  T handleErroneousSuperSend(ast.Send node) {
+  TypeInformation handleErroneousSuperSend(ast.Send node) {
     ArgumentsTypes arguments =
         node.isPropertyAccess ? null : analyzeArguments(node.arguments);
     Selector selector = elements.getSelector(node);
@@ -1408,8 +2024,8 @@
     return handleSuperNoSuchMethod(node, selector, mask, arguments);
   }
 
-  T handleSuperNoSuchMethod(ast.Send node, Selector selector, TypeMask mask,
-      ArgumentsTypes arguments) {
+  TypeInformation handleSuperNoSuchMethod(ast.Send node, Selector selector,
+      TypeMask mask, ArgumentsTypes arguments) {
     // Ensure we create a node, to make explicit the call to the
     // `noSuchMethod` handler.
     ClassElement cls = outermostElement.enclosingClass.declaration;
@@ -1423,7 +2039,7 @@
 
   /// Handle a .call invocation on the values retrieved from the super
   /// [element]. For instance `super.foo(bar)` where `foo` is a field or getter.
-  T handleSuperClosureCall(
+  TypeInformation handleSuperClosureCall(
       ast.Send node, Element element, ast.NodeList arguments) {
     ArgumentsTypes argumentTypes = analyzeArguments(arguments.nodes);
     Selector selector = elements.getSelector(node);
@@ -1443,7 +2059,7 @@
   }
 
   /// Handle an invocation of super [method].
-  T handleSuperMethodInvoke(
+  TypeInformation handleSuperMethodInvoke(
       ast.Send node, MethodElement method, ArgumentsTypes arguments) {
     // TODO(herhut): We could do better here if we knew what we
     // are calling does not expose this.
@@ -1454,7 +2070,7 @@
   }
 
   /// Handle access to a super field or getter [element].
-  T handleSuperGet(ast.Send node, Element element) {
+  TypeInformation handleSuperGet(ast.Send node, Element element) {
     // TODO(herhut): We could do better here if we knew what we
     // are calling does not expose this.
     isThisExposed = true;
@@ -1464,131 +2080,137 @@
   }
 
   /// Handle update to a super field or setter [element].
-  T handleSuperSet(ast.Send node, Element element, ast.Node rhs) {
-    T rhsType = visit(rhs);
+  TypeInformation handleSuperSet(ast.Send node, Element element, ast.Node rhs) {
+    TypeInformation rhsType = visit(rhs);
     // TODO(herhut): We could do better here if we knew what we
     // are calling does not expose this.
     isThisExposed = true;
     Selector selector = elements.getSelector(node);
     TypeMask mask = inTreeData.typeOfSend(node);
     handleStaticSend(
-        node, selector, mask, element, new ArgumentsTypes<T>([rhsType], null));
+        node, selector, mask, element, new ArgumentsTypes([rhsType], null));
     return rhsType;
   }
 
   @override
-  T visitSuperFieldSet(ast.Send node, FieldElement method, ast.Node rhs, _) {
+  TypeInformation visitSuperFieldSet(
+      ast.Send node, FieldElement method, ast.Node rhs, _) {
     return handleSuperSet(node, method, rhs);
   }
 
   @override
-  T visitSuperSetterSet(ast.Send node, SetterElement field, ast.Node rhs, _) {
+  TypeInformation visitSuperSetterSet(
+      ast.Send node, SetterElement field, ast.Node rhs, _) {
     return handleSuperSet(node, field, rhs);
   }
 
   @override
-  T visitUnresolvedSuperIndex(
+  TypeInformation visitUnresolvedSuperIndex(
       ast.Send node, Element element, ast.Node index, _) {
     return handleErroneousSuperSend(node);
   }
 
   @override
-  T visitUnresolvedSuperUnary(
+  TypeInformation visitUnresolvedSuperUnary(
       ast.Send node, op.UnaryOperator operator, Element element, _) {
     return handleErroneousSuperSend(node);
   }
 
   @override
-  T visitUnresolvedSuperBinary(ast.Send node, Element element,
+  TypeInformation visitUnresolvedSuperBinary(ast.Send node, Element element,
       op.BinaryOperator operator, ast.Node argument, _) {
     return handleErroneousSuperSend(node);
   }
 
   @override
-  T visitUnresolvedSuperGet(ast.Send node, Element element, _) {
+  TypeInformation visitUnresolvedSuperGet(ast.Send node, Element element, _) {
     return handleErroneousSuperSend(node);
   }
 
   @override
-  T visitSuperSetterGet(ast.Send node, MethodElement setter, _) {
+  TypeInformation visitSuperSetterGet(ast.Send node, MethodElement setter, _) {
     return handleErroneousSuperSend(node);
   }
 
   @override
-  T visitSuperGetterSet(ast.Send node, MethodElement getter, ast.Node rhs, _) {
+  TypeInformation visitSuperGetterSet(
+      ast.Send node, MethodElement getter, ast.Node rhs, _) {
     return handleErroneousSuperSend(node);
   }
 
   @override
-  T visitSuperMethodSet(ast.Send node, MethodElement method, ast.Node rhs, _) {
+  TypeInformation visitSuperMethodSet(
+      ast.Send node, MethodElement method, ast.Node rhs, _) {
     return handleErroneousSuperSend(node);
   }
 
   @override
-  T visitFinalSuperFieldSet(
+  TypeInformation visitFinalSuperFieldSet(
       ast.Send node, FieldElement method, ast.Node rhs, _) {
     return handleErroneousSuperSend(node);
   }
 
   @override
-  T visitUnresolvedSuperSet(ast.Send node, Element element, ast.Node rhs, _) {
+  TypeInformation visitUnresolvedSuperSet(
+      ast.Send node, Element element, ast.Node rhs, _) {
     return handleErroneousSuperSend(node);
   }
 
   @override
-  T visitUnresolvedSuperInvoke(
+  TypeInformation visitUnresolvedSuperInvoke(
       ast.Send node, Element element, ast.Node argument, Selector selector, _) {
     return handleErroneousSuperSend(node);
   }
 
   @override
-  T visitSuperFieldGet(ast.Send node, FieldElement field, _) {
+  TypeInformation visitSuperFieldGet(ast.Send node, FieldElement field, _) {
     return handleSuperGet(node, field);
   }
 
   @override
-  T visitSuperGetterGet(ast.Send node, MethodElement method, _) {
+  TypeInformation visitSuperGetterGet(ast.Send node, MethodElement method, _) {
     return handleSuperGet(node, method);
   }
 
   @override
-  T visitSuperMethodGet(ast.Send node, MethodElement method, _) {
+  TypeInformation visitSuperMethodGet(ast.Send node, MethodElement method, _) {
     return handleSuperGet(node, method);
   }
 
   @override
-  T visitSuperFieldInvoke(ast.Send node, FieldElement field,
+  TypeInformation visitSuperFieldInvoke(ast.Send node, FieldElement field,
       ast.NodeList arguments, CallStructure callStructure, _) {
     return handleSuperClosureCall(node, field, arguments);
   }
 
   @override
-  T visitSuperGetterInvoke(ast.Send node, MethodElement getter,
+  TypeInformation visitSuperGetterInvoke(ast.Send node, MethodElement getter,
       ast.NodeList arguments, CallStructure callStructure, _) {
     return handleSuperClosureCall(node, getter, arguments);
   }
 
   @override
-  T visitSuperMethodInvoke(ast.Send node, MethodElement method,
+  TypeInformation visitSuperMethodInvoke(ast.Send node, MethodElement method,
       ast.NodeList arguments, CallStructure callStructure, _) {
     return handleSuperMethodInvoke(
         node, method, analyzeArguments(arguments.nodes));
   }
 
   @override
-  T visitSuperSetterInvoke(ast.Send node, FunctionElement setter,
+  TypeInformation visitSuperSetterInvoke(ast.Send node, FunctionElement setter,
       ast.NodeList arguments, CallStructure callStructure, _) {
     return handleErroneousSuperSend(node);
   }
 
   @override
-  T visitSuperIndex(ast.Send node, MethodElement method, ast.Node index, _) {
+  TypeInformation visitSuperIndex(
+      ast.Send node, MethodElement method, ast.Node index, _) {
     return handleSuperMethodInvoke(
         node, method, analyzeArguments(node.arguments));
   }
 
   @override
-  T visitSuperEquals(
+  TypeInformation visitSuperEquals(
       ast.Send node, MethodElement method, ast.Node argument, _) {
     // TODO(johnniwinther): Special case ==.
     return handleSuperMethodInvoke(
@@ -1596,7 +2218,7 @@
   }
 
   @override
-  T visitSuperNotEquals(
+  TypeInformation visitSuperNotEquals(
       ast.Send node, MethodElement method, ast.Node argument, _) {
     // TODO(johnniwinther): Special case !=.
     return handleSuperMethodInvoke(
@@ -1604,22 +2226,26 @@
   }
 
   @override
-  T visitSuperBinary(ast.Send node, MethodElement method,
+  TypeInformation visitSuperBinary(ast.Send node, MethodElement method,
       op.BinaryOperator operator, ast.Node argument, _) {
     return handleSuperMethodInvoke(
         node, method, analyzeArguments(node.arguments));
   }
 
   @override
-  T visitSuperUnary(
+  TypeInformation visitSuperUnary(
       ast.Send node, op.UnaryOperator operator, MethodElement method, _) {
     return handleSuperMethodInvoke(
         node, method, analyzeArguments(node.arguments));
   }
 
   @override
-  T visitSuperMethodIncompatibleInvoke(ast.Send node, MethodElement method,
-      ast.NodeList arguments, CallStructure callStructure, _) {
+  TypeInformation visitSuperMethodIncompatibleInvoke(
+      ast.Send node,
+      MethodElement method,
+      ast.NodeList arguments,
+      CallStructure callStructure,
+      _) {
     return handleErroneousSuperSend(node);
   }
 
@@ -1632,36 +2258,38 @@
       return length.value;
     } else if (element != null &&
         element.isField &&
-        Elements.isStaticOrTopLevelField(element) &&
-        closedWorld.fieldNeverChanges(element)) {
+        Elements.isStaticOrTopLevelField(element)) {
       FieldElement fieldElement = element;
-      ConstantValue value =
-          compiler.backend.constants.getConstantValue(fieldElement.constant);
-      if (value != null && value.isInt) {
-        IntConstantValue intValue = value;
-        return intValue.primitiveValue;
+      if (closedWorld.fieldNeverChanges(fieldElement)) {
+        ConstantValue value =
+            compiler.backend.constants.getConstantValue(fieldElement.constant);
+        if (value != null && value.isInt) {
+          IntConstantValue intValue = value;
+          return intValue.primitiveValue;
+        }
       }
     }
     return null;
   }
 
-  T visitAwait(ast.Await node) {
-    T futureType = node.expression.accept(this);
+  TypeInformation visitAwait(ast.Await node) {
+    TypeInformation futureType = node.expression.accept(this);
     return inferrer.registerAwait(node, futureType);
   }
 
   @override
-  T handleTypeLiteralInvoke(ast.NodeList arguments) {
+  TypeInformation handleTypeLiteralInvoke(ast.NodeList arguments) {
     // This is reached when users forget to put a `new` in front of a type
     // literal. The emitter will generate an actual call (even though it is
     // likely invalid), and for that it needs to have the arguments processed
     // as well.
     analyzeArguments(arguments.nodes);
-    return super.handleTypeLiteralInvoke(arguments);
+    return types.dynamicType;
   }
 
   /// Handle constructor invocation of [constructor].
-  T handleConstructorSend(ast.Send node, ConstructorElement constructor) {
+  TypeInformation handleConstructorSend(
+      ast.Send node, ConstructorElement constructor) {
     ConstructorElement target = constructor.implementation;
     ArgumentsTypes arguments = analyzeArguments(node.arguments);
     if (visitingInitializers) {
@@ -1687,13 +2315,14 @@
     TypeMask mask = inTreeData.typeOfSend(node);
     // In erroneous code the number of arguments in the selector might not
     // match the function element.
-    // TODO(polux): return nonNullEmpty and check it doesn't break anything
+    // TODO(polux): return nonNullEmpty and check it doesn'TypeInformation break anything
     if (target.isMalformed ||
         !callStructure.signatureApplies(target.functionSignature)) {
       return types.dynamicType;
     }
 
-    T returnType = handleStaticSend(node, selector, mask, target, arguments);
+    TypeInformation returnType =
+        handleStaticSend(node, selector, mask, target, arguments);
     if (Elements.isGrowableListConstructorCall(
         constructor, node, closedWorld.commonElements)) {
       return inferrer.concreteTypes.putIfAbsent(
@@ -1705,7 +2334,7 @@
         Elements.isFilledListConstructorCall(
             constructor, node, closedWorld.commonElements)) {
       int length = findLength(node);
-      T elementType = Elements.isFixedListConstructorCall(
+      TypeInformation elementType = Elements.isFixedListConstructorCall(
               constructor, node, closedWorld.commonElements)
           ? types.nullType
           : arguments.positional[1];
@@ -1717,7 +2346,7 @@
     } else if (Elements.isConstructorOfTypedArraySubclass(
         constructor, closedWorld)) {
       int length = findLength(node);
-      T elementType = inferrer
+      TypeInformation elementType = inferrer
           .returnTypeOfElement(target.enclosingClass.lookupMember('[]'));
       return inferrer.concreteTypes.putIfAbsent(
           node,
@@ -1729,13 +2358,13 @@
   }
 
   @override
-  T bulkHandleNew(ast.NewExpression node, _) {
+  TypeInformation bulkHandleNew(ast.NewExpression node, _) {
     Element element = elements[node.send];
     return handleConstructorSend(node.send, element);
   }
 
   @override
-  T errorNonConstantConstructorInvoke(
+  TypeInformation errorNonConstantConstructorInvoke(
       ast.NewExpression node,
       Element element,
       ResolutionDartType type,
@@ -1746,7 +2375,8 @@
   }
 
   /// Handle invocation of a top level or static field or getter [element].
-  T handleStaticFieldOrGetterInvoke(ast.Send node, Element element) {
+  TypeInformation handleStaticFieldOrGetterInvoke(
+      ast.Send node, Element element) {
     ArgumentsTypes arguments = analyzeArguments(node.arguments);
     Selector selector = elements.getSelector(node);
     TypeMask mask = inTreeData.typeOfSend(node);
@@ -1763,7 +2393,8 @@
   }
 
   /// Handle invocation of a top level or static [function].
-  T handleStaticFunctionInvoke(ast.Send node, MethodElement function) {
+  TypeInformation handleStaticFunctionInvoke(
+      ast.Send node, MethodElement function) {
     if (compiler.backend.isForeign(function)) {
       return handleForeignSend(node, function);
     }
@@ -1775,49 +2406,29 @@
 
   /// Handle an static invocation of an unresolved target or with incompatible
   /// arguments to a resolved target.
-  T handleInvalidStaticInvoke(ast.Send node) {
+  TypeInformation handleInvalidStaticInvoke(ast.Send node) {
     analyzeArguments(node.arguments);
     return types.dynamicType;
   }
 
   @override
-  T visitStaticFieldInvoke(ast.Send node, FieldElement field,
+  TypeInformation visitStaticFieldInvoke(ast.Send node, FieldElement field,
       ast.NodeList arguments, CallStructure callStructure, _) {
     return handleStaticFieldOrGetterInvoke(node, field);
   }
 
   @override
-  T visitStaticFunctionInvoke(ast.Send node, MethodElement function,
-      ast.NodeList arguments, CallStructure callStructure, _) {
+  TypeInformation visitStaticFunctionInvoke(
+      ast.Send node,
+      MethodElement function,
+      ast.NodeList arguments,
+      CallStructure callStructure,
+      _) {
     return handleStaticFunctionInvoke(node, function);
   }
 
   @override
-  T visitStaticFunctionIncompatibleInvoke(ast.Send node, MethodElement function,
-      ast.NodeList arguments, CallStructure callStructure, _) {
-    return handleInvalidStaticInvoke(node);
-  }
-
-  @override
-  T visitStaticGetterInvoke(ast.Send node, FunctionElement getter,
-      ast.NodeList arguments, CallStructure callStructure, _) {
-    return handleStaticFieldOrGetterInvoke(node, getter);
-  }
-
-  @override
-  T visitTopLevelFieldInvoke(ast.Send node, FieldElement field,
-      ast.NodeList arguments, CallStructure callStructure, _) {
-    return handleStaticFieldOrGetterInvoke(node, field);
-  }
-
-  @override
-  T visitTopLevelFunctionInvoke(ast.Send node, MethodElement function,
-      ast.NodeList arguments, CallStructure callStructure, _) {
-    return handleStaticFunctionInvoke(node, function);
-  }
-
-  @override
-  T visitTopLevelFunctionIncompatibleInvoke(
+  TypeInformation visitStaticFunctionIncompatibleInvoke(
       ast.Send node,
       MethodElement function,
       ast.NodeList arguments,
@@ -1827,30 +2438,66 @@
   }
 
   @override
-  T visitTopLevelGetterInvoke(ast.Send node, FunctionElement getter,
+  TypeInformation visitStaticGetterInvoke(ast.Send node, FunctionElement getter,
       ast.NodeList arguments, CallStructure callStructure, _) {
     return handleStaticFieldOrGetterInvoke(node, getter);
   }
 
   @override
-  T visitStaticSetterInvoke(ast.Send node, MethodElement setter,
+  TypeInformation visitTopLevelFieldInvoke(ast.Send node, FieldElement field,
+      ast.NodeList arguments, CallStructure callStructure, _) {
+    return handleStaticFieldOrGetterInvoke(node, field);
+  }
+
+  @override
+  TypeInformation visitTopLevelFunctionInvoke(
+      ast.Send node,
+      MethodElement function,
+      ast.NodeList arguments,
+      CallStructure callStructure,
+      _) {
+    return handleStaticFunctionInvoke(node, function);
+  }
+
+  @override
+  TypeInformation visitTopLevelFunctionIncompatibleInvoke(
+      ast.Send node,
+      MethodElement function,
+      ast.NodeList arguments,
+      CallStructure callStructure,
+      _) {
+    return handleInvalidStaticInvoke(node);
+  }
+
+  @override
+  TypeInformation visitTopLevelGetterInvoke(
+      ast.Send node,
+      FunctionElement getter,
+      ast.NodeList arguments,
+      CallStructure callStructure,
+      _) {
+    return handleStaticFieldOrGetterInvoke(node, getter);
+  }
+
+  @override
+  TypeInformation visitStaticSetterInvoke(ast.Send node, MethodElement setter,
       ast.NodeList arguments, CallStructure callStructure, _) {
     return handleInvalidStaticInvoke(node);
   }
 
   @override
-  T visitTopLevelSetterInvoke(ast.Send node, MethodElement setter,
+  TypeInformation visitTopLevelSetterInvoke(ast.Send node, MethodElement setter,
       ast.NodeList arguments, CallStructure callStructure, _) {
     return handleInvalidStaticInvoke(node);
   }
 
   @override
-  T visitUnresolvedInvoke(ast.Send node, Element element,
+  TypeInformation visitUnresolvedInvoke(ast.Send node, Element element,
       ast.NodeList arguments, Selector selector, _) {
     return handleInvalidStaticInvoke(node);
   }
 
-  T handleForeignSend(ast.Send node, Element element) {
+  TypeInformation handleForeignSend(ast.Send node, Element element) {
     ArgumentsTypes arguments = analyzeArguments(node.arguments);
     Selector selector = elements.getSelector(node);
     TypeMask mask = inTreeData.typeOfSend(node);
@@ -1871,13 +2518,13 @@
   }
 
   ArgumentsTypes analyzeArguments(Link<ast.Node> arguments) {
-    List<T> positional = [];
-    Map<String, T> named;
+    List positional = [];
+    Map<String, TypeInformation> named;
     for (var argument in arguments) {
       ast.NamedArgument namedArgument = argument.asNamedArgument();
       if (namedArgument != null) {
         argument = namedArgument.expression;
-        if (named == null) named = new Map<String, T>();
+        if (named == null) named = new Map<String, TypeInformation>();
         named[namedArgument.name.source] = argument.accept(this);
       } else {
         positional.add(argument.accept(this));
@@ -1886,114 +2533,124 @@
       // are calling does not expose this.
       isThisExposed = isThisExposed || argument.isThis();
     }
-    return new ArgumentsTypes<T>(positional, named);
+    return new ArgumentsTypes(positional, named);
   }
 
   /// Read a local variable, function or parameter.
-  T handleLocalGet(ast.Send node, LocalElement local) {
+  TypeInformation handleLocalGet(ast.Send node, LocalElement local) {
     assert(locals.use(local) != null);
     return locals.use(local);
   }
 
   /// Read a static or top level field.
-  T handleStaticFieldGet(ast.Send node, FieldElement field) {
+  TypeInformation handleStaticFieldGet(ast.Send node, FieldElement field) {
     Selector selector = elements.getSelector(node);
     TypeMask mask = inTreeData.typeOfSend(node);
     return handleStaticSend(node, selector, mask, field, null);
   }
 
   /// Invoke a static or top level getter.
-  T handleStaticGetterGet(ast.Send node, MethodElement getter) {
+  TypeInformation handleStaticGetterGet(ast.Send node, MethodElement getter) {
     Selector selector = elements.getSelector(node);
     TypeMask mask = inTreeData.typeOfSend(node);
     return handleStaticSend(node, selector, mask, getter, null);
   }
 
   /// Closurize a static or top level function.
-  T handleStaticFunctionGet(ast.Send node, MethodElement function) {
+  TypeInformation handleStaticFunctionGet(
+      ast.Send node, MethodElement function) {
     Selector selector = elements.getSelector(node);
     TypeMask mask = inTreeData.typeOfSend(node);
     return handleStaticSend(node, selector, mask, function, null);
   }
 
   @override
-  T visitDynamicPropertyGet(ast.Send node, ast.Node receiver, Name name, _) {
-    return handleDynamicGet(node);
-  }
-
-  @override
-  T visitIfNotNullDynamicPropertyGet(
+  TypeInformation visitDynamicPropertyGet(
       ast.Send node, ast.Node receiver, Name name, _) {
     return handleDynamicGet(node);
   }
 
   @override
-  T visitLocalVariableGet(ast.Send node, LocalVariableElement variable, _) {
-    return handleLocalGet(node, variable);
-  }
-
-  @override
-  T visitParameterGet(ast.Send node, ParameterElement parameter, _) {
-    return handleLocalGet(node, parameter);
-  }
-
-  @override
-  T visitLocalFunctionGet(ast.Send node, LocalFunctionElement function, _) {
-    return handleLocalGet(node, function);
-  }
-
-  @override
-  T visitStaticFieldGet(ast.Send node, FieldElement field, _) {
-    return handleStaticFieldGet(node, field);
-  }
-
-  @override
-  T visitStaticFunctionGet(ast.Send node, MethodElement function, _) {
-    return handleStaticFunctionGet(node, function);
-  }
-
-  @override
-  T visitStaticGetterGet(ast.Send node, FunctionElement getter, _) {
-    return handleStaticGetterGet(node, getter);
-  }
-
-  @override
-  T visitThisPropertyGet(ast.Send node, Name name, _) {
+  TypeInformation visitIfNotNullDynamicPropertyGet(
+      ast.Send node, ast.Node receiver, Name name, _) {
     return handleDynamicGet(node);
   }
 
   @override
-  T visitTopLevelFieldGet(ast.Send node, FieldElement field, _) {
+  TypeInformation visitLocalVariableGet(
+      ast.Send node, LocalVariableElement variable, _) {
+    return handleLocalGet(node, variable);
+  }
+
+  @override
+  TypeInformation visitParameterGet(
+      ast.Send node, ParameterElement parameter, _) {
+    return handleLocalGet(node, parameter);
+  }
+
+  @override
+  TypeInformation visitLocalFunctionGet(
+      ast.Send node, LocalFunctionElement function, _) {
+    return handleLocalGet(node, function);
+  }
+
+  @override
+  TypeInformation visitStaticFieldGet(ast.Send node, FieldElement field, _) {
     return handleStaticFieldGet(node, field);
   }
 
   @override
-  T visitTopLevelFunctionGet(ast.Send node, MethodElement function, _) {
+  TypeInformation visitStaticFunctionGet(
+      ast.Send node, MethodElement function, _) {
     return handleStaticFunctionGet(node, function);
   }
 
   @override
-  T visitTopLevelGetterGet(ast.Send node, FunctionElement getter, _) {
+  TypeInformation visitStaticGetterGet(
+      ast.Send node, FunctionElement getter, _) {
     return handleStaticGetterGet(node, getter);
   }
 
   @override
-  T visitStaticSetterGet(ast.Send node, MethodElement setter, _) {
+  TypeInformation visitThisPropertyGet(ast.Send node, Name name, _) {
+    return handleDynamicGet(node);
+  }
+
+  @override
+  TypeInformation visitTopLevelFieldGet(ast.Send node, FieldElement field, _) {
+    return handleStaticFieldGet(node, field);
+  }
+
+  @override
+  TypeInformation visitTopLevelFunctionGet(
+      ast.Send node, MethodElement function, _) {
+    return handleStaticFunctionGet(node, function);
+  }
+
+  @override
+  TypeInformation visitTopLevelGetterGet(
+      ast.Send node, FunctionElement getter, _) {
+    return handleStaticGetterGet(node, getter);
+  }
+
+  @override
+  TypeInformation visitStaticSetterGet(ast.Send node, MethodElement setter, _) {
     return types.dynamicType;
   }
 
   @override
-  T visitTopLevelSetterGet(ast.Send node, MethodElement setter, _) {
+  TypeInformation visitTopLevelSetterGet(
+      ast.Send node, MethodElement setter, _) {
     return types.dynamicType;
   }
 
   @override
-  T visitUnresolvedGet(ast.Send node, Element element, _) {
+  TypeInformation visitUnresolvedGet(ast.Send node, Element element, _) {
     return types.dynamicType;
   }
 
   /// Handle .call invocation on [closure].
-  T handleCallInvoke(ast.Send node, T closure) {
+  TypeInformation handleCallInvoke(ast.Send node, TypeInformation closure) {
     ArgumentsTypes arguments = analyzeArguments(node.arguments);
     Selector selector = elements.getSelector(node);
     TypeMask mask = inTreeData.typeOfSend(node);
@@ -2002,32 +2659,44 @@
   }
 
   @override
-  T visitExpressionInvoke(ast.Send node, ast.Node expression,
+  TypeInformation visitExpressionInvoke(ast.Send node, ast.Node expression,
       ast.NodeList arguments, CallStructure callStructure, _) {
     return handleCallInvoke(node, expression.accept(this));
   }
 
   @override
-  T visitThisInvoke(
+  TypeInformation visitThisInvoke(
       ast.Send node, ast.NodeList arguments, CallStructure callStructure, _) {
     return handleCallInvoke(node, thisType);
   }
 
   @override
-  T visitParameterInvoke(ast.Send node, ParameterElement parameter,
-      ast.NodeList arguments, CallStructure callStructure, _) {
+  TypeInformation visitParameterInvoke(
+      ast.Send node,
+      ParameterElement parameter,
+      ast.NodeList arguments,
+      CallStructure callStructure,
+      _) {
     return handleCallInvoke(node, locals.use(parameter));
   }
 
   @override
-  T visitLocalVariableInvoke(ast.Send node, LocalVariableElement variable,
-      ast.NodeList arguments, CallStructure callStructure, _) {
+  TypeInformation visitLocalVariableInvoke(
+      ast.Send node,
+      LocalVariableElement variable,
+      ast.NodeList arguments,
+      CallStructure callStructure,
+      _) {
     return handleCallInvoke(node, locals.use(variable));
   }
 
   @override
-  T visitLocalFunctionInvoke(ast.Send node, LocalFunctionElement function,
-      ast.NodeList arguments, CallStructure callStructure, _) {
+  TypeInformation visitLocalFunctionInvoke(
+      ast.Send node,
+      LocalFunctionElement function,
+      ast.NodeList arguments,
+      CallStructure callStructure,
+      _) {
     ArgumentsTypes argumentTypes = analyzeArguments(node.arguments);
     Selector selector = elements.getSelector(node);
     TypeMask mask = inTreeData.typeOfSend(node);
@@ -2039,7 +2708,7 @@
   }
 
   @override
-  T visitLocalFunctionIncompatibleInvoke(
+  TypeInformation visitLocalFunctionIncompatibleInvoke(
       ast.Send node,
       LocalFunctionElement function,
       ast.NodeList arguments,
@@ -2049,8 +2718,8 @@
     return types.dynamicType;
   }
 
-  T handleStaticSend(ast.Node node, Selector selector, TypeMask mask,
-      Element element, ArgumentsTypes arguments) {
+  TypeInformation handleStaticSend(ast.Node node, Selector selector,
+      TypeMask mask, Element element, ArgumentsTypes arguments) {
     assert(!element.isFactoryConstructor ||
         !(element as ConstructorElement).isRedirectingFactory);
     // Erroneous elements may be unresolved, for example missing getters.
@@ -2062,8 +2731,8 @@
         outermostElement, element, arguments, sideEffects, inLoop);
   }
 
-  T handleDynamicSend(ast.Node node, Selector selector, TypeMask mask,
-      T receiverType, ArgumentsTypes arguments) {
+  TypeInformation handleDynamicSend(ast.Node node, Selector selector,
+      TypeMask mask, TypeInformation receiverType, ArgumentsTypes arguments) {
     assert(receiverType != null);
     if (types.selectorNeedsUpdate(receiverType, mask)) {
       mask = receiverType == types.dynamicType
@@ -2081,7 +2750,7 @@
       if (receiver != null) {
         Element element = elements[receiver];
         if (Elements.isLocal(element) && !capturedVariables.contains(element)) {
-          T refinedType = types.refineReceiver(
+          TypeInformation refinedType = types.refineReceiver(
               selector, mask, receiverType, send.isConditional);
           locals.update(element, refinedType, node);
         }
@@ -2092,17 +2761,17 @@
         outermostElement, arguments, sideEffects, inLoop);
   }
 
-  T handleDynamicInvoke(ast.Send node) {
+  TypeInformation handleDynamicInvoke(ast.Send node) {
     return _handleDynamicSend(node);
   }
 
-  T handleDynamicGet(ast.Send node) {
+  TypeInformation handleDynamicGet(ast.Send node) {
     return _handleDynamicSend(node);
   }
 
-  T _handleDynamicSend(ast.Send node) {
+  TypeInformation _handleDynamicSend(ast.Send node) {
     Element element = elements[node];
-    T receiverType;
+    TypeInformation receiverType;
     bool isCallOnThis = false;
     if (node.receiver == null) {
       if (treatAsInstanceMember(element)) {
@@ -2135,11 +2804,12 @@
     return handleDynamicSend(node, selector, mask, receiverType, arguments);
   }
 
-  void recordReturnType(T type) {
+  void recordReturnType(TypeInformation type) {
     returnType = inferrer.addReturnTypeFor(analyzedElement, returnType, type);
   }
 
-  T synthesizeForwardingCall(Spannable node, FunctionElement element) {
+  TypeInformation synthesizeForwardingCall(
+      Spannable node, FunctionElement element) {
     element = element.implementation;
     FunctionElement function = analyzedElement;
     FunctionSignature signature = function.functionSignature;
@@ -2148,15 +2818,15 @@
       return types.nonNullEmpty();
     }
 
-    List<T> unnamed = <T>[];
+    List<TypeInformation> unnamed = <TypeInformation>[];
     signature.forEachRequiredParameter((ParameterElement element) {
       assert(locals.use(element) != null);
       unnamed.add(locals.use(element));
     });
 
-    Map<String, T> named;
+    Map<String, TypeInformation> named;
     if (signature.optionalParametersAreNamed) {
-      named = new Map<String, T>();
+      named = new Map<String, TypeInformation>();
       signature.forEachOptionalParameter((ParameterElement element) {
         named[element.name] = locals.use(element);
       });
@@ -2166,28 +2836,29 @@
       });
     }
 
-    ArgumentsTypes arguments = new ArgumentsTypes<T>(unnamed, named);
+    ArgumentsTypes arguments = new ArgumentsTypes(unnamed, named);
     return inferrer.registerCalledElement(node, null, null, outermostElement,
         element, arguments, sideEffects, inLoop);
   }
 
-  T visitRedirectingFactoryBody(ast.RedirectingFactoryBody node) {
+  TypeInformation visitRedirectingFactoryBody(ast.RedirectingFactoryBody node) {
     Element element = elements.getRedirectingTargetConstructor(node);
     if (Elements.isMalformed(element)) {
       recordReturnType(types.dynamicType);
     } else {
-      // We don't create a selector for redirecting factories, and
+      // We don'TypeInformation create a selector for redirecting factories, and
       // the send is just a property access. Therefore we must
       // manually create the [ArgumentsTypes] of the call, and
       // manually register [analyzedElement] as a caller of [element].
-      T mask = synthesizeForwardingCall(node.constructorReference, element);
+      TypeInformation mask =
+          synthesizeForwardingCall(node.constructorReference, element);
       recordReturnType(mask);
     }
     locals.seenReturnOrThrow = true;
     return null;
   }
 
-  T visitReturn(ast.Return node) {
+  TypeInformation visitReturn(ast.Return node) {
     ast.Node expression = node.expression;
     recordReturnType(
         expression == null ? types.nullType : expression.accept(this));
@@ -2195,12 +2866,17 @@
     return null;
   }
 
-  T handleForInLoop(ast.ForIn node, T iteratorType, Selector currentSelector,
-      TypeMask currentMask, Selector moveNextSelector, TypeMask moveNextMask) {
+  TypeInformation handleForInLoop(
+      ast.ForIn node,
+      TypeInformation iteratorType,
+      Selector currentSelector,
+      TypeMask currentMask,
+      Selector moveNextSelector,
+      TypeMask moveNextMask) {
     handleDynamicSend(node, moveNextSelector, moveNextMask, iteratorType,
-        new ArgumentsTypes<T>.empty());
-    T currentType = handleDynamicSend(node, currentSelector, currentMask,
-        iteratorType, new ArgumentsTypes<T>.empty());
+        new ArgumentsTypes.empty());
+    TypeInformation currentType = handleDynamicSend(node, currentSelector,
+        currentMask, iteratorType, new ArgumentsTypes.empty());
 
     if (node.expression.isThis()) {
       // Any reasonable implementation of an iterator would expose
@@ -2213,7 +2889,7 @@
     Selector selector = elements.getSelector(identifier);
     TypeMask mask = inTreeData.typeOfSend(identifier);
 
-    T receiverType;
+    TypeInformation receiverType;
     if (element != null && element.isInstanceMember) {
       receiverType = thisType;
     } else {
@@ -2227,8 +2903,8 @@
     });
   }
 
-  T visitAsyncForIn(ast.AsyncForIn node) {
-    T expressionType = visit(node.expression);
+  TypeInformation visitAsyncForIn(ast.AsyncForIn node) {
+    TypeInformation expressionType = visit(node.expression);
 
     Selector currentSelector = Selectors.current;
     TypeMask currentMask = inTreeData.typeOfIteratorCurrent(node);
@@ -2239,15 +2915,15 @@
     Element ctor = backend.helpers.streamIteratorConstructor;
 
     /// Synthesize a call to the [StreamIterator] constructor.
-    T iteratorType = handleStaticSend(
-        node, null, null, ctor, new ArgumentsTypes<T>([expressionType], null));
+    TypeInformation iteratorType = handleStaticSend(
+        node, null, null, ctor, new ArgumentsTypes([expressionType], null));
 
     return handleForInLoop(node, iteratorType, currentSelector, currentMask,
         moveNextSelector, moveNextMask);
   }
 
-  T visitSyncForIn(ast.SyncForIn node) {
-    T expressionType = visit(node.expression);
+  TypeInformation visitSyncForIn(ast.SyncForIn node) {
+    TypeInformation expressionType = visit(node.expression);
     Selector iteratorSelector = Selectors.iterator;
     TypeMask iteratorMask = inTreeData.typeOfIterator(node);
     Selector currentSelector = Selectors.current;
@@ -2255,8 +2931,8 @@
     Selector moveNextSelector = Selectors.moveNext;
     TypeMask moveNextMask = inTreeData.typeOfIteratorMoveNext(node);
 
-    T iteratorType = handleDynamicSend(node, iteratorSelector, iteratorMask,
-        expressionType, new ArgumentsTypes<T>.empty());
+    TypeInformation iteratorType = handleDynamicSend(node, iteratorSelector,
+        iteratorMask, expressionType, new ArgumentsTypes.empty());
 
     return handleForInLoop(node, iteratorType, currentSelector, currentMask,
         moveNextSelector, moveNextMask);
diff --git a/pkg/compiler/lib/src/inferrer/type_graph_dump.dart b/pkg/compiler/lib/src/inferrer/type_graph_dump.dart
index 8024e52..1afa2d3 100644
--- a/pkg/compiler/lib/src/inferrer/type_graph_dump.dart
+++ b/pkg/compiler/lib/src/inferrer/type_graph_dump.dart
@@ -7,7 +7,7 @@
 
 import '../elements/elements.dart';
 import '../types/types.dart';
-import 'type_graph_inferrer.dart';
+import 'inferrer_engine.dart';
 import 'type_graph_nodes.dart';
 
 /// Dumps the type inference graph in Graphviz Dot format into the `typegraph`
@@ -29,7 +29,7 @@
 class TypeGraphDump {
   static const String outputDir = 'typegraph';
 
-  final TypeGraphInferrerEngine inferrer;
+  final InferrerEngine inferrer;
   final Map<TypeInformation, Set<TypeInformation>> assignmentsBeforeAnalysis =
       <TypeInformation, Set<TypeInformation>>{};
   final Map<TypeInformation, Set<TypeInformation>> assignmentsBeforeTracing =
diff --git a/pkg/compiler/lib/src/inferrer/type_graph_inferrer.dart b/pkg/compiler/lib/src/inferrer/type_graph_inferrer.dart
index 7cf3baa..0155c28 100644
--- a/pkg/compiler/lib/src/inferrer/type_graph_inferrer.dart
+++ b/pkg/compiler/lib/src/inferrer/type_graph_inferrer.dart
@@ -7,522 +7,17 @@
 import 'dart:collection' show Queue;
 
 import '../common.dart';
-import '../common/names.dart' show Identifiers;
 import '../compiler.dart' show Compiler;
-import '../constants/expressions.dart' show ConstantExpression;
-import '../constants/values.dart';
-import '../elements/resolution_types.dart' show ResolutionDartType;
 import '../elements/elements.dart';
-import '../js_backend/js_backend.dart' show Annotations, JavaScriptBackend;
-import '../resolution/tree_elements.dart' show TreeElementMapping;
-import '../tree/dartstring.dart' show DartString;
-import '../tree/tree.dart' as ast show Node, LiteralBool, TryStatement;
-import '../types/constants.dart' show computeTypeMask;
+import '../tree/tree.dart' as ast show Node;
 import '../types/masks.dart'
     show CommonMasks, ContainerTypeMask, MapTypeMask, TypeMask;
 import '../types/types.dart' show TypesInferrer;
-import '../universe/call_structure.dart' show CallStructure;
 import '../universe/selector.dart' show Selector;
-import '../universe/side_effects.dart' show SideEffects;
-import '../util/util.dart' show Setlet;
 import '../world.dart' show ClosedWorld, ClosedWorldRefiner;
-import 'closure_tracer.dart';
-import 'debug.dart' as debug;
-import 'inferrer_visitor.dart' show ArgumentsTypes, TypeSystem;
-import 'list_tracer.dart';
-import 'map_tracer.dart';
-import 'simple_types_inferrer.dart';
-import 'type_graph_dump.dart';
+import 'inferrer_engine.dart';
 import 'type_graph_nodes.dart';
 
-class TypeInformationSystem extends TypeSystem<TypeInformation> {
-  final ClosedWorld closedWorld;
-
-  /// [ElementTypeInformation]s for elements.
-  final Map<Element, TypeInformation> typeInformations =
-      new Map<Element, TypeInformation>();
-
-  /// [ListTypeInformation] for allocated lists.
-  final Map<ast.Node, TypeInformation> allocatedLists =
-      new Map<ast.Node, TypeInformation>();
-
-  /// [MapTypeInformation] for allocated Maps.
-  final Map<ast.Node, TypeInformation> allocatedMaps =
-      new Map<ast.Node, TypeInformation>();
-
-  /// Closures found during the analysis.
-  final Set<TypeInformation> allocatedClosures = new Set<TypeInformation>();
-
-  /// Cache of [ConcreteTypeInformation].
-  final Map<TypeMask, TypeInformation> concreteTypes =
-      new Map<TypeMask, TypeInformation>();
-
-  /// List of [TypeInformation]s allocated inside method bodies (calls,
-  /// narrowing, phis, and containers).
-  final List<TypeInformation> allocatedTypes = <TypeInformation>[];
-
-  Iterable<TypeInformation> get allTypes => [
-        typeInformations.values,
-        allocatedLists.values,
-        allocatedMaps.values,
-        allocatedClosures,
-        concreteTypes.values,
-        allocatedTypes
-      ].expand((x) => x);
-
-  TypeInformationSystem(this.closedWorld) {
-    nonNullEmptyType = getConcreteTypeFor(commonMasks.emptyType);
-  }
-
-  CommonMasks get commonMasks => closedWorld.commonMasks;
-
-  /// Used to group [TypeInformation] nodes by the element that triggered their
-  /// creation.
-  MemberTypeInformation _currentMember = null;
-  MemberTypeInformation get currentMember => _currentMember;
-
-  void withMember(MemberElement element, action) {
-    assert(invariant(element, _currentMember == null,
-        message: "Already constructing graph for $_currentMember."));
-    _currentMember = getInferredTypeOf(element);
-    action();
-    _currentMember = null;
-  }
-
-  TypeInformation nullTypeCache;
-  TypeInformation get nullType {
-    if (nullTypeCache != null) return nullTypeCache;
-    return nullTypeCache = getConcreteTypeFor(commonMasks.nullType);
-  }
-
-  TypeInformation intTypeCache;
-  TypeInformation get intType {
-    if (intTypeCache != null) return intTypeCache;
-    return intTypeCache = getConcreteTypeFor(commonMasks.intType);
-  }
-
-  TypeInformation uint32TypeCache;
-  TypeInformation get uint32Type {
-    if (uint32TypeCache != null) return uint32TypeCache;
-    return uint32TypeCache = getConcreteTypeFor(commonMasks.uint32Type);
-  }
-
-  TypeInformation uint31TypeCache;
-  TypeInformation get uint31Type {
-    if (uint31TypeCache != null) return uint31TypeCache;
-    return uint31TypeCache = getConcreteTypeFor(commonMasks.uint31Type);
-  }
-
-  TypeInformation positiveIntTypeCache;
-  TypeInformation get positiveIntType {
-    if (positiveIntTypeCache != null) return positiveIntTypeCache;
-    return positiveIntTypeCache =
-        getConcreteTypeFor(commonMasks.positiveIntType);
-  }
-
-  TypeInformation doubleTypeCache;
-  TypeInformation get doubleType {
-    if (doubleTypeCache != null) return doubleTypeCache;
-    return doubleTypeCache = getConcreteTypeFor(commonMasks.doubleType);
-  }
-
-  TypeInformation numTypeCache;
-  TypeInformation get numType {
-    if (numTypeCache != null) return numTypeCache;
-    return numTypeCache = getConcreteTypeFor(commonMasks.numType);
-  }
-
-  TypeInformation boolTypeCache;
-  TypeInformation get boolType {
-    if (boolTypeCache != null) return boolTypeCache;
-    return boolTypeCache = getConcreteTypeFor(commonMasks.boolType);
-  }
-
-  TypeInformation functionTypeCache;
-  TypeInformation get functionType {
-    if (functionTypeCache != null) return functionTypeCache;
-    return functionTypeCache = getConcreteTypeFor(commonMasks.functionType);
-  }
-
-  TypeInformation listTypeCache;
-  TypeInformation get listType {
-    if (listTypeCache != null) return listTypeCache;
-    return listTypeCache = getConcreteTypeFor(commonMasks.listType);
-  }
-
-  TypeInformation constListTypeCache;
-  TypeInformation get constListType {
-    if (constListTypeCache != null) return constListTypeCache;
-    return constListTypeCache = getConcreteTypeFor(commonMasks.constListType);
-  }
-
-  TypeInformation fixedListTypeCache;
-  TypeInformation get fixedListType {
-    if (fixedListTypeCache != null) return fixedListTypeCache;
-    return fixedListTypeCache = getConcreteTypeFor(commonMasks.fixedListType);
-  }
-
-  TypeInformation growableListTypeCache;
-  TypeInformation get growableListType {
-    if (growableListTypeCache != null) return growableListTypeCache;
-    return growableListTypeCache =
-        getConcreteTypeFor(commonMasks.growableListType);
-  }
-
-  TypeInformation mapTypeCache;
-  TypeInformation get mapType {
-    if (mapTypeCache != null) return mapTypeCache;
-    return mapTypeCache = getConcreteTypeFor(commonMasks.mapType);
-  }
-
-  TypeInformation constMapTypeCache;
-  TypeInformation get constMapType {
-    if (constMapTypeCache != null) return constMapTypeCache;
-    return constMapTypeCache = getConcreteTypeFor(commonMasks.constMapType);
-  }
-
-  TypeInformation stringTypeCache;
-  TypeInformation get stringType {
-    if (stringTypeCache != null) return stringTypeCache;
-    return stringTypeCache = getConcreteTypeFor(commonMasks.stringType);
-  }
-
-  TypeInformation typeTypeCache;
-  TypeInformation get typeType {
-    if (typeTypeCache != null) return typeTypeCache;
-    return typeTypeCache = getConcreteTypeFor(commonMasks.typeType);
-  }
-
-  TypeInformation dynamicTypeCache;
-  TypeInformation get dynamicType {
-    if (dynamicTypeCache != null) return dynamicTypeCache;
-    return dynamicTypeCache = getConcreteTypeFor(commonMasks.dynamicType);
-  }
-
-  TypeInformation asyncFutureTypeCache;
-  TypeInformation get asyncFutureType {
-    if (asyncFutureTypeCache != null) return asyncFutureTypeCache;
-    return asyncFutureTypeCache =
-        getConcreteTypeFor(commonMasks.asyncFutureType);
-  }
-
-  TypeInformation syncStarIterableTypeCache;
-  TypeInformation get syncStarIterableType {
-    if (syncStarIterableTypeCache != null) return syncStarIterableTypeCache;
-    return syncStarIterableTypeCache =
-        getConcreteTypeFor(commonMasks.syncStarIterableType);
-  }
-
-  TypeInformation asyncStarStreamTypeCache;
-  TypeInformation get asyncStarStreamType {
-    if (asyncStarStreamTypeCache != null) return asyncStarStreamTypeCache;
-    return asyncStarStreamTypeCache =
-        getConcreteTypeFor(commonMasks.asyncStarStreamType);
-  }
-
-  TypeInformation nonNullEmptyType;
-
-  TypeInformation stringLiteralType(DartString value) {
-    return new StringLiteralTypeInformation(value, commonMasks.stringType);
-  }
-
-  TypeInformation boolLiteralType(ast.LiteralBool value) {
-    return new BoolLiteralTypeInformation(value, commonMasks.boolType);
-  }
-
-  TypeInformation computeLUB(
-      TypeInformation firstType, TypeInformation secondType) {
-    if (firstType == null) return secondType;
-    if (firstType == secondType) return firstType;
-    if (firstType == nonNullEmptyType) return secondType;
-    if (secondType == nonNullEmptyType) return firstType;
-    if (firstType == dynamicType || secondType == dynamicType) {
-      return dynamicType;
-    }
-    return getConcreteTypeFor(
-        firstType.type.union(secondType.type, closedWorld));
-  }
-
-  bool selectorNeedsUpdate(TypeInformation info, TypeMask mask) {
-    return info.type != mask;
-  }
-
-  TypeInformation refineReceiver(Selector selector, TypeMask mask,
-      TypeInformation receiver, bool isConditional) {
-    if (receiver.type.isExact) return receiver;
-    TypeMask otherType = closedWorld.allFunctions.receiverType(selector, mask);
-    // Conditional sends (a?.b) can still narrow the possible types of `a`,
-    // however, we still need to consider that `a` may be null.
-    if (isConditional) {
-      // Note: we don't check that receiver.type.isNullable here because this is
-      // called during the graph construction.
-      otherType = otherType.nullable();
-    }
-    // If this is refining to nullable subtype of `Object` just return
-    // the receiver. We know the narrowing is useless.
-    if (otherType.isNullable && otherType.containsAll(closedWorld)) {
-      return receiver;
-    }
-    assert(TypeMask.assertIsNormalized(otherType, closedWorld));
-    TypeInformation newType = new NarrowTypeInformation(receiver, otherType);
-    allocatedTypes.add(newType);
-    return newType;
-  }
-
-  TypeInformation narrowType(
-      TypeInformation type, ResolutionDartType annotation,
-      {bool isNullable: true}) {
-    if (annotation.treatAsDynamic) return type;
-    if (annotation.isVoid) return nullType;
-    if (annotation.element == closedWorld.commonElements.objectClass &&
-        isNullable) {
-      return type;
-    }
-    TypeMask otherType;
-    if (annotation.isTypedef || annotation.isFunctionType) {
-      otherType = functionType.type;
-    } else if (annotation.isTypeVariable) {
-      // TODO(ngeoffray): Narrow to bound.
-      return type;
-    } else {
-      assert(annotation.isInterfaceType);
-      otherType = annotation.element == closedWorld.commonElements.objectClass
-          ? dynamicType.type.nonNullable()
-          : new TypeMask.nonNullSubtype(annotation.element, closedWorld);
-    }
-    if (isNullable) otherType = otherType.nullable();
-    if (type.type.isExact) {
-      return type;
-    } else {
-      assert(TypeMask.assertIsNormalized(otherType, closedWorld));
-      TypeInformation newType = new NarrowTypeInformation(type, otherType);
-      allocatedTypes.add(newType);
-      return newType;
-    }
-  }
-
-  TypeInformation narrowNotNull(TypeInformation type) {
-    if (type.type.isExact && !type.type.isNullable) {
-      return type;
-    }
-    TypeInformation newType =
-        new NarrowTypeInformation(type, dynamicType.type.nonNullable());
-    allocatedTypes.add(newType);
-    return newType;
-  }
-
-  ElementTypeInformation getInferredTypeOf(Element element) {
-    element = element.implementation;
-    return typeInformations.putIfAbsent(element, () {
-      return new ElementTypeInformation(element, this);
-    });
-  }
-
-  ConcreteTypeInformation getConcreteTypeFor(TypeMask mask) {
-    assert(mask != null);
-    return concreteTypes.putIfAbsent(mask, () {
-      return new ConcreteTypeInformation(mask);
-    });
-  }
-
-  String getInferredSignatureOf(FunctionElement function) {
-    ElementTypeInformation info = getInferredTypeOf(function);
-    FunctionElement impl = function.implementation;
-    FunctionSignature signature = impl.functionSignature;
-    var res = "";
-    signature.forEachParameter((Element parameter) {
-      TypeInformation type = getInferredTypeOf(parameter);
-      res += "${res.isEmpty ? '(' : ', '}${type.type} ${parameter.name}";
-    });
-    res += ") -> ${info.type}";
-    return res;
-  }
-
-  TypeInformation nonNullSubtype(ClassElement type) {
-    return getConcreteTypeFor(
-        new TypeMask.nonNullSubtype(type.declaration, closedWorld));
-  }
-
-  TypeInformation nonNullSubclass(ClassElement type) {
-    return getConcreteTypeFor(
-        new TypeMask.nonNullSubclass(type.declaration, closedWorld));
-  }
-
-  TypeInformation nonNullExact(ClassElement type) {
-    return getConcreteTypeFor(
-        new TypeMask.nonNullExact(type.declaration, closedWorld));
-  }
-
-  TypeInformation nonNullEmpty() {
-    return nonNullEmptyType;
-  }
-
-  bool isNull(TypeInformation type) {
-    return type == nullType;
-  }
-
-  TypeInformation allocateList(
-      TypeInformation type, ast.Node node, Element enclosing,
-      [TypeInformation elementType, int length]) {
-    ClassElement typedDataClass = closedWorld.commonElements.typedDataClass;
-    bool isTypedArray = typedDataClass != null &&
-        closedWorld.isInstantiated(typedDataClass) &&
-        type.type.satisfies(typedDataClass, closedWorld);
-    bool isConst = (type.type == commonMasks.constListType);
-    bool isFixed =
-        (type.type == commonMasks.fixedListType) || isConst || isTypedArray;
-    bool isElementInferred = isConst || isTypedArray;
-
-    int inferredLength = isFixed ? length : null;
-    TypeMask elementTypeMask =
-        isElementInferred ? elementType.type : dynamicType.type;
-    ContainerTypeMask mask = new ContainerTypeMask(
-        type.type, node, enclosing, elementTypeMask, inferredLength);
-    ElementInContainerTypeInformation element =
-        new ElementInContainerTypeInformation(currentMember, elementType);
-    element.inferred = isElementInferred;
-
-    allocatedTypes.add(element);
-    return allocatedLists[node] =
-        new ListTypeInformation(currentMember, mask, element, length);
-  }
-
-  TypeInformation allocateClosure(ast.Node node, Element element) {
-    TypeInformation result =
-        new ClosureTypeInformation(currentMember, node, element);
-    allocatedClosures.add(result);
-    return result;
-  }
-
-  TypeInformation allocateMap(
-      ConcreteTypeInformation type, ast.Node node, Element element,
-      [List<TypeInformation> keyTypes, List<TypeInformation> valueTypes]) {
-    assert(keyTypes.length == valueTypes.length);
-    bool isFixed = (type.type == commonMasks.constMapType);
-
-    TypeMask keyType, valueType;
-    if (isFixed) {
-      keyType = keyTypes.fold(nonNullEmptyType.type,
-          (type, info) => type.union(info.type, closedWorld));
-      valueType = valueTypes.fold(nonNullEmptyType.type,
-          (type, info) => type.union(info.type, closedWorld));
-    } else {
-      keyType = valueType = dynamicType.type;
-    }
-    MapTypeMask mask =
-        new MapTypeMask(type.type, node, element, keyType, valueType);
-
-    TypeInformation keyTypeInfo =
-        new KeyInMapTypeInformation(currentMember, null);
-    TypeInformation valueTypeInfo =
-        new ValueInMapTypeInformation(currentMember, null);
-    allocatedTypes.add(keyTypeInfo);
-    allocatedTypes.add(valueTypeInfo);
-
-    MapTypeInformation map =
-        new MapTypeInformation(currentMember, mask, keyTypeInfo, valueTypeInfo);
-
-    for (int i = 0; i < keyTypes.length; ++i) {
-      TypeInformation newType =
-          map.addEntryAssignment(keyTypes[i], valueTypes[i], true);
-      if (newType != null) allocatedTypes.add(newType);
-    }
-
-    // Shortcut: If we already have a first approximation of the key/value type,
-    // start propagating it early.
-    if (isFixed) map.markAsInferred();
-
-    allocatedMaps[node] = map;
-    return map;
-  }
-
-  TypeMask newTypedSelector(TypeInformation info, TypeMask mask) {
-    // Only type the selector if [info] is concrete, because the other
-    // kinds of [TypeInformation] have the empty type at this point of
-    // analysis.
-    return info.isConcrete ? info.type : mask;
-  }
-
-  TypeInformation allocateDiamondPhi(
-      TypeInformation firstInput, TypeInformation secondInput) {
-    PhiElementTypeInformation result =
-        new PhiElementTypeInformation(currentMember, null, false, null);
-    result.addAssignment(firstInput);
-    result.addAssignment(secondInput);
-    allocatedTypes.add(result);
-    return result;
-  }
-
-  PhiElementTypeInformation _addPhi(
-      ast.Node node, Local variable, inputType, bool isLoop) {
-    PhiElementTypeInformation result =
-        new PhiElementTypeInformation(currentMember, node, isLoop, variable);
-    allocatedTypes.add(result);
-    result.addAssignment(inputType);
-    return result;
-  }
-
-  PhiElementTypeInformation allocatePhi(
-      ast.Node node, Local variable, inputType) {
-    // Check if [inputType] is a phi for a local updated in
-    // the try/catch block [node]. If it is, no need to allocate a new
-    // phi.
-    if (inputType is PhiElementTypeInformation &&
-        inputType.branchNode == node &&
-        inputType.branchNode is ast.TryStatement) {
-      return inputType;
-    }
-    return _addPhi(node, variable, inputType, false);
-  }
-
-  PhiElementTypeInformation allocateLoopPhi(
-      ast.Node node, Local variable, inputType) {
-    return _addPhi(node, variable, inputType, true);
-  }
-
-  TypeInformation simplifyPhi(
-      ast.Node node, Local variable, PhiElementTypeInformation phiType) {
-    assert(phiType.branchNode == node);
-    if (phiType.assignments.length == 1) return phiType.assignments.first;
-    return phiType;
-  }
-
-  PhiElementTypeInformation addPhiInput(Local variable,
-      PhiElementTypeInformation phiType, TypeInformation newType) {
-    phiType.addAssignment(newType);
-    return phiType;
-  }
-
-  TypeMask computeTypeMask(Iterable<TypeInformation> assignments) {
-    return joinTypeMasks(assignments.map((e) => e.type));
-  }
-
-  TypeMask joinTypeMasks(Iterable<TypeMask> masks) {
-    var dynamicType = commonMasks.dynamicType;
-    // Optimization: we are iterating over masks twice, but because `masks` is a
-    // mapped iterable, we save the intermediate results to avoid computing them
-    // again.
-    var list = [];
-    for (TypeMask mask in masks) {
-      // Don't do any work on computing unions if we know that after all that
-      // work the result will be `dynamic`.
-      // TODO(sigmund): change to `mask == dynamicType` so we can continue to
-      // track the non-nullable bit.
-      if (mask.containsAll(closedWorld)) return dynamicType;
-      list.add(mask);
-    }
-
-    TypeMask newType = null;
-    for (TypeMask mask in list) {
-      newType = newType == null ? mask : newType.union(mask, closedWorld);
-      // Likewise - stop early if we already reach dynamic.
-      if (newType.containsAll(closedWorld)) return dynamicType;
-    }
-
-    return newType ?? const TypeMask.nonNullEmpty();
-  }
-}
-
 /**
  * A work queue for the inferrer. It filters out nodes that are tagged as
  * [TypeInformation.doNotEnqueue], as well as ensures through
@@ -554,805 +49,8 @@
   int get length => queue.length;
 }
 
-/**
- * An inferencing engine that computes a call graph of
- * [TypeInformation] nodes by visiting the AST of the application, and
- * then does the inferencing on the graph.
- *
- */
-class TypeGraphInferrerEngine
-    extends InferrerEngine<TypeInformation, TypeInformationSystem> {
-  final Map<Element, TypeInformation> defaultTypeOfParameter =
-      new Map<Element, TypeInformation>();
-  final List<CallSiteTypeInformation> allocatedCalls =
-      <CallSiteTypeInformation>[];
-  final WorkQueue workQueue = new WorkQueue();
-  final Element mainElement;
-  final Set<Element> analyzedElements = new Set<Element>();
-
-  /// The maximum number of times we allow a node in the graph to
-  /// change types. If a node reaches that limit, we give up
-  /// inferencing on it and give it the dynamic type.
-  final int MAX_CHANGE_COUNT = 6;
-
-  int overallRefineCount = 0;
-  int addedInGraph = 0;
-
-  TypeGraphInferrerEngine(Compiler compiler, ClosedWorld closedWorld,
-      ClosedWorldRefiner closedWorldRefiner, this.mainElement)
-      : super(compiler, closedWorld, closedWorldRefiner,
-            new TypeInformationSystem(closedWorld));
-
-  JavaScriptBackend get backend => compiler.backend;
-  Annotations get annotations => backend.annotations;
-  DiagnosticReporter get reporter => compiler.reporter;
-  CommonMasks get commonMasks => closedWorld.commonMasks;
-
-  /**
-   * A set of selector names that [List] implements, that we know return
-   * their element type.
-   */
-  final Set<Selector> returnsListElementTypeSet =
-      new Set<Selector>.from(<Selector>[
-    new Selector.getter(const PublicName('first')),
-    new Selector.getter(const PublicName('last')),
-    new Selector.getter(const PublicName('single')),
-    new Selector.call(const PublicName('singleWhere'), CallStructure.ONE_ARG),
-    new Selector.call(const PublicName('elementAt'), CallStructure.ONE_ARG),
-    new Selector.index(),
-    new Selector.call(const PublicName('removeAt'), CallStructure.ONE_ARG),
-    new Selector.call(const PublicName('removeLast'), CallStructure.NO_ARGS)
-  ]);
-
-  bool returnsListElementType(Selector selector, TypeMask mask) {
-    return mask != null &&
-        mask.isContainer &&
-        returnsListElementTypeSet.contains(selector);
-  }
-
-  bool returnsMapValueType(Selector selector, TypeMask mask) {
-    return mask != null && mask.isMap && selector.isIndex;
-  }
-
-  void analyzeListAndEnqueue(ListTypeInformation info) {
-    if (info.analyzed) return;
-    info.analyzed = true;
-
-    ListTracerVisitor tracer = new ListTracerVisitor(info, this);
-    bool succeeded = tracer.run();
-    if (!succeeded) return;
-
-    info.bailedOut = false;
-    info.elementType.inferred = true;
-    TypeMask fixedListType = commonMasks.fixedListType;
-    if (info.originalType.forwardTo == fixedListType) {
-      info.checksGrowable = tracer.callsGrowableMethod;
-    }
-    tracer.assignments.forEach(info.elementType.addAssignment);
-    // Enqueue the list for later refinement
-    workQueue.add(info);
-    workQueue.add(info.elementType);
-  }
-
-  void analyzeMapAndEnqueue(MapTypeInformation info) {
-    if (info.analyzed) return;
-    info.analyzed = true;
-    MapTracerVisitor tracer = new MapTracerVisitor(info, this);
-
-    bool succeeded = tracer.run();
-    if (!succeeded) return;
-
-    info.bailedOut = false;
-    for (int i = 0; i < tracer.keyAssignments.length; ++i) {
-      TypeInformation newType = info.addEntryAssignment(
-          tracer.keyAssignments[i], tracer.valueAssignments[i]);
-      if (newType != null) workQueue.add(newType);
-    }
-    for (TypeInformation map in tracer.mapAssignments) {
-      workQueue.addAll(info.addMapAssignment(map));
-    }
-
-    info.markAsInferred();
-    workQueue.add(info.keyType);
-    workQueue.add(info.valueType);
-    workQueue.addAll(info.typeInfoMap.values);
-    workQueue.add(info);
-  }
-
-  void runOverAllElements() {
-    if (compiler.disableTypeInference) return;
-    if (compiler.options.verbose) {
-      compiler.progress.reset();
-    }
-    sortResolvedAsts().forEach((ResolvedAst resolvedAst) {
-      if (compiler.shouldPrintProgress) {
-        reporter.log('Added $addedInGraph elements in inferencing graph.');
-        compiler.progress.reset();
-      }
-      // This also forces the creation of the [ElementTypeInformation] to ensure
-      // it is in the graph.
-      types.withMember(
-          resolvedAst.element.implementation, () => analyze(resolvedAst, null));
-    });
-    reporter.log('Added $addedInGraph elements in inferencing graph.');
-
-    TypeGraphDump dump = debug.PRINT_GRAPH ? new TypeGraphDump(this) : null;
-
-    dump?.beforeAnalysis();
-    buildWorkQueue();
-    refine();
-
-    // Try to infer element types of lists and compute their escape information.
-    types.allocatedLists.values.forEach((ListTypeInformation info) {
-      analyzeListAndEnqueue(info);
-    });
-
-    // Try to infer the key and value types for maps and compute the values'
-    // escape information.
-    types.allocatedMaps.values.forEach((MapTypeInformation info) {
-      analyzeMapAndEnqueue(info);
-    });
-
-    Set<FunctionElement> bailedOutOn = new Set<FunctionElement>();
-
-    // Trace closures to potentially infer argument types.
-    types.allocatedClosures.forEach((info) {
-      void trace(
-          Iterable<FunctionElement> elements, ClosureTracerVisitor tracer) {
-        tracer.run();
-        if (!tracer.continueAnalyzing) {
-          elements.forEach((FunctionElement e) {
-            closedWorldRefiner.registerMightBePassedToApply(e);
-            if (debug.VERBOSE) print("traced closure $e as ${true} (bail)");
-            e.functionSignature.forEachParameter((parameter) {
-              types
-                  .getInferredTypeOf(parameter)
-                  .giveUp(this, clearAssignments: false);
-            });
-          });
-          bailedOutOn.addAll(elements);
-          return;
-        }
-        elements
-            .where((e) => !bailedOutOn.contains(e))
-            .forEach((FunctionElement e) {
-          e.functionSignature.forEachParameter((parameter) {
-            var info = types.getInferredTypeOf(parameter);
-            info.maybeResume();
-            workQueue.add(info);
-          });
-          if (tracer.tracedType.mightBePassedToFunctionApply) {
-            closedWorldRefiner.registerMightBePassedToApply(e);
-          }
-          if (debug.VERBOSE) {
-            print("traced closure $e as "
-                "${closedWorldRefiner
-                    .getCurrentlyKnownMightBePassedToApply(e)}");
-          }
-        });
-      }
-
-      if (info is ClosureTypeInformation) {
-        Iterable<FunctionElement> elements = [info.element];
-        trace(elements, new ClosureTracerVisitor(elements, info, this));
-      } else if (info is CallSiteTypeInformation) {
-        if (info is StaticCallSiteTypeInformation &&
-            info.selector != null &&
-            info.selector.isCall) {
-          // This is a constructor call to a class with a call method. So we
-          // need to trace the call method here.
-          assert(info.calledElement.isConstructor);
-          ClassElement cls = info.calledElement.enclosingClass;
-          FunctionElement callMethod = cls.lookupMember(Identifiers.call);
-          assert(invariant(cls, callMethod != null));
-          Iterable<FunctionElement> elements = [callMethod];
-          trace(elements, new ClosureTracerVisitor(elements, info, this));
-        } else {
-          // We only are interested in functions here, as other targets
-          // of this closure call are not a root to trace but an intermediate
-          // for some other function.
-          Iterable<FunctionElement> elements = new List<FunctionElement>.from(
-              info.callees.where((e) => e.isFunction));
-          trace(elements, new ClosureTracerVisitor(elements, info, this));
-        }
-      } else {
-        assert(info is ElementTypeInformation);
-        trace([info.element],
-            new StaticTearOffClosureTracerVisitor(info.element, info, this));
-      }
-    });
-
-    dump?.beforeTracing();
-
-    // Reset all nodes that use lists/maps that have been inferred, as well
-    // as nodes that use elements fetched from these lists/maps. The
-    // workset for a new run of the analysis will be these nodes.
-    Set<TypeInformation> seenTypes = new Set<TypeInformation>();
-    while (!workQueue.isEmpty) {
-      TypeInformation info = workQueue.remove();
-      if (seenTypes.contains(info)) continue;
-      // If the node cannot be reset, we do not need to update its users either.
-      if (!info.reset(this)) continue;
-      seenTypes.add(info);
-      workQueue.addAll(info.users);
-    }
-
-    workQueue.addAll(seenTypes);
-    refine();
-
-    if (debug.PRINT_SUMMARY) {
-      types.allocatedLists.values.forEach((ListTypeInformation info) {
-        print('${info.type} '
-            'for ${info.originalType.allocationNode} '
-            'at ${info.originalType.allocationElement} '
-            'after ${info.refineCount}');
-      });
-      types.allocatedMaps.values.forEach((MapTypeInformation info) {
-        print('${info.type} '
-            'for ${info.originalType.allocationNode} '
-            'at ${info.originalType.allocationElement} '
-            'after ${info.refineCount}');
-      });
-      types.allocatedClosures.forEach((TypeInformation info) {
-        if (info is ElementTypeInformation) {
-          print('${types.getInferredSignatureOf(info.element)} for '
-              '${info.element}');
-        } else if (info is ClosureTypeInformation) {
-          print('${types.getInferredSignatureOf(info.element)} for '
-              '${info.element}');
-        } else if (info is DynamicCallSiteTypeInformation) {
-          for (Element target in info.targets) {
-            if (target is FunctionElement) {
-              print('${types.getInferredSignatureOf(target)} for ${target}');
-            } else {
-              print('${types.getInferredTypeOf(target).type} for ${target}');
-            }
-          }
-        } else if (info is StaticCallSiteTypeInformation) {
-          ClassElement cls = info.calledElement.enclosingClass;
-          FunctionElement callMethod = cls.lookupMember(Identifiers.call);
-          print('${types.getInferredSignatureOf(callMethod)} for ${cls}');
-        } else {
-          print('${info.type} for some unknown kind of closure');
-        }
-      });
-      analyzedElements.forEach((Element elem) {
-        TypeInformation type = types.getInferredTypeOf(elem);
-        print('${elem} :: ${type} from ${type.assignments} ');
-      });
-    }
-    dump?.afterAnalysis();
-
-    reporter.log('Inferred $overallRefineCount types.');
-
-    processLoopInformation();
-  }
-
-  void analyze(ResolvedAst resolvedAst, ArgumentsTypes arguments) {
-    AstElement element = resolvedAst.element.implementation;
-    if (analyzedElements.contains(element)) return;
-    analyzedElements.add(element);
-
-    SimpleTypeInferrerVisitor visitor =
-        new SimpleTypeInferrerVisitor(element, resolvedAst, compiler, this);
-    TypeInformation type;
-    reporter.withCurrentElement(element, () {
-      type = visitor.run();
-    });
-    addedInGraph++;
-
-    if (element.isField) {
-      VariableElement fieldElement = element;
-      ast.Node node = resolvedAst.node;
-      ast.Node initializer = resolvedAst.body;
-      if (element.isFinal || element.isConst) {
-        // If [element] is final and has an initializer, we record
-        // the inferred type.
-        if (resolvedAst.body != null) {
-          if (type is! ListTypeInformation && type is! MapTypeInformation) {
-            // For non-container types, the constant handler does
-            // constant folding that could give more precise results.
-            ConstantExpression constant = fieldElement.constant;
-            if (constant != null) {
-              ConstantValue value =
-                  compiler.backend.constants.getConstantValue(constant);
-              if (value != null) {
-                if (value.isFunction) {
-                  FunctionConstantValue functionConstant = value;
-                  MethodElement function = functionConstant.element;
-                  type = types.allocateClosure(node, function);
-                } else {
-                  // Although we might find a better type, we have to keep
-                  // the old type around to ensure that we get a complete view
-                  // of the type graph and do not drop any flow edges.
-                  TypeMask refinedType = computeTypeMask(closedWorld, value);
-                  assert(TypeMask.assertIsNormalized(refinedType, closedWorld));
-                  type = new NarrowTypeInformation(type, refinedType);
-                  types.allocatedTypes.add(type);
-                }
-              } else {
-                assert(invariant(
-                    fieldElement,
-                    fieldElement.isInstanceMember ||
-                        constant.isImplicit ||
-                        constant.isPotential,
-                    message: "Constant expression without value: "
-                        "${constant.toStructuredText()}."));
-              }
-            }
-          }
-          recordType(element, type);
-        } else if (!element.isInstanceMember) {
-          recordType(element, types.nullType);
-        }
-      } else if (initializer == null) {
-        // Only update types of static fields if there is no
-        // assignment. Instance fields are dealt with in the constructor.
-        if (Elements.isStaticOrTopLevelField(element)) {
-          recordTypeOfNonFinalField(node, element, type);
-        }
-      } else {
-        recordTypeOfNonFinalField(node, element, type);
-      }
-      if (Elements.isStaticOrTopLevelField(element) &&
-          resolvedAst.body != null &&
-          !element.isConst) {
-        var argument = resolvedAst.body;
-        // TODO(13429): We could do better here by using the
-        // constant handler to figure out if it's a lazy field or not.
-        if (argument.asSend() != null ||
-            (argument.asNewExpression() != null && !argument.isConst)) {
-          recordType(element, types.nullType);
-        }
-      }
-    } else {
-      recordReturnType(element, type);
-    }
-  }
-
-  void processLoopInformation() {
-    allocatedCalls.forEach((info) {
-      if (!info.inLoop) return;
-      if (info is StaticCallSiteTypeInformation) {
-        closedWorldRefiner.addFunctionCalledInLoop(info.calledElement);
-      } else if (info.mask != null && !info.mask.containsAll(closedWorld)) {
-        // For instance methods, we only register a selector called in a
-        // loop if it is a typed selector, to avoid marking too many
-        // methods as being called from within a loop. This cuts down
-        // on the code bloat.
-        info.targets.forEach(closedWorldRefiner.addFunctionCalledInLoop);
-      }
-    });
-  }
-
-  void refine() {
-    while (!workQueue.isEmpty) {
-      if (compiler.shouldPrintProgress) {
-        reporter.log('Inferred $overallRefineCount types.');
-        compiler.progress.reset();
-      }
-      TypeInformation info = workQueue.remove();
-      TypeMask oldType = info.type;
-      TypeMask newType = info.refine(this);
-      // Check that refinement has not accidentially changed the type.
-      assert(oldType == info.type);
-      if (info.abandonInferencing) info.doNotEnqueue = true;
-      if ((info.type = newType) != oldType) {
-        overallRefineCount++;
-        info.refineCount++;
-        if (info.refineCount > MAX_CHANGE_COUNT) {
-          if (debug.ANOMALY_WARN) {
-            print("ANOMALY WARNING: max refinement reached for $info");
-          }
-          info.giveUp(this);
-          info.type = info.refine(this);
-          info.doNotEnqueue = true;
-        }
-        workQueue.addAll(info.users);
-        if (info.hasStableType(this)) {
-          info.stabilize(this);
-        }
-      }
-    }
-  }
-
-  void buildWorkQueue() {
-    workQueue.addAll(types.typeInformations.values);
-    workQueue.addAll(types.allocatedTypes);
-    workQueue.addAll(types.allocatedClosures);
-    workQueue.addAll(allocatedCalls);
-  }
-
-  /**
-   * Update the assignments to parameters in the graph. [remove] tells
-   * wheter assignments must be added or removed. If [init] is false,
-   * parameters are added to the work queue.
-   */
-  void updateParameterAssignments(TypeInformation caller, Element callee,
-      ArgumentsTypes arguments, Selector selector, TypeMask mask,
-      {bool remove, bool addToQueue: true}) {
-    if (callee.name == Identifiers.noSuchMethod_) return;
-    if (callee.isField) {
-      if (selector.isSetter) {
-        ElementTypeInformation info = types.getInferredTypeOf(callee);
-        if (remove) {
-          info.removeAssignment(arguments.positional[0]);
-        } else {
-          info.addAssignment(arguments.positional[0]);
-        }
-        if (addToQueue) workQueue.add(info);
-      }
-    } else if (callee.isGetter) {
-      return;
-    } else if (selector != null && selector.isGetter) {
-      // We are tearing a function off and thus create a closure.
-      assert(callee.isFunction);
-      MemberTypeInformation info = types.getInferredTypeOf(callee);
-      if (remove) {
-        info.closurizedCount--;
-      } else {
-        info.closurizedCount++;
-        if (Elements.isStaticOrTopLevel(callee)) {
-          types.allocatedClosures.add(info);
-        } else {
-          // We add the call-site type information here so that we
-          // can benefit from further refinement of the selector.
-          types.allocatedClosures.add(caller);
-        }
-        FunctionElement function = callee.implementation;
-        FunctionSignature signature = function.functionSignature;
-        signature.forEachParameter((Element parameter) {
-          ParameterTypeInformation info = types.getInferredTypeOf(parameter);
-          info.tagAsTearOffClosureParameter(this);
-          if (addToQueue) workQueue.add(info);
-        });
-      }
-    } else {
-      FunctionElement function = callee.implementation;
-      FunctionSignature signature = function.functionSignature;
-      int parameterIndex = 0;
-      bool visitingRequiredParameter = true;
-      signature.forEachParameter((Element parameter) {
-        if (signature.hasOptionalParameters &&
-            parameter == signature.optionalParameters.first) {
-          visitingRequiredParameter = false;
-        }
-        TypeInformation type = visitingRequiredParameter
-            ? arguments.positional[parameterIndex]
-            : signature.optionalParametersAreNamed
-                ? arguments.named[parameter.name]
-                : parameterIndex < arguments.positional.length
-                    ? arguments.positional[parameterIndex]
-                    : null;
-        if (type == null) type = getDefaultTypeOfParameter(parameter);
-        TypeInformation info = types.getInferredTypeOf(parameter);
-        if (remove) {
-          info.removeAssignment(type);
-        } else {
-          info.addAssignment(type);
-        }
-        parameterIndex++;
-        if (addToQueue) workQueue.add(info);
-      });
-    }
-  }
-
-  /**
-   * Sets the type of a parameter's default value to [type]. If the global
-   * mapping in [defaultTypeOfParameter] already contains a type, it must be
-   * a [PlaceholderTypeInformation], which will be replaced. All its uses are
-   * updated.
-   */
-  void setDefaultTypeOfParameter(
-      ParameterElement parameter, TypeInformation type) {
-    assert(parameter.functionDeclaration.isImplementation);
-    TypeInformation existing = defaultTypeOfParameter[parameter];
-    defaultTypeOfParameter[parameter] = type;
-    TypeInformation info = types.getInferredTypeOf(parameter);
-    if (existing != null && existing is PlaceholderTypeInformation) {
-      // Replace references to [existing] to use [type] instead.
-      if (parameter.functionDeclaration.isInstanceMember) {
-        ParameterAssignments assignments = info.assignments;
-        assignments.replace(existing, type);
-      } else {
-        List<TypeInformation> assignments = info.assignments;
-        for (int i = 0; i < assignments.length; i++) {
-          if (assignments[i] == existing) {
-            assignments[i] = type;
-          }
-        }
-      }
-      // Also forward all users.
-      type.addUsersOf(existing);
-    } else {
-      assert(existing == null);
-    }
-  }
-
-  /**
-   * Returns the [TypeInformation] node for the default value of a parameter.
-   * If this is queried before it is set by [setDefaultTypeOfParameter], a
-   * [PlaceholderTypeInformation] is returned, which will later be replaced
-   * by the actual node when [setDefaultTypeOfParameter] is called.
-   *
-   * Invariant: After graph construction, no [PlaceholderTypeInformation] nodes
-   *            should be present and a default type for each parameter should
-   *            exist.
-   */
-  TypeInformation getDefaultTypeOfParameter(Element parameter) {
-    return defaultTypeOfParameter.putIfAbsent(parameter, () {
-      return new PlaceholderTypeInformation(types.currentMember);
-    });
-  }
-
-  /**
-   * Helper to inspect the [TypeGraphInferrer]'s state. To be removed by
-   * TODO(johnniwinther) once synthetic parameters get their own default
-   * values.
-   */
-  bool hasAlreadyComputedTypeOfParameterDefault(Element parameter) {
-    TypeInformation seen = defaultTypeOfParameter[parameter];
-    return (seen != null && seen is! PlaceholderTypeInformation);
-  }
-
-  TypeInformation typeOfElement(Element element) {
-    if (element is FunctionElement) return types.functionType;
-    return types.getInferredTypeOf(element);
-  }
-
-  TypeInformation returnTypeOfElement(Element element) {
-    if (element is! FunctionElement) return types.dynamicType;
-    return types.getInferredTypeOf(element);
-  }
-
-  void recordTypeOfFinalField(
-      Spannable node, Element analyzed, Element element, TypeInformation type) {
-    types.getInferredTypeOf(element).addAssignment(type);
-  }
-
-  void recordTypeOfNonFinalField(
-      Spannable node, Element element, TypeInformation type) {
-    types.getInferredTypeOf(element).addAssignment(type);
-  }
-
-  void recordType(Element element, TypeInformation type) {
-    types.getInferredTypeOf(element).addAssignment(type);
-  }
-
-  void recordReturnType(Element element, TypeInformation type) {
-    TypeInformation info = types.getInferredTypeOf(element);
-    if (element.name == '==') {
-      // Even if x.== doesn't return a bool, 'x == null' evaluates to 'false'.
-      info.addAssignment(types.boolType);
-    }
-    // TODO(ngeoffray): Clean up. We do these checks because
-    // [SimpleTypesInferrer] deals with two different inferrers.
-    if (type == null) return;
-    if (info.assignments.isEmpty) info.addAssignment(type);
-  }
-
-  TypeInformation addReturnTypeFor(
-      Element element, TypeInformation unused, TypeInformation newType) {
-    TypeInformation type = types.getInferredTypeOf(element);
-    // TODO(ngeoffray): Clean up. We do this check because
-    // [SimpleTypesInferrer] deals with two different inferrers.
-    if (element.isGenerativeConstructor) return type;
-    type.addAssignment(newType);
-    return type;
-  }
-
-  TypeInformation registerCalledElement(
-      Spannable node,
-      Selector selector,
-      TypeMask mask,
-      Element caller,
-      Element callee,
-      ArgumentsTypes arguments,
-      SideEffects sideEffects,
-      bool inLoop) {
-    CallSiteTypeInformation info = new StaticCallSiteTypeInformation(
-        types.currentMember,
-        node,
-        caller,
-        callee,
-        selector,
-        mask,
-        arguments,
-        inLoop);
-    // If this class has a 'call' method then we have essentially created a
-    // closure here. Register it as such so that it is traced.
-    if (selector != null && selector.isCall && callee.isConstructor) {
-      ClassElement cls = callee.enclosingClass.declaration;
-      if (cls.callType != null) {
-        types.allocatedClosures.add(info);
-      }
-    }
-    info.addToGraph(this);
-    allocatedCalls.add(info);
-    updateSideEffects(sideEffects, selector, callee);
-    return info;
-  }
-
-  TypeInformation registerCalledSelector(
-      ast.Node node,
-      Selector selector,
-      TypeMask mask,
-      TypeInformation receiverType,
-      Element caller,
-      ArgumentsTypes arguments,
-      SideEffects sideEffects,
-      bool inLoop) {
-    if (selector.isClosureCall) {
-      return registerCalledClosure(node, selector, mask, receiverType, caller,
-          arguments, sideEffects, inLoop);
-    }
-
-    closedWorld.allFunctions.filter(selector, mask).forEach((callee) {
-      updateSideEffects(sideEffects, selector, callee);
-    });
-
-    CallSiteTypeInformation info = new DynamicCallSiteTypeInformation(
-        types.currentMember,
-        node,
-        caller,
-        selector,
-        mask,
-        receiverType,
-        arguments,
-        inLoop);
-
-    info.addToGraph(this);
-    allocatedCalls.add(info);
-    return info;
-  }
-
-  TypeInformation registerAwait(ast.Node node, TypeInformation argument) {
-    AwaitTypeInformation info =
-        new AwaitTypeInformation(types.currentMember, node);
-    info.addAssignment(argument);
-    types.allocatedTypes.add(info);
-    return info;
-  }
-
-  TypeInformation registerCalledClosure(
-      ast.Node node,
-      Selector selector,
-      TypeMask mask,
-      TypeInformation closure,
-      Element caller,
-      ArgumentsTypes arguments,
-      SideEffects sideEffects,
-      bool inLoop) {
-    sideEffects.setDependsOnSomething();
-    sideEffects.setAllSideEffects();
-    CallSiteTypeInformation info = new ClosureCallSiteTypeInformation(
-        types.currentMember,
-        node,
-        caller,
-        selector,
-        mask,
-        closure,
-        arguments,
-        inLoop);
-    info.addToGraph(this);
-    allocatedCalls.add(info);
-    return info;
-  }
-
-  // Sorts the resolved elements by size. We do this for this inferrer
-  // to get the same results for [ListTracer] compared to the
-  // [SimpleTypesInferrer].
-  Iterable<ResolvedAst> sortResolvedAsts() {
-    int max = 0;
-    Map<int, Setlet<ResolvedAst>> methodSizes = <int, Setlet<ResolvedAst>>{};
-    compiler.enqueuer.resolution.processedEntities
-        .forEach((AstElement element) {
-      ResolvedAst resolvedAst = element.resolvedAst;
-      element = element.implementation;
-      if (element.impliesType) return;
-      assert(invariant(
-          element,
-          element.isField ||
-              element.isFunction ||
-              element.isConstructor ||
-              element.isGetter ||
-              element.isSetter,
-          message: 'Unexpected element kind: ${element.kind}'));
-      if (element.isAbstract) return;
-      // Put the other operators in buckets by length, later to be added in
-      // length order.
-      int length = 0;
-      if (resolvedAst.kind == ResolvedAstKind.PARSED) {
-        TreeElementMapping mapping = resolvedAst.elements;
-        length = mapping.getSelectorCount();
-      }
-      max = length > max ? length : max;
-      Setlet<ResolvedAst> set =
-          methodSizes.putIfAbsent(length, () => new Setlet<ResolvedAst>());
-      set.add(resolvedAst);
-    });
-
-    List<ResolvedAst> result = <ResolvedAst>[];
-    for (int i = 0; i <= max; i++) {
-      Setlet<ResolvedAst> set = methodSizes[i];
-      if (set != null) result.addAll(set);
-    }
-    return result;
-  }
-
-  void clear() {
-    void cleanup(TypeInformation info) => info.cleanup();
-
-    allocatedCalls.forEach(cleanup);
-    allocatedCalls.clear();
-
-    defaultTypeOfParameter.clear();
-
-    types.typeInformations.values.forEach(cleanup);
-
-    types.allocatedTypes.forEach(cleanup);
-    types.allocatedTypes.clear();
-
-    types.concreteTypes.clear();
-
-    types.allocatedClosures.forEach(cleanup);
-    types.allocatedClosures.clear();
-
-    analyzedElements.clear();
-    generativeConstructorsExposingThis.clear();
-
-    types.allocatedMaps.values.forEach(cleanup);
-    types.allocatedLists.values.forEach(cleanup);
-  }
-
-  Iterable<Element> getCallersOf(Element element) {
-    if (compiler.disableTypeInference) {
-      throw new UnsupportedError(
-          "Cannot query the type inferrer when type inference is disabled.");
-    }
-    MemberTypeInformation info = types.getInferredTypeOf(element);
-    return info.callers;
-  }
-
-  /**
-   * Returns the type of [element] when being called with [selector].
-   */
-  TypeInformation typeOfElementWithSelector(
-      Element element, Selector selector) {
-    if (element.name == Identifiers.noSuchMethod_ &&
-        selector.name != element.name) {
-      // An invocation can resolve to a [noSuchMethod], in which case
-      // we get the return type of [noSuchMethod].
-      return returnTypeOfElement(element);
-    } else if (selector.isGetter) {
-      if (element.isFunction) {
-        // [functionType] is null if the inferrer did not run.
-        return types.functionType == null
-            ? types.dynamicType
-            : types.functionType;
-      } else if (element.isField) {
-        return typeOfElement(element);
-      } else if (Elements.isUnresolved(element)) {
-        return types.dynamicType;
-      } else {
-        assert(element.isGetter);
-        return returnTypeOfElement(element);
-      }
-    } else if (element.isGetter || element.isField) {
-      assert(selector.isCall || selector.isSetter);
-      return types.dynamicType;
-    } else {
-      return returnTypeOfElement(element);
-    }
-  }
-
-  void recordCapturedLocalRead(Local local) {}
-
-  void recordLocalUpdate(Local local, TypeInformation type) {}
-}
-
 class TypeGraphInferrer implements TypesInferrer {
-  TypeGraphInferrerEngine inferrer;
+  InferrerEngine inferrer;
   final Compiler compiler;
   final ClosedWorld closedWorld;
   final ClosedWorldRefiner closedWorldRefiner;
@@ -1366,8 +64,8 @@
   TypeMask get _dynamicType => commonMasks.dynamicType;
 
   void analyzeMain(Element main) {
-    inferrer = new TypeGraphInferrerEngine(
-        compiler, closedWorld, closedWorldRefiner, main);
+    inferrer =
+        new InferrerEngine(compiler, closedWorld, closedWorldRefiner, main);
     inferrer.runOverAllElements();
   }
 
diff --git a/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart b/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart
index 7244856..92c2b46 100644
--- a/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart
+++ b/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart
@@ -11,7 +11,11 @@
 import '../compiler.dart' show Compiler;
 import '../constants/values.dart';
 import '../elements/resolution_types.dart'
-    show ResolutionDartType, ResolutionFunctionType, ResolutionTypeKind;
+    show
+        ResolutionDartType,
+        ResolutionFunctionType,
+        ResolutionInterfaceType,
+        ResolutionTypeKind;
 import '../elements/elements.dart';
 import '../js_backend/backend.dart';
 import '../tree/dartstring.dart' show DartString;
@@ -29,8 +33,8 @@
 import '../world.dart' show ClosedWorld;
 import 'debug.dart' as debug;
 import 'inferrer_visitor.dart' show ArgumentsTypes;
-import 'type_graph_inferrer.dart'
-    show TypeGraphInferrerEngine, TypeInformationSystem;
+import 'inferrer_engine.dart';
+import 'type_system.dart';
 
 /**
  * Common class for all nodes in the graph. The current nodes are:
@@ -156,7 +160,7 @@
     }
   }
 
-  TypeMask refine(TypeGraphInferrerEngine inferrer) {
+  TypeMask refine(InferrerEngine inferrer) {
     return abandonInferencing ? safeType(inferrer) : computeType(inferrer);
   }
 
@@ -164,17 +168,17 @@
    * Computes a new type for this [TypeInformation] node depending on its
    * potentially updated inputs.
    */
-  TypeMask computeType(TypeGraphInferrerEngine inferrer);
+  TypeMask computeType(InferrerEngine inferrer);
 
   /**
    * Returns an approximation for this [TypeInformation] node that is always
    * safe to use. Used when abandoning inference on a node.
    */
-  TypeMask safeType(TypeGraphInferrerEngine inferrer) {
+  TypeMask safeType(InferrerEngine inferrer) {
     return inferrer.types.dynamicType.type;
   }
 
-  void giveUp(TypeGraphInferrerEngine inferrer, {bool clearAssignments: true}) {
+  void giveUp(InferrerEngine inferrer, {bool clearAssignments: true}) {
     abandonInferencing = true;
     // Do not remove [this] as a user of nodes in [assignments],
     // because our tracing analysis could be interested in tracing
@@ -191,7 +195,7 @@
 
   /// Reset the analysis of this node by making its type empty.
 
-  bool reset(TypeGraphInferrerEngine inferrer) {
+  bool reset(InferrerEngine inferrer) {
     if (abandonInferencing) return false;
     type = const TypeMask.nonNullEmpty();
     refineCount = 0;
@@ -207,17 +211,17 @@
 
   /// Returns whether the type cannot change after it has been
   /// inferred.
-  bool hasStableType(TypeGraphInferrerEngine inferrer) {
+  bool hasStableType(InferrerEngine inferrer) {
     return !mightResume && assignments.every((e) => e.isStable);
   }
 
-  void removeAndClearReferences(TypeGraphInferrerEngine inferrer) {
+  void removeAndClearReferences(InferrerEngine inferrer) {
     assignments.forEach((info) {
       info.removeUser(this);
     });
   }
 
-  void stabilize(TypeGraphInferrerEngine inferrer) {
+  void stabilize(InferrerEngine inferrer) {
     removeAndClearReferences(inferrer);
     // Do not remove users because the tracing analysis could be interested
     // in tracing the users of this node.
@@ -258,7 +262,7 @@
     throw new UnsupportedError("Cannot visit placeholder");
   }
 
-  TypeMask computeType(TypeGraphInferrerEngine inferrer) {
+  TypeMask computeType(InferrerEngine inferrer) {
     throw new UnsupportedError("Cannot refine placeholder");
   }
 
@@ -345,7 +349,7 @@
   /// Marker to disable inference for closures in [handleSpecialCases].
   bool disableInferenceForClosures = true;
 
-  factory ElementTypeInformation(Element element, TypeInformationSystem types) {
+  factory ElementTypeInformation(Element element, TypeSystem types) {
     if (element.isRegularParameter || element.isInitializingFormal) {
       ParameterElement parameter = element;
       if (parameter.functionDeclaration.isInstanceMember) {
@@ -456,7 +460,7 @@
   // state of the [isStable] field inhertied from [TypeInformation].
   bool get isStable => super.isStable && !isClosurized;
 
-  TypeMask handleSpecialCases(TypeGraphInferrerEngine inferrer) {
+  TypeMask handleSpecialCases(InferrerEngine inferrer) {
     if (element.isField &&
         (!inferrer.backend.canBeUsedForGlobalOptimizations(element) ||
             inferrer.annotations.assumeDynamic(element))) {
@@ -511,8 +515,7 @@
     return null;
   }
 
-  TypeMask potentiallyNarrowType(
-      TypeMask mask, TypeGraphInferrerEngine inferrer) {
+  TypeMask potentiallyNarrowType(TypeMask mask, InferrerEngine inferrer) {
     Compiler compiler = inferrer.compiler;
     if (!compiler.options.trustTypeAnnotations &&
         !compiler.options.enableTypeAssertions &&
@@ -532,14 +535,14 @@
     return _narrowType(inferrer.closedWorld, mask, type.returnType);
   }
 
-  TypeMask computeType(TypeGraphInferrerEngine inferrer) {
+  TypeMask computeType(InferrerEngine inferrer) {
     TypeMask special = handleSpecialCases(inferrer);
     if (special != null) return potentiallyNarrowType(special, inferrer);
     return potentiallyNarrowType(
         inferrer.types.computeTypeMask(assignments), inferrer);
   }
 
-  TypeMask safeType(TypeGraphInferrerEngine inferrer) {
+  TypeMask safeType(InferrerEngine inferrer) {
     return potentiallyNarrowType(super.safeType(inferrer), inferrer);
   }
 
@@ -549,7 +552,7 @@
     return visitor.visitMemberTypeInformation(this);
   }
 
-  bool hasStableType(TypeGraphInferrerEngine inferrer) {
+  bool hasStableType(InferrerEngine inferrer) {
     // The number of assignments of non-final fields is
     // not stable. Therefore such a field cannot be stable.
     if (element.isField && !(element.isConst || element.isFinal)) {
@@ -583,15 +586,14 @@
   ParameterElement get element => super.element;
   FunctionElement get declaration => element.functionDeclaration;
 
-  ParameterTypeInformation._internal(
-      ParameterElement element, TypeInformationSystem types)
+  ParameterTypeInformation._internal(ParameterElement element, TypeSystem types)
       : super._internal(
             types.getInferredTypeOf(element.functionDeclaration), element) {
     assert(!element.functionDeclaration.isInstanceMember);
   }
 
   ParameterTypeInformation._instanceMember(
-      ParameterElement element, TypeInformationSystem types)
+      ParameterElement element, TypeSystem types)
       : super._withAssignments(
             types.getInferredTypeOf(element.functionDeclaration),
             element,
@@ -601,7 +603,7 @@
 
   bool isTearOffClosureParameter = false;
 
-  void tagAsTearOffClosureParameter(TypeGraphInferrerEngine inferrer) {
+  void tagAsTearOffClosureParameter(InferrerEngine inferrer) {
     assert(element.isRegularParameter);
     isTearOffClosureParameter = true;
     // We have to add a flow-edge for the default value (if it exists), as we
@@ -611,7 +613,7 @@
   }
 
   // TODO(herhut): Cleanup into one conditional.
-  TypeMask handleSpecialCases(TypeGraphInferrerEngine inferrer) {
+  TypeMask handleSpecialCases(InferrerEngine inferrer) {
     if (!inferrer.backend.canBeUsedForGlobalOptimizations(element) ||
         inferrer.annotations.assumeDynamic(declaration)) {
       // Do not infer types for parameters that have a correspondign annotation
@@ -659,8 +661,7 @@
     return null;
   }
 
-  TypeMask potentiallyNarrowType(
-      TypeMask mask, TypeGraphInferrerEngine inferrer) {
+  TypeMask potentiallyNarrowType(TypeMask mask, InferrerEngine inferrer) {
     Compiler compiler = inferrer.compiler;
     if (!compiler.options.trustTypeAnnotations &&
         !inferrer.annotations.trustTypeAnnotations(declaration)) {
@@ -673,18 +674,18 @@
     return _narrowType(inferrer.closedWorld, mask, element.type);
   }
 
-  TypeMask computeType(TypeGraphInferrerEngine inferrer) {
+  TypeMask computeType(InferrerEngine inferrer) {
     TypeMask special = handleSpecialCases(inferrer);
     if (special != null) return special;
     return potentiallyNarrowType(
         inferrer.types.computeTypeMask(assignments), inferrer);
   }
 
-  TypeMask safeType(TypeGraphInferrerEngine inferrer) {
+  TypeMask safeType(InferrerEngine inferrer) {
     return potentiallyNarrowType(super.safeType(inferrer), inferrer);
   }
 
-  bool hasStableType(TypeGraphInferrerEngine inferrer) {
+  bool hasStableType(InferrerEngine inferrer) {
     // The number of assignments of parameters of instance methods is
     // not stable. Therefore such a parameter cannot be stable.
     if (element.functionDeclaration.isInstanceMember) {
@@ -726,7 +727,7 @@
   String toString() => 'Call site $call $type';
 
   /// Add [this] to the graph being computed by [engine].
-  void addToGraph(TypeGraphInferrerEngine engine);
+  void addToGraph(InferrerEngine engine);
 
   /// Return an iterable over the targets of this call.
   Iterable<Element> get callees;
@@ -746,7 +747,7 @@
       bool inLoop)
       : super(context, call, enclosing, selector, mask, arguments, inLoop);
 
-  void addToGraph(TypeGraphInferrerEngine inferrer) {
+  void addToGraph(InferrerEngine inferrer) {
     MemberTypeInformation callee =
         inferrer.types.getInferredTypeOf(calledElement);
     callee.addCall(caller, call);
@@ -767,7 +768,7 @@
     return selector == null;
   }
 
-  TypeMask computeType(TypeGraphInferrerEngine inferrer) {
+  TypeMask computeType(InferrerEngine inferrer) {
     if (isSynthesized) {
       assert(arguments != null);
       return inferrer.types.getInferredTypeOf(calledElement).type;
@@ -782,13 +783,13 @@
     return visitor.visitStaticCallSiteTypeInformation(this);
   }
 
-  bool hasStableType(TypeGraphInferrerEngine inferrer) {
+  bool hasStableType(InferrerEngine inferrer) {
     return inferrer.types.getInferredTypeOf(calledElement).isStable &&
         (arguments == null || arguments.every((info) => info.isStable)) &&
         super.hasStableType(inferrer);
   }
 
-  void removeAndClearReferences(TypeGraphInferrerEngine inferrer) {
+  void removeAndClearReferences(InferrerEngine inferrer) {
     ElementTypeInformation callee =
         inferrer.types.getInferredTypeOf(calledElement);
     callee.removeUser(this);
@@ -816,7 +817,7 @@
       bool inLoop)
       : super(context, call, enclosing, selector, mask, arguments, inLoop);
 
-  void addToGraph(TypeGraphInferrerEngine inferrer) {
+  void addToGraph(InferrerEngine inferrer) {
     assert(receiver != null);
     TypeMask typeMask = computeTypedSelector(inferrer);
     targets = inferrer.closedWorld.allFunctions.filter(selector, typeMask);
@@ -836,7 +837,7 @@
 
   Iterable<Element> get callees => targets.map((e) => e.implementation);
 
-  TypeMask computeTypedSelector(TypeGraphInferrerEngine inferrer) {
+  TypeMask computeTypedSelector(InferrerEngine inferrer) {
     TypeMask receiverType = receiver.type;
 
     if (mask != receiverType) {
@@ -848,7 +849,7 @@
     }
   }
 
-  bool targetsIncludeComplexNoSuchMethod(TypeGraphInferrerEngine inferrer) {
+  bool targetsIncludeComplexNoSuchMethod(InferrerEngine inferrer) {
     return targets.any((Element e) {
       return e is FunctionElement &&
           e.isInstanceMember &&
@@ -867,7 +868,7 @@
    * code.
    */
   TypeInformation handleIntrisifiedSelector(
-      Selector selector, TypeMask mask, TypeGraphInferrerEngine inferrer) {
+      Selector selector, TypeMask mask, InferrerEngine inferrer) {
     ClosedWorld closedWorld = inferrer.closedWorld;
     if (!closedWorld.backendClasses.intImplementation.isResolved) return null;
     if (mask == null) return null;
@@ -965,7 +966,7 @@
     }
   }
 
-  TypeMask computeType(TypeGraphInferrerEngine inferrer) {
+  TypeMask computeType(InferrerEngine inferrer) {
     Iterable<Element> oldTargets = targets;
     TypeMask typeMask = computeTypedSelector(inferrer);
     inferrer.updateSelectorInTree(caller, call, selector, typeMask);
@@ -1025,30 +1026,29 @@
       if (canReachAll && !typedTargets.contains(element)) {
         return const TypeMask.nonNullEmpty();
       }
-
       if (inferrer.returnsListElementType(selector, typeMask)) {
         ContainerTypeMask containerTypeMask = receiver.type;
         return containerTypeMask.elementType;
       } else if (inferrer.returnsMapValueType(selector, typeMask)) {
-        if (typeMask.isDictionary &&
-            arguments.positional[0].type.isValue &&
-            arguments.positional[0].type.value.isString) {
-          DictionaryTypeMask dictionaryTypeMask = typeMask;
-          ValueTypeMask arg = arguments.positional[0].type;
-          String key = arg.value.primitiveValue.slowToString();
-          if (dictionaryTypeMask.typeMap.containsKey(key)) {
-            if (debug.VERBOSE) {
-              print("Dictionary lookup for $key yields "
-                  "${dictionaryTypeMask.typeMap[key]}.");
+        if (typeMask.isDictionary) {
+          TypeMask arg = arguments.positional[0].type;
+          if (arg is ValueTypeMask && arg.value.isString) {
+            DictionaryTypeMask dictionaryTypeMask = typeMask;
+            String key = arg.value.primitiveValue.slowToString();
+            if (dictionaryTypeMask.typeMap.containsKey(key)) {
+              if (debug.VERBOSE) {
+                print("Dictionary lookup for $key yields "
+                    "${dictionaryTypeMask.typeMap[key]}.");
+              }
+              return dictionaryTypeMask.typeMap[key];
+            } else {
+              // The typeMap is precise, so if we do not find the key, the lookup
+              // will be [null] at runtime.
+              if (debug.VERBOSE) {
+                print("Dictionary lookup for $key yields [null].");
+              }
+              return inferrer.types.nullType.type;
             }
-            return dictionaryTypeMask.typeMap[key];
-          } else {
-            // The typeMap is precise, so if we do not find the key, the lookup
-            // will be [null] at runtime.
-            if (debug.VERBOSE) {
-              print("Dictionary lookup for $key yields [null].");
-            }
-            return inferrer.types.nullType.type;
           }
         }
         MapTypeMask mapTypeMask = typeMask;
@@ -1074,7 +1074,7 @@
     return result;
   }
 
-  void giveUp(TypeGraphInferrerEngine inferrer, {bool clearAssignments: true}) {
+  void giveUp(InferrerEngine inferrer, {bool clearAssignments: true}) {
     if (!abandonInferencing) {
       inferrer.updateSelectorInTree(caller, call, selector, mask);
       Iterable<Element> oldTargets = targets;
@@ -1093,7 +1093,7 @@
     super.giveUp(inferrer, clearAssignments: clearAssignments);
   }
 
-  void removeAndClearReferences(TypeGraphInferrerEngine inferrer) {
+  void removeAndClearReferences(InferrerEngine inferrer) {
     for (Element element in targets) {
       ElementTypeInformation callee = inferrer.types.getInferredTypeOf(element);
       callee.removeUser(this);
@@ -1110,7 +1110,7 @@
     return visitor.visitDynamicCallSiteTypeInformation(this);
   }
 
-  bool hasStableType(TypeGraphInferrerEngine inferrer) {
+  bool hasStableType(InferrerEngine inferrer) {
     return receiver.isStable &&
         targets.every(
             (element) => inferrer.types.getInferredTypeOf(element).isStable) &&
@@ -1133,12 +1133,12 @@
       bool inLoop)
       : super(context, call, enclosing, selector, mask, arguments, inLoop);
 
-  void addToGraph(TypeGraphInferrerEngine inferrer) {
+  void addToGraph(InferrerEngine inferrer) {
     arguments.forEach((info) => info.addUser(this));
     closure.addUser(this);
   }
 
-  TypeMask computeType(TypeGraphInferrerEngine inferrer) => safeType(inferrer);
+  TypeMask computeType(InferrerEngine inferrer) => safeType(inferrer);
 
   Iterable<Element> get callees {
     throw new UnsupportedError("Cannot compute callees of a closure call.");
@@ -1150,7 +1150,7 @@
     return visitor.visitClosureCallSiteTypeInformation(this);
   }
 
-  void removeAndClearReferences(TypeGraphInferrerEngine inferrer) {
+  void removeAndClearReferences(InferrerEngine inferrer) {
     // This method is a placeholder for the following comment:
     // We should maintain the information that the closure is a user
     // of its arguments because we do not check that the arguments
@@ -1199,9 +1199,9 @@
     throw "Not supported";
   }
 
-  TypeMask computeType(TypeGraphInferrerEngine inferrer) => type;
+  TypeMask computeType(InferrerEngine inferrer) => type;
 
-  bool reset(TypeGraphInferrerEngine inferrer) {
+  bool reset(InferrerEngine inferrer) {
     throw "Not supported";
   }
 
@@ -1211,7 +1211,7 @@
     return visitor.visitConcreteTypeInformation(this);
   }
 
-  bool hasStableType(TypeGraphInferrerEngine inferrer) => true;
+  bool hasStableType(InferrerEngine inferrer) => true;
 }
 
 class StringLiteralTypeInformation extends ConcreteTypeInformation {
@@ -1276,7 +1276,7 @@
     assert(assignments.length == 1);
   }
 
-  TypeMask computeType(TypeGraphInferrerEngine inferrer) {
+  TypeMask computeType(InferrerEngine inferrer) {
     TypeMask input = assignments.first.type;
     TypeMask intersection =
         input.intersection(typeAnnotation, inferrer.closedWorld);
@@ -1315,12 +1315,12 @@
     if (parentType != null) addAssignment(parentType);
   }
 
-  TypeMask computeType(TypeGraphInferrerEngine inferrer) {
+  TypeMask computeType(InferrerEngine inferrer) {
     if (!inferred) return safeType(inferrer);
     return inferrer.types.computeTypeMask(assignments);
   }
 
-  bool hasStableType(TypeGraphInferrerEngine inferrer) {
+  bool hasStableType(InferrerEngine inferrer) {
     return inferred && super.hasStableType(inferrer);
   }
 }
@@ -1361,11 +1361,11 @@
     return visitor.visitListTypeInformation(this);
   }
 
-  bool hasStableType(TypeGraphInferrerEngine inferrer) {
+  bool hasStableType(InferrerEngine inferrer) {
     return elementType.isStable && super.hasStableType(inferrer);
   }
 
-  TypeMask computeType(TypeGraphInferrerEngine inferrer) {
+  TypeMask computeType(InferrerEngine inferrer) {
     var mask = type;
     if (!mask.isContainer ||
         mask.elementType != elementType.type ||
@@ -1380,7 +1380,7 @@
     return mask;
   }
 
-  TypeMask safeType(TypeGraphInferrerEngine inferrer) => originalType;
+  TypeMask safeType(InferrerEngine inferrer) => originalType;
 
   void cleanup() {
     super.cleanup();
@@ -1486,7 +1486,7 @@
     return visitor.visitMapTypeInformation(this);
   }
 
-  TypeMask toTypeMask(TypeGraphInferrerEngine inferrer) {
+  TypeMask toTypeMask(InferrerEngine inferrer) {
     if (inDictionaryMode) {
       Map<String, TypeMask> mappings = new Map<String, TypeMask>();
       for (var key in typeInfoMap.keys) {
@@ -1509,7 +1509,7 @@
     }
   }
 
-  TypeMask computeType(TypeGraphInferrerEngine inferrer) {
+  TypeMask computeType(InferrerEngine inferrer) {
     if (type.isDictionary != inDictionaryMode) {
       return toTypeMask(inferrer);
     } else if (type.isDictionary) {
@@ -1538,9 +1538,9 @@
     return type;
   }
 
-  TypeMask safeType(TypeGraphInferrerEngine inferrer) => originalType;
+  TypeMask safeType(InferrerEngine inferrer) => originalType;
 
-  bool hasStableType(TypeGraphInferrerEngine inferrer) {
+  bool hasStableType(InferrerEngine inferrer) {
     return keyType.isStable &&
         valueType.isStable &&
         super.hasStableType(inferrer);
@@ -1596,7 +1596,7 @@
     return visitor.visitValueInMapTypeInformation(this);
   }
 
-  TypeMask computeType(TypeGraphInferrerEngine inferrer) {
+  TypeMask computeType(InferrerEngine inferrer) {
     return nonNull
         ? super.computeType(inferrer)
         : super.computeType(inferrer).nullable();
@@ -1618,7 +1618,7 @@
       this.isLoopPhi, this.variable)
       : super(context);
 
-  TypeMask computeType(TypeGraphInferrerEngine inferrer) {
+  TypeMask computeType(InferrerEngine inferrer) {
     return inferrer.types.computeTypeMask(assignments);
   }
 
@@ -1637,9 +1637,9 @@
   ClosureTypeInformation(MemberTypeInformation context, this.node, this.element)
       : super(context);
 
-  TypeMask computeType(TypeGraphInferrerEngine inferrer) => safeType(inferrer);
+  TypeMask computeType(InferrerEngine inferrer) => safeType(inferrer);
 
-  TypeMask safeType(TypeGraphInferrerEngine inferrer) {
+  TypeMask safeType(InferrerEngine inferrer) {
     return inferrer.types.functionType.type;
   }
 
@@ -1649,7 +1649,7 @@
     return visitor.visitClosureTypeInformation(this);
   }
 
-  bool hasStableType(TypeGraphInferrerEngine inferrer) {
+  bool hasStableType(InferrerEngine inferrer) {
     return false;
   }
 }
@@ -1695,7 +1695,7 @@
       : super(context);
 
   // TODO(22894): Compute a better type here.
-  TypeMask computeType(TypeGraphInferrerEngine inferrer) => safeType(inferrer);
+  TypeMask computeType(InferrerEngine inferrer) => safeType(inferrer);
 
   String toString() => 'Await';
 
@@ -1739,8 +1739,8 @@
   } else if (annotation.isVoid) {
     otherType = closedWorld.commonMasks.nullType;
   } else {
-    assert(annotation.isInterfaceType);
-    otherType = new TypeMask.nonNullSubtype(annotation.element, closedWorld);
+    ResolutionInterfaceType interfaceType = annotation;
+    otherType = new TypeMask.nonNullSubtype(interfaceType.element, closedWorld);
   }
   if (isNullable) otherType = otherType.nullable();
   if (type == null) return otherType;
diff --git a/pkg/compiler/lib/src/inferrer/type_system.dart b/pkg/compiler/lib/src/inferrer/type_system.dart
new file mode 100644
index 0000000..9f51271
--- /dev/null
+++ b/pkg/compiler/lib/src/inferrer/type_system.dart
@@ -0,0 +1,556 @@
+// 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 '../common.dart';
+import '../elements/elements.dart';
+import '../elements/resolution_types.dart'
+    show ResolutionDartType, ResolutionInterfaceType;
+import '../tree/dartstring.dart';
+import '../tree/nodes.dart' as ast;
+import '../types/masks.dart';
+import '../universe/selector.dart';
+import '../world.dart';
+import 'type_graph_nodes.dart';
+
+/**
+ * The class [SimpleInferrerVisitor] will use when working on types.
+ */
+class TypeSystem {
+  final ClosedWorld closedWorld;
+
+  /// [ElementTypeInformation]s for elements.
+  final Map<Element, TypeInformation> typeInformations =
+      new Map<Element, TypeInformation>();
+
+  /// [ListTypeInformation] for allocated lists.
+  final Map<ast.Node, TypeInformation> allocatedLists =
+      new Map<ast.Node, TypeInformation>();
+
+  /// [MapTypeInformation] for allocated Maps.
+  final Map<ast.Node, TypeInformation> allocatedMaps =
+      new Map<ast.Node, TypeInformation>();
+
+  /// Closures found during the analysis.
+  final Set<TypeInformation> allocatedClosures = new Set<TypeInformation>();
+
+  /// Cache of [ConcreteTypeInformation].
+  final Map<TypeMask, TypeInformation> concreteTypes =
+      new Map<TypeMask, TypeInformation>();
+
+  /// List of [TypeInformation]s allocated inside method bodies (calls,
+  /// narrowing, phis, and containers).
+  final List<TypeInformation> allocatedTypes = <TypeInformation>[];
+
+  Iterable<TypeInformation> get allTypes => [
+        typeInformations.values,
+        allocatedLists.values,
+        allocatedMaps.values,
+        allocatedClosures,
+        concreteTypes.values,
+        allocatedTypes
+      ].expand((x) => x);
+
+  TypeSystem(this.closedWorld) {
+    nonNullEmptyType = getConcreteTypeFor(commonMasks.emptyType);
+  }
+
+  CommonMasks get commonMasks => closedWorld.commonMasks;
+
+  /// Used to group [TypeInformation] nodes by the element that triggered their
+  /// creation.
+  MemberTypeInformation _currentMember = null;
+  MemberTypeInformation get currentMember => _currentMember;
+
+  void withMember(MemberElement element, action) {
+    assert(invariant(element, _currentMember == null,
+        message: "Already constructing graph for $_currentMember."));
+    _currentMember = getInferredTypeOf(element);
+    action();
+    _currentMember = null;
+  }
+
+  TypeInformation nullTypeCache;
+  TypeInformation get nullType {
+    if (nullTypeCache != null) return nullTypeCache;
+    return nullTypeCache = getConcreteTypeFor(commonMasks.nullType);
+  }
+
+  TypeInformation intTypeCache;
+  TypeInformation get intType {
+    if (intTypeCache != null) return intTypeCache;
+    return intTypeCache = getConcreteTypeFor(commonMasks.intType);
+  }
+
+  TypeInformation uint32TypeCache;
+  TypeInformation get uint32Type {
+    if (uint32TypeCache != null) return uint32TypeCache;
+    return uint32TypeCache = getConcreteTypeFor(commonMasks.uint32Type);
+  }
+
+  TypeInformation uint31TypeCache;
+  TypeInformation get uint31Type {
+    if (uint31TypeCache != null) return uint31TypeCache;
+    return uint31TypeCache = getConcreteTypeFor(commonMasks.uint31Type);
+  }
+
+  TypeInformation positiveIntTypeCache;
+  TypeInformation get positiveIntType {
+    if (positiveIntTypeCache != null) return positiveIntTypeCache;
+    return positiveIntTypeCache =
+        getConcreteTypeFor(commonMasks.positiveIntType);
+  }
+
+  TypeInformation doubleTypeCache;
+  TypeInformation get doubleType {
+    if (doubleTypeCache != null) return doubleTypeCache;
+    return doubleTypeCache = getConcreteTypeFor(commonMasks.doubleType);
+  }
+
+  TypeInformation numTypeCache;
+  TypeInformation get numType {
+    if (numTypeCache != null) return numTypeCache;
+    return numTypeCache = getConcreteTypeFor(commonMasks.numType);
+  }
+
+  TypeInformation boolTypeCache;
+  TypeInformation get boolType {
+    if (boolTypeCache != null) return boolTypeCache;
+    return boolTypeCache = getConcreteTypeFor(commonMasks.boolType);
+  }
+
+  TypeInformation functionTypeCache;
+  TypeInformation get functionType {
+    if (functionTypeCache != null) return functionTypeCache;
+    return functionTypeCache = getConcreteTypeFor(commonMasks.functionType);
+  }
+
+  TypeInformation listTypeCache;
+  TypeInformation get listType {
+    if (listTypeCache != null) return listTypeCache;
+    return listTypeCache = getConcreteTypeFor(commonMasks.listType);
+  }
+
+  TypeInformation constListTypeCache;
+  TypeInformation get constListType {
+    if (constListTypeCache != null) return constListTypeCache;
+    return constListTypeCache = getConcreteTypeFor(commonMasks.constListType);
+  }
+
+  TypeInformation fixedListTypeCache;
+  TypeInformation get fixedListType {
+    if (fixedListTypeCache != null) return fixedListTypeCache;
+    return fixedListTypeCache = getConcreteTypeFor(commonMasks.fixedListType);
+  }
+
+  TypeInformation growableListTypeCache;
+  TypeInformation get growableListType {
+    if (growableListTypeCache != null) return growableListTypeCache;
+    return growableListTypeCache =
+        getConcreteTypeFor(commonMasks.growableListType);
+  }
+
+  TypeInformation mapTypeCache;
+  TypeInformation get mapType {
+    if (mapTypeCache != null) return mapTypeCache;
+    return mapTypeCache = getConcreteTypeFor(commonMasks.mapType);
+  }
+
+  TypeInformation constMapTypeCache;
+  TypeInformation get constMapType {
+    if (constMapTypeCache != null) return constMapTypeCache;
+    return constMapTypeCache = getConcreteTypeFor(commonMasks.constMapType);
+  }
+
+  TypeInformation stringTypeCache;
+  TypeInformation get stringType {
+    if (stringTypeCache != null) return stringTypeCache;
+    return stringTypeCache = getConcreteTypeFor(commonMasks.stringType);
+  }
+
+  TypeInformation typeTypeCache;
+  TypeInformation get typeType {
+    if (typeTypeCache != null) return typeTypeCache;
+    return typeTypeCache = getConcreteTypeFor(commonMasks.typeType);
+  }
+
+  TypeInformation dynamicTypeCache;
+  TypeInformation get dynamicType {
+    if (dynamicTypeCache != null) return dynamicTypeCache;
+    return dynamicTypeCache = getConcreteTypeFor(commonMasks.dynamicType);
+  }
+
+  TypeInformation asyncFutureTypeCache;
+  // Subtype of Future returned by async methods.
+  TypeInformation get asyncFutureType {
+    if (asyncFutureTypeCache != null) return asyncFutureTypeCache;
+    return asyncFutureTypeCache =
+        getConcreteTypeFor(commonMasks.asyncFutureType);
+  }
+
+  TypeInformation syncStarIterableTypeCache;
+  TypeInformation get syncStarIterableType {
+    if (syncStarIterableTypeCache != null) return syncStarIterableTypeCache;
+    return syncStarIterableTypeCache =
+        getConcreteTypeFor(commonMasks.syncStarIterableType);
+  }
+
+  TypeInformation asyncStarStreamTypeCache;
+  TypeInformation get asyncStarStreamType {
+    if (asyncStarStreamTypeCache != null) return asyncStarStreamTypeCache;
+    return asyncStarStreamTypeCache =
+        getConcreteTypeFor(commonMasks.asyncStarStreamType);
+  }
+
+  TypeInformation nonNullEmptyType;
+
+  TypeInformation stringLiteralType(DartString value) {
+    return new StringLiteralTypeInformation(value, commonMasks.stringType);
+  }
+
+  TypeInformation boolLiteralType(ast.LiteralBool value) {
+    return new BoolLiteralTypeInformation(value, commonMasks.boolType);
+  }
+
+  /**
+   * Returns the least upper bound between [firstType] and
+   * [secondType].
+   */
+  TypeInformation computeLUB(
+      TypeInformation firstType, TypeInformation secondType) {
+    if (firstType == null) return secondType;
+    if (firstType == secondType) return firstType;
+    if (firstType == nonNullEmptyType) return secondType;
+    if (secondType == nonNullEmptyType) return firstType;
+    if (firstType == dynamicType || secondType == dynamicType) {
+      return dynamicType;
+    }
+    return getConcreteTypeFor(
+        firstType.type.union(secondType.type, closedWorld));
+  }
+
+  /**
+   * Returns `true` if `selector` should be updated to reflect the new
+   * `receiverType`.
+   */
+  bool selectorNeedsUpdate(TypeInformation info, TypeMask mask) {
+    return info.type != mask;
+  }
+
+  /**
+   * Returns a new receiver type for this [selector] applied to
+   * [receiverType].
+   *
+   * The option [isConditional] is true when [selector] was seen in a
+   * conditional send (e.g.  `a?.selector`), in which case the returned type may
+   * be null.
+   */
+  TypeInformation refineReceiver(Selector selector, TypeMask mask,
+      TypeInformation receiver, bool isConditional) {
+    if (receiver.type.isExact) return receiver;
+    TypeMask otherType = closedWorld.allFunctions.receiverType(selector, mask);
+    // Conditional sends (a?.b) can still narrow the possible types of `a`,
+    // however, we still need to consider that `a` may be null.
+    if (isConditional) {
+      // Note: we don't check that receiver.type.isNullable here because this is
+      // called during the graph construction.
+      otherType = otherType.nullable();
+    }
+    // If this is refining to nullable subtype of `Object` just return
+    // the receiver. We know the narrowing is useless.
+    if (otherType.isNullable && otherType.containsAll(closedWorld)) {
+      return receiver;
+    }
+    assert(TypeMask.assertIsNormalized(otherType, closedWorld));
+    TypeInformation newType = new NarrowTypeInformation(receiver, otherType);
+    allocatedTypes.add(newType);
+    return newType;
+  }
+
+  /**
+   * Returns the intersection between [type] and [annotation].
+   * [isNullable] indicates whether the annotation implies a null
+   * type.
+   */
+  TypeInformation narrowType(
+      TypeInformation type, ResolutionDartType annotation,
+      {bool isNullable: true}) {
+    if (annotation.treatAsDynamic) return type;
+    if (annotation.isVoid) return nullType;
+    if (annotation.element == closedWorld.commonElements.objectClass &&
+        isNullable) {
+      return type;
+    }
+    TypeMask otherType;
+    if (annotation.isTypedef || annotation.isFunctionType) {
+      otherType = functionType.type;
+    } else if (annotation.isTypeVariable) {
+      // TODO(ngeoffray): Narrow to bound.
+      return type;
+    } else {
+      ResolutionInterfaceType interface = annotation;
+      otherType = annotation.element == closedWorld.commonElements.objectClass
+          ? dynamicType.type.nonNullable()
+          : new TypeMask.nonNullSubtype(interface.element, closedWorld);
+    }
+    if (isNullable) otherType = otherType.nullable();
+    if (type.type.isExact) {
+      return type;
+    } else {
+      assert(TypeMask.assertIsNormalized(otherType, closedWorld));
+      TypeInformation newType = new NarrowTypeInformation(type, otherType);
+      allocatedTypes.add(newType);
+      return newType;
+    }
+  }
+
+  /**
+   * Returns the non-nullable type of [type].
+   */
+  TypeInformation narrowNotNull(TypeInformation type) {
+    if (type.type.isExact && !type.type.isNullable) {
+      return type;
+    }
+    TypeInformation newType =
+        new NarrowTypeInformation(type, dynamicType.type.nonNullable());
+    allocatedTypes.add(newType);
+    return newType;
+  }
+
+  ElementTypeInformation getInferredTypeOf(Element element) {
+    element = element.implementation;
+    return typeInformations.putIfAbsent(element, () {
+      return new ElementTypeInformation(element, this);
+    });
+  }
+
+  /**
+   * Returns the internal inferrer representation for [mask].
+   */
+  ConcreteTypeInformation getConcreteTypeFor(TypeMask mask) {
+    assert(mask != null);
+    return concreteTypes.putIfAbsent(mask, () {
+      return new ConcreteTypeInformation(mask);
+    });
+  }
+
+  String getInferredSignatureOf(FunctionElement function) {
+    ElementTypeInformation info = getInferredTypeOf(function);
+    FunctionElement impl = function.implementation;
+    FunctionSignature signature = impl.functionSignature;
+    var res = "";
+    signature.forEachParameter((Element parameter) {
+      TypeInformation type = getInferredTypeOf(parameter);
+      res += "${res.isEmpty ? '(' : ', '}${type.type} ${parameter.name}";
+    });
+    res += ") -> ${info.type}";
+    return res;
+  }
+
+  TypeInformation nonNullSubtype(ClassElement type) {
+    return getConcreteTypeFor(
+        new TypeMask.nonNullSubtype(type.declaration, closedWorld));
+  }
+
+  TypeInformation nonNullSubclass(ClassElement type) {
+    return getConcreteTypeFor(
+        new TypeMask.nonNullSubclass(type.declaration, closedWorld));
+  }
+
+  TypeInformation nonNullExact(ClassElement type) {
+    return getConcreteTypeFor(
+        new TypeMask.nonNullExact(type.declaration, closedWorld));
+  }
+
+  TypeInformation nonNullEmpty() {
+    return nonNullEmptyType;
+  }
+
+  bool isNull(TypeInformation type) {
+    return type == nullType;
+  }
+
+  TypeInformation allocateList(
+      TypeInformation type, ast.Node node, Element enclosing,
+      [TypeInformation elementType, int length]) {
+    ClassElement typedDataClass = closedWorld.commonElements.typedDataClass;
+    bool isTypedArray = typedDataClass != null &&
+        closedWorld.isInstantiated(typedDataClass) &&
+        type.type.satisfies(typedDataClass, closedWorld);
+    bool isConst = (type.type == commonMasks.constListType);
+    bool isFixed =
+        (type.type == commonMasks.fixedListType) || isConst || isTypedArray;
+    bool isElementInferred = isConst || isTypedArray;
+
+    int inferredLength = isFixed ? length : null;
+    TypeMask elementTypeMask =
+        isElementInferred ? elementType.type : dynamicType.type;
+    ContainerTypeMask mask = new ContainerTypeMask(
+        type.type, node, enclosing, elementTypeMask, inferredLength);
+    ElementInContainerTypeInformation element =
+        new ElementInContainerTypeInformation(currentMember, elementType);
+    element.inferred = isElementInferred;
+
+    allocatedTypes.add(element);
+    return allocatedLists[node] =
+        new ListTypeInformation(currentMember, mask, element, length);
+  }
+
+  TypeInformation allocateClosure(ast.Node node, Element element) {
+    TypeInformation result =
+        new ClosureTypeInformation(currentMember, node, element);
+    allocatedClosures.add(result);
+    return result;
+  }
+
+  TypeInformation allocateMap(
+      ConcreteTypeInformation type, ast.Node node, Element element,
+      [List<TypeInformation> keyTypes, List<TypeInformation> valueTypes]) {
+    assert(keyTypes.length == valueTypes.length);
+    bool isFixed = (type.type == commonMasks.constMapType);
+
+    TypeMask keyType, valueType;
+    if (isFixed) {
+      keyType = keyTypes.fold(nonNullEmptyType.type,
+          (type, info) => type.union(info.type, closedWorld));
+      valueType = valueTypes.fold(nonNullEmptyType.type,
+          (type, info) => type.union(info.type, closedWorld));
+    } else {
+      keyType = valueType = dynamicType.type;
+    }
+    MapTypeMask mask =
+        new MapTypeMask(type.type, node, element, keyType, valueType);
+
+    TypeInformation keyTypeInfo =
+        new KeyInMapTypeInformation(currentMember, null);
+    TypeInformation valueTypeInfo =
+        new ValueInMapTypeInformation(currentMember, null);
+    allocatedTypes.add(keyTypeInfo);
+    allocatedTypes.add(valueTypeInfo);
+
+    MapTypeInformation map =
+        new MapTypeInformation(currentMember, mask, keyTypeInfo, valueTypeInfo);
+
+    for (int i = 0; i < keyTypes.length; ++i) {
+      TypeInformation newType =
+          map.addEntryAssignment(keyTypes[i], valueTypes[i], true);
+      if (newType != null) allocatedTypes.add(newType);
+    }
+
+    // Shortcut: If we already have a first approximation of the key/value type,
+    // start propagating it early.
+    if (isFixed) map.markAsInferred();
+
+    allocatedMaps[node] = map;
+    return map;
+  }
+
+  TypeMask newTypedSelector(TypeInformation info, TypeMask mask) {
+    // Only type the selector if [info] is concrete, because the other
+    // kinds of [TypeInformation] have the empty type at this point of
+    // analysis.
+    return info.isConcrete ? info.type : mask;
+  }
+
+  /**
+   * Returns a new type that unions [firstInput] and [secondInput].
+   */
+  TypeInformation allocateDiamondPhi(
+      TypeInformation firstInput, TypeInformation secondInput) {
+    PhiElementTypeInformation result =
+        new PhiElementTypeInformation(currentMember, null, false, null);
+    result.addAssignment(firstInput);
+    result.addAssignment(secondInput);
+    allocatedTypes.add(result);
+    return result;
+  }
+
+  PhiElementTypeInformation _addPhi(
+      ast.Node node, Local variable, inputType, bool isLoop) {
+    PhiElementTypeInformation result =
+        new PhiElementTypeInformation(currentMember, node, isLoop, variable);
+    allocatedTypes.add(result);
+    result.addAssignment(inputType);
+    return result;
+  }
+
+  /**
+   * Returns a new type for holding the potential types of [element].
+   * [inputType] is the first incoming type of the phi.
+   */
+  PhiElementTypeInformation allocatePhi(
+      ast.Node node, Local variable, inputType) {
+    // Check if [inputType] is a phi for a local updated in
+    // the try/catch block [node]. If it is, no need to allocate a new
+    // phi.
+    if (inputType is PhiElementTypeInformation &&
+        inputType.branchNode == node &&
+        inputType.branchNode is ast.TryStatement) {
+      return inputType;
+    }
+    return _addPhi(node, variable, inputType, false);
+  }
+
+  /**
+   * Returns a new type for holding the potential types of [element].
+   * [inputType] is the first incoming type of the phi. [allocateLoopPhi]
+   * only differs from [allocatePhi] in that it allows the underlying
+   * implementation of [TypeSystem] to differentiate Phi nodes due to loops
+   * from other merging uses.
+   */
+  PhiElementTypeInformation allocateLoopPhi(
+      ast.Node node, Local variable, inputType) {
+    return _addPhi(node, variable, inputType, true);
+  }
+
+  /**
+   * Simplies the phi representing [element] and of the type
+   * [phiType]. For example, if this phi has one incoming input, an
+   * implementation of this method could just return that incoming
+   * input type.
+   */
+  TypeInformation simplifyPhi(
+      ast.Node node, Local variable, PhiElementTypeInformation phiType) {
+    assert(phiType.branchNode == node);
+    if (phiType.assignments.length == 1) return phiType.assignments.first;
+    return phiType;
+  }
+
+  /**
+   * Adds [newType] as an input of [phiType].
+   */
+  PhiElementTypeInformation addPhiInput(Local variable,
+      PhiElementTypeInformation phiType, TypeInformation newType) {
+    phiType.addAssignment(newType);
+    return phiType;
+  }
+
+  TypeMask computeTypeMask(Iterable<TypeInformation> assignments) {
+    return joinTypeMasks(assignments.map((e) => e.type));
+  }
+
+  TypeMask joinTypeMasks(Iterable<TypeMask> masks) {
+    var dynamicType = commonMasks.dynamicType;
+    // Optimization: we are iterating over masks twice, but because `masks` is a
+    // mapped iterable, we save the intermediate results to avoid computing them
+    // again.
+    var list = [];
+    for (TypeMask mask in masks) {
+      // Don't do any work on computing unions if we know that after all that
+      // work the result will be `dynamic`.
+      // TODO(sigmund): change to `mask == dynamicType` so we can continue to
+      // track the non-nullable bit.
+      if (mask.containsAll(closedWorld)) return dynamicType;
+      list.add(mask);
+    }
+
+    TypeMask newType = null;
+    for (TypeMask mask in list) {
+      newType = newType == null ? mask : newType.union(mask, closedWorld);
+      // Likewise - stop early if we already reach dynamic.
+      if (newType.containsAll(closedWorld)) return dynamicType;
+    }
+
+    return newType ?? const TypeMask.nonNullEmpty();
+  }
+}
diff --git a/pkg/compiler/lib/src/js_backend/backend.dart b/pkg/compiler/lib/src/js_backend/backend.dart
index 002cf4e..95cd78e 100644
--- a/pkg/compiler/lib/src/js_backend/backend.dart
+++ b/pkg/compiler/lib/src/js_backend/backend.dart
@@ -1099,11 +1099,8 @@
 
   void computeImpactForInstantiatedConstantType(
       ResolutionDartType type, WorldImpactBuilder impactBuilder) {
-    ResolutionDartType instantiatedType =
-        type.isFunctionType ? commonElements.functionType : type;
     if (type is ResolutionInterfaceType) {
-      impactBuilder
-          .registerTypeUse(new TypeUse.instantiation(instantiatedType));
+      impactBuilder.registerTypeUse(new TypeUse.instantiation(type));
       if (classNeedsRtiField(type.element)) {
         impactBuilder.registerStaticUse(new StaticUse.staticInvoke(
             // TODO(johnniwinther): Find the right [CallStructure].
diff --git a/pkg/compiler/lib/src/js_backend/constant_system_javascript.dart b/pkg/compiler/lib/src/js_backend/constant_system_javascript.dart
index 43e516b..40dcd8f 100644
--- a/pkg/compiler/lib/src/js_backend/constant_system_javascript.dart
+++ b/pkg/compiler/lib/src/js_backend/constant_system_javascript.dart
@@ -124,6 +124,20 @@
   apply(left, right) => _addOperation.apply(left, right);
 }
 
+class JavaScriptRemainderOperation extends ArithmeticNumOperation {
+  String get name => 'remainder';
+
+  const JavaScriptRemainderOperation();
+
+  int foldInts(int left, int right) {
+    if (right == 0) return null;
+    return left.remainder(right);
+  }
+
+  num foldNums(num left, num right) => left.remainder(right);
+  apply(left, right) => left.remainder(right);
+}
+
 class JavaScriptBinaryArithmeticOperation implements BinaryOperation {
   final BinaryOperation dartArithmeticOperation;
 
@@ -233,6 +247,7 @@
       const JavaScriptBinaryArithmeticOperation(const MultiplyOperation());
   final negate = const JavaScriptNegateOperation();
   final not = const NotOperation();
+  final remainder = const JavaScriptRemainderOperation();
   final shiftLeft =
       const JavaScriptBinaryBitOperation(const ShiftLeftOperation());
   final shiftRight = const JavaScriptShiftRightOperation();
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 298d736..3d8ea6c 100644
--- a/pkg/compiler/lib/src/js_emitter/full_emitter/emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/full_emitter/emitter.dart
@@ -27,6 +27,7 @@
         FunctionElement,
         FunctionSignature,
         LibraryElement,
+        MemberElement,
         MetadataAnnotation,
         MethodElement,
         Name,
diff --git a/pkg/compiler/lib/src/js_emitter/full_emitter/nsm_emitter.dart b/pkg/compiler/lib/src/js_emitter/full_emitter/nsm_emitter.dart
index ad1ef5b..9f8cc28 100644
--- a/pkg/compiler/lib/src/js_emitter/full_emitter/nsm_emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/full_emitter/nsm_emitter.dart
@@ -61,7 +61,7 @@
         if (reflectionName != null) {
           bool accessible = closedWorld.allFunctions
               .filter(selector, null)
-              .any((Element e) => backend.isAccessibleByReflection(e));
+              .any((MemberElement e) => backend.isAccessibleByReflection(e));
           addProperty(
               namer.asName('+$reflectionName'), js(accessible ? '2' : '0'));
         }
diff --git a/pkg/compiler/lib/src/kernel/kernel_visitor.dart b/pkg/compiler/lib/src/kernel/kernel_visitor.dart
index 905ea0f..c4ec66d 100644
--- a/pkg/compiler/lib/src/kernel/kernel_visitor.dart
+++ b/pkg/compiler/lib/src/kernel/kernel_visitor.dart
@@ -1205,7 +1205,8 @@
       NodeList arguments,
       CallStructure callStructure,
       _) {
-    return buildCall(buildTypeLiteral(constant), callStructure, arguments);
+    return associateNode(
+        buildCall(buildTypeLiteral(constant), callStructure, arguments), node);
   }
 
   ir.Expression buildTypeLiteralSet(TypeConstantExpression constant, Node rhs) {
@@ -1318,8 +1319,17 @@
     Accessor accessor = (receiver == null)
         ? new ThisPropertyAccessor(irName, null, null)
         : PropertyAccessor.make(visitForValue(receiver), irName, null, null);
-    return accessor.buildNullAwareAssignment(visitForValue(rhs), null,
+    return _finishSetIfNull(node, accessor, rhs);
+  }
+
+  ir.Expression _finishSetIfNull(Send node, Accessor accessor, Node rhs) {
+    ir.Expression result = accessor.buildNullAwareAssignment(
+        visitForValue(rhs), null,
         voidContext: isVoidContext);
+    if (accessor.builtGetter != null) {
+      kernel.nodeToAst[accessor.builtGetter] = node;
+    }
+    return result;
   }
 
   @override
@@ -1551,9 +1561,8 @@
   @override
   ir.Expression visitIfNotNullDynamicPropertySetIfNull(
       Send node, Node receiver, Name name, Node rhs, _) {
-    return buildNullAwarePropertyAccessor(receiver, name)
-        .buildNullAwareAssignment(visitForValue(rhs), null,
-            voidContext: isVoidContext);
+    return _finishSetIfNull(
+        node, buildNullAwarePropertyAccessor(receiver, name), rhs);
   }
 
   ir.LogicalExpression buildLogicalExpression(
@@ -1892,9 +1901,7 @@
   ir.Expression handleLocalSetIfNulls(
       SendSet node, LocalElement local, Node rhs, _,
       {bool isSetterValid}) {
-    return new VariableAccessor(getLocal(local)).buildNullAwareAssignment(
-        visitForValue(rhs), null,
-        voidContext: isVoidContext);
+    return _finishSetIfNull(node, new VariableAccessor(getLocal(local)), rhs);
   }
 
   @override
@@ -2009,9 +2016,7 @@
     if (setterKind == CompoundSetter.INVALID) {
       setter = null;
     }
-    return buildStaticAccessor(getter, setter).buildNullAwareAssignment(
-        visitForValue(rhs), null,
-        voidContext: isVoidContext);
+    return _finishSetIfNull(node, buildStaticAccessor(getter, setter), rhs);
   }
 
   ir.VariableDeclaration getLocal(LocalElement local) {
@@ -2230,7 +2235,8 @@
       // TODO(ahe): Support deferred load.
       return new ir.InvalidExpression();
     }
-    return buildCall(buildStaticGet(getter), callStructure, arguments);
+    return associateNode(
+        buildCall(buildStaticGet(getter), callStructure, arguments), node);
   }
 
   @override
@@ -2456,9 +2462,8 @@
     if (setterKind == CompoundSetter.INVALID) {
       setter = null;
     }
-    return buildSuperPropertyAccessor(getter, setter).buildNullAwareAssignment(
-        visitForValue(rhs), null,
-        voidContext: isVoidContext);
+    return _finishSetIfNull(
+        node, buildSuperPropertyAccessor(getter, setter), rhs);
   }
 
   @override
@@ -2585,7 +2590,8 @@
   @override
   ir.MethodInvocation visitThisInvoke(
       Send node, NodeList arguments, CallStructure callStructure, _) {
-    return buildCall(new ir.ThisExpression(), callStructure, arguments);
+    return associateNode(
+        buildCall(new ir.ThisExpression(), callStructure, arguments), node);
   }
 
   Accessor buildThisPropertyAccessor(Name name) {
@@ -2672,7 +2678,8 @@
       NodeList arguments,
       CallStructure callStructure,
       _) {
-    return buildCall(buildTypeVariable(element), callStructure, arguments);
+    return associateNode(
+        buildCall(buildTypeVariable(element), callStructure, arguments), node);
   }
 
   @override
@@ -2685,9 +2692,8 @@
   @override
   ir.Expression visitTypeVariableTypeLiteralSetIfNull(
       Send node, TypeVariableElement element, Node rhs, _) {
-    return new ReadOnlyAccessor(buildTypeVariable(element))
-        .buildNullAwareAssignment(visitForValue(rhs), null,
-            voidContext: isVoidContext);
+    return _finishSetIfNull(
+        node, new ReadOnlyAccessor(buildTypeVariable(element)), rhs);
   }
 
   @override
@@ -2703,7 +2709,8 @@
       NodeList arguments,
       CallStructure callStructure,
       _) {
-    return buildCall(buildTypeLiteral(constant), callStructure, arguments);
+    return associateNode(
+        buildCall(buildTypeLiteral(constant), callStructure, arguments), node);
   }
 
   @override
@@ -2751,17 +2758,14 @@
   @override
   ir.Expression visitIndexSetIfNull(
       SendSet node, Node receiver, Node index, Node rhs, _) {
-    return buildIndexAccessor(receiver, index).buildNullAwareAssignment(
-        visitForValue(rhs), null,
-        voidContext: isVoidContext);
+    return _finishSetIfNull(node, buildIndexAccessor(receiver, index), rhs);
   }
 
   @override
   ir.Expression visitSuperIndexSetIfNull(SendSet node, MethodElement getter,
       MethodElement setter, Node index, Node rhs, _) {
-    return buildSuperIndexAccessor(index, getter, setter)
-        .buildNullAwareAssignment(visitForValue(rhs), null,
-            voidContext: isVoidContext);
+    return _finishSetIfNull(
+        node, buildSuperIndexAccessor(index, getter, setter), rhs);
   }
 
   @override
diff --git a/pkg/compiler/lib/src/resolved_uri_translator.dart b/pkg/compiler/lib/src/resolved_uri_translator.dart
index 84cdf50..e2bf954 100644
--- a/pkg/compiler/lib/src/resolved_uri_translator.dart
+++ b/pkg/compiler/lib/src/resolved_uri_translator.dart
@@ -115,6 +115,7 @@
       bool allowInternalLibraryAccess = importingLibrary != null &&
           (importingLibrary.isPlatformLibrary ||
               importingLibrary.isPatch ||
+              importingLibrary.canonicalUri.scheme == 'memory' ||
               importingLibrary.canonicalUri.path
                   .contains('sdk/tests/compiler/dart2js_native'));
 
diff --git a/pkg/compiler/lib/src/ssa/builder.dart b/pkg/compiler/lib/src/ssa/builder.dart
index 685a313..b6ef7c1 100644
--- a/pkg/compiler/lib/src/ssa/builder.dart
+++ b/pkg/compiler/lib/src/ssa/builder.dart
@@ -4018,7 +4018,7 @@
       return false;
     }
 
-    Element element = closedWorld.locateSingleElement(selector, mask);
+    MemberElement element = closedWorld.locateSingleElement(selector, mask);
     if (element != null &&
         !element.isField &&
         !(element.isGetter && selector.isCall) &&
diff --git a/pkg/compiler/lib/src/ssa/builder_kernel.dart b/pkg/compiler/lib/src/ssa/builder_kernel.dart
index a61c7e8..d978338 100644
--- a/pkg/compiler/lib/src/ssa/builder_kernel.dart
+++ b/pkg/compiler/lib/src/ssa/builder_kernel.dart
@@ -116,7 +116,7 @@
   JavaScriptBackend get backend => compiler.backend;
 
   @override
-  TreeElements get elements => resolvedAst.elements;
+  TreeElements get elements => astAdapter.elements;
 
   SourceInformationBuilder sourceInformationBuilder;
   KernelAstAdapter astAdapter;
@@ -290,16 +290,22 @@
     closeFunction();
   }
 
-  /// Maps the fields of a class to their SSA values.
+  /// Maps the instance fields of a class to their SSA values.
   Map<ir.Field, HInstruction> _collectFieldValues(ir.Class clazz) {
     final fieldValues = <ir.Field, HInstruction>{};
 
     for (var field in clazz.fields) {
-      if (field.initializer == null) {
-        fieldValues[field] = graph.addConstantNull(closedWorld);
-      } else {
-        field.initializer.accept(this);
-        fieldValues[field] = pop();
+      if (field.isInstanceMember) {
+        if (field.initializer == null) {
+          fieldValues[field] = graph.addConstantNull(closedWorld);
+        } else {
+          // Gotta update the resolvedAst when we're looking at field values
+          // outside the constructor.
+          astAdapter.pushResolvedAst(field);
+          field.initializer.accept(this);
+          fieldValues[field] = pop();
+          astAdapter.popResolvedAstStack();
+        }
       }
     }
 
@@ -386,7 +392,7 @@
     return builtArguments;
   }
 
-  /// Inlines the given super [constructor]'s initializers by collecting it's
+  /// Inlines the given super [constructor]'s initializers by collecting its
   /// field values and building its constructor initializers. We visit super
   /// constructors all the way up to the [Object] constructor.
   void _buildInlinedInitializers(ir.Constructor constructor,
@@ -793,8 +799,8 @@
     HLoopInformation loopInfo = current.loopInformation;
     HBasicBlock loopEntryBlock = current;
     HBasicBlock bodyEntryBlock = current;
-    JumpTarget target =
-        elements.getTargetDefinition(astAdapter.getNode(doStatement));
+    JumpTarget target = astAdapter.elements
+        .getTargetDefinition(astAdapter.getNode(doStatement));
     bool hasContinues = target != null && target.isContinueTarget;
     if (hasContinues) {
       // Add extra block to hang labels on.
@@ -906,8 +912,8 @@
         // Since the body of the loop has a break, we attach a synthesized label
         // to the body.
         SubGraph bodyGraph = new SubGraph(bodyEntryBlock, bodyExitBlock);
-        JumpTarget target =
-            elements.getTargetDefinition(astAdapter.getNode(doStatement));
+        JumpTarget target = astAdapter.elements
+            .getTargetDefinition(astAdapter.getNode(doStatement));
         LabelDefinition label = target.addLabel(null, 'loop');
         label.setBreakTarget();
         HLabeledBlockInformation info = new HLabeledBlockInformation(
@@ -1207,7 +1213,7 @@
     // type inference might discover a more specific type, or find nothing (in
     // dart2js unit tests).
     TypeMask mapType = new TypeMask.nonNullSubtype(
-        astAdapter.getElement(astAdapter.mapLiteralClass), closedWorld);
+        astAdapter.getClass(astAdapter.mapLiteralClass), closedWorld);
     TypeMask returnTypeMask = TypeMaskFactory.inferredReturnTypeForElement(
         astAdapter.getElement(constructor), globalInferenceResults);
     TypeMask instructionType =
@@ -2098,7 +2104,7 @@
     List<HInstruction> arguments =
         _visitArgumentsForStaticTarget(target.function, invocation.arguments);
     TypeMask typeMask = new TypeMask.nonNullExact(
-        astAdapter.getElement(target.enclosingClass), closedWorld);
+        astAdapter.getClass(target.enclosingClass), closedWorld);
     _pushStaticInvocation(target, arguments, typeMask);
   }
 
diff --git a/pkg/compiler/lib/src/ssa/codegen.dart b/pkg/compiler/lib/src/ssa/codegen.dart
index 68f7422..3ede5f6 100644
--- a/pkg/compiler/lib/src/ssa/codegen.dart
+++ b/pkg/compiler/lib/src/ssa/codegen.dart
@@ -15,13 +15,12 @@
         Entity,
         JumpTarget,
         LabelDefinition,
-        Local,
         Name,
         AsyncMarker,
         ResolvedAst,
         FunctionElement;
 import '../elements/entities.dart';
-import '../elements/resolution_types.dart';
+import '../elements/types.dart';
 import '../io/source_information.dart';
 import '../js/js.dart' as js;
 import '../js_backend/backend_helpers.dart' show BackendHelpers;
@@ -1410,6 +1409,10 @@
         .withSourceInformation(node.sourceInformation));
   }
 
+  visitRemainder(HRemainder node) {
+    return visitInvokeBinary(node, '%');
+  }
+
   visitNegate(HNegate node) => visitInvokeUnary(node, '-');
 
   visitLess(HLess node) => visitRelational(node, '<');
@@ -1829,7 +1832,7 @@
 
   visitInvokeStatic(HInvokeStatic node) {
     MemberEntity element = node.element;
-    List<ResolutionDartType> instantiatedTypes = node.instantiatedTypes;
+    List<DartType> instantiatedTypes = node.instantiatedTypes;
 
     if (instantiatedTypes != null && !instantiatedTypes.isEmpty) {
       instantiatedTypes.forEach((type) {
@@ -2564,11 +2567,11 @@
     push(new js.Binary('!=', pop(), new js.LiteralNull()));
   }
 
-  void checkType(HInstruction input, HInstruction interceptor,
-      ResolutionDartType type, SourceInformation sourceInformation,
+  void checkType(HInstruction input, HInstruction interceptor, DartType type,
+      SourceInformation sourceInformation,
       {bool negative: false}) {
     if (type.isInterfaceType) {
-      ResolutionInterfaceType interfaceType = type;
+      InterfaceType interfaceType = type;
       ClassEntity element = interfaceType.element;
       if (element == helpers.jsArrayClass) {
         checkArray(input, negative ? '!==' : '===');
@@ -2611,8 +2614,8 @@
     }
   }
 
-  void checkTypeViaProperty(HInstruction input, ResolutionDartType type,
-      SourceInformation sourceInformation,
+  void checkTypeViaProperty(
+      HInstruction input, DartType type, SourceInformation sourceInformation,
       {bool negative: false}) {
     registry.registerTypeUse(new TypeUse.isCheck(type));
 
@@ -2629,7 +2632,7 @@
     }
   }
 
-  void checkTypeViaInstanceof(HInstruction input, ResolutionDartType type,
+  void checkTypeViaInstanceof(HInstruction input, InterfaceType type,
       SourceInformation sourceInformation,
       {bool negative: false}) {
     registry.registerTypeUse(new TypeUse.isCheck(type));
@@ -2649,7 +2652,7 @@
   void handleNumberOrStringSupertypeCheck(
       HInstruction input,
       HInstruction interceptor,
-      ResolutionDartType type,
+      InterfaceType type,
       SourceInformation sourceInformation,
       {bool negative: false}) {
     assert(!identical(type.element, commonElements.listClass) &&
@@ -2675,7 +2678,7 @@
   }
 
   void handleStringSupertypeCheck(HInstruction input, HInstruction interceptor,
-      ResolutionDartType type, SourceInformation sourceInformation,
+      InterfaceType type, SourceInformation sourceInformation,
       {bool negative: false}) {
     assert(!identical(type.element, commonElements.listClass) &&
         !commonElements.isListSupertype(type.element) &&
@@ -2692,7 +2695,7 @@
   }
 
   void handleListOrSupertypeCheck(HInstruction input, HInstruction interceptor,
-      ResolutionDartType type, SourceInformation sourceInformation,
+      InterfaceType type, SourceInformation sourceInformation,
       {bool negative: false}) {
     assert(!identical(type.element, commonElements.stringClass) &&
         !commonElements.isStringOnlySupertype(type.element) &&
@@ -2718,7 +2721,7 @@
   }
 
   void emitIs(HIs node, String relation, SourceInformation sourceInformation) {
-    ResolutionDartType type = node.typeExpression;
+    DartType type = node.typeExpression;
     registry.registerTypeUse(new TypeUse.isCheck(type));
     HInstruction input = node.expression;
 
@@ -2733,7 +2736,7 @@
     } else {
       assert(node.isRawCheck);
       HInstruction interceptor = node.interceptor;
-      ResolutionInterfaceType interfaceType = type;
+      InterfaceType interfaceType = type;
       ClassEntity element = interfaceType.element;
       if (element == commonElements.nullClass) {
         if (negative) {
@@ -2875,7 +2878,7 @@
     }
 
     assert(node.isCheckedModeCheck || node.isCastTypeCheck);
-    ResolutionDartType type = node.typeExpression;
+    DartType type = node.typeExpression;
     assert(!type.isTypedef);
     if (type.isFunctionType) {
       // TODO(5022): We currently generate $isFunction checks for
@@ -2921,7 +2924,7 @@
   }
 
   void visitFunctionType(HFunctionType node) {
-    ResolutionFunctionType type = node.dartType;
+    FunctionType type = node.dartType;
     int inputCount = 0;
     use(node.inputs[inputCount++]);
     js.Expression returnType = pop();
@@ -3011,16 +3014,15 @@
       case TypeInfoExpressionKind.COMPLETE:
         int index = 0;
         js.Expression result = backend.rtiEncoder.getTypeRepresentation(
-            node.dartType,
-            (ResolutionTypeVariableType variable) => arguments[index++]);
+            node.dartType, (TypeVariableType variable) => arguments[index++]);
         assert(index == node.inputs.length);
         push(result);
         return;
 
       case TypeInfoExpressionKind.INSTANCE:
         // We expect only flat types for the INSTANCE representation.
-        assert(node.dartType ==
-            (node.dartType as ResolutionInterfaceType).element.thisType);
+        assert((node.dartType as InterfaceType).typeArguments.length ==
+            arguments.length);
         registry.registerInstantiatedClass(commonElements.listClass);
         push(new js.ArrayInitializer(arguments)
             .withSourceInformation(node.sourceInformation));
@@ -3088,7 +3090,7 @@
       use(type);
       typeArguments.add(pop());
     }
-    ResolutionInterfaceType type = node.dartType;
+    InterfaceType type = node.dartType;
     ClassEntity cls = type.element;
     var arguments = [backend.emitter.typeAccess(cls)];
     if (!typeArguments.isEmpty) {
diff --git a/pkg/compiler/lib/src/ssa/invoke_dynamic_specializers.dart b/pkg/compiler/lib/src/ssa/invoke_dynamic_specializers.dart
index e2536a5..ffdb95b 100644
--- a/pkg/compiler/lib/src/ssa/invoke_dynamic_specializers.dart
+++ b/pkg/compiler/lib/src/ssa/invoke_dynamic_specializers.dart
@@ -74,6 +74,7 @@
           if (name == 'round') return const RoundSpecializer();
         } else if (argumentCount == 1) {
           if (name == 'codeUnitAt') return const CodeUnitAtSpecializer();
+          if (name == 'remainder') return const RemainderSpecializer();
         }
       }
     }
@@ -307,11 +308,92 @@
   HInstruction newBuiltinVariant(
       HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld) {
     // Modulo cannot be mapped to the native operator (different semantics).
-    // TODO(sra): For non-negative values we can use JavaScript's %.
+
+    // We can use HRemainder if both inputs are non-negative and the receiver
+    // cannot be -0.0.  Note that -0.0 is considered to be an int, so until we
+    // track -0.0 precisely, we have to syntatically filter inputs that cannot
+    // generate -0.0.
+    bool canBePositiveZero(HInstruction input) {
+      if (input is HConstant) {
+        ConstantValue value = input.constant;
+        if (value is DoubleConstantValue && value.isZero) return true;
+        if (value is IntConstantValue && value.isZero) return true;
+        return false;
+      }
+      return true;
+    }
+
+    bool inPhi = false;
+    bool canBeNegativeZero(HInstruction input) {
+      if (input is HConstant) {
+        ConstantValue value = input.constant;
+        if (value is DoubleConstantValue && value.isMinusZero) return true;
+        return false;
+      }
+      if (input is HAdd) {
+        // '+' can only generate -0.0 when both inputs are -0.0.
+        return canBeNegativeZero(input.left) && canBeNegativeZero(input.right);
+      }
+      if (input is HSubtract) {
+        return canBeNegativeZero(input.left) && canBePositiveZero(input.right);
+      }
+      if (input is HPhi) {
+        if (inPhi) return true;
+        inPhi = true;
+        bool result = input.inputs.any(canBeNegativeZero);
+        inPhi = false;
+        return result;
+      }
+      return true;
+    }
+
+    if (inputsArePositiveIntegers(instruction, closedWorld) &&
+        !canBeNegativeZero(instruction.getDartReceiver(closedWorld))) {
+      return new HRemainder(
+          instruction.inputs[1],
+          instruction.inputs[2],
+          instruction.selector,
+          computeTypeFromInputTypes(instruction, compiler, closedWorld));
+    }
+    // TODO(sra):
+    //   a % N -->  a & (N-1), N=2^k, where a>=0, does not have -0.0 problem.
+
+    // TODO(sra): We could avoid problems with -0.0 if we generate x % y as (x +
+    // 0) % y, but we would have to fix HAdd optimizations.
+
+    // TODO(sra): We could replace $mod with HRemainder when we don't care about
+    // a -0.0 result (e.g. a % 10 == 0, a[i % 3]). This is tricky, since we
+    // don't want to ruin GVN opportunities.
     return null;
   }
 }
 
+class RemainderSpecializer extends BinaryArithmeticSpecializer {
+  const RemainderSpecializer();
+
+  TypeMask computeTypeFromInputTypes(
+      HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld) {
+    if (inputsArePositiveIntegers(instruction, closedWorld)) {
+      return closedWorld.commonMasks.positiveIntType;
+    }
+    return super.computeTypeFromInputTypes(instruction, compiler, closedWorld);
+  }
+
+  BinaryOperation operation(ConstantSystem constantSystem) {
+    return constantSystem.remainder;
+  }
+
+  HInstruction newBuiltinVariant(
+      HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld) {
+    JavaScriptBackend backend = compiler.backend;
+    return new HRemainder(
+        instruction.inputs[1],
+        instruction.inputs[2],
+        instruction.selector,
+        computeTypeFromInputTypes(instruction, compiler, closedWorld));
+  }
+}
+
 class MultiplySpecializer extends BinaryArithmeticSpecializer {
   const MultiplySpecializer();
 
diff --git a/pkg/compiler/lib/src/ssa/kernel_ast_adapter.dart b/pkg/compiler/lib/src/ssa/kernel_ast_adapter.dart
index e108ad5..a865f1c 100644
--- a/pkg/compiler/lib/src/ssa/kernel_ast_adapter.dart
+++ b/pkg/compiler/lib/src/ssa/kernel_ast_adapter.dart
@@ -36,7 +36,6 @@
 class KernelAstAdapter {
   final Kernel kernel;
   final JavaScriptBackend _backend;
-  final ResolvedAst _resolvedAst;
   final Map<ir.Node, ast.Node> _nodeToAst;
   final Map<ir.Node, Element> _nodeToElement;
   final Map<ir.VariableDeclaration, SyntheticLocal> _syntheticLocals =
@@ -44,6 +43,12 @@
   final Map<ir.LabeledStatement, KernelJumpTarget> _jumpTargets =
       <ir.LabeledStatement, KernelJumpTarget>{};
   DartTypeConverter _typeConverter;
+  ResolvedAst _resolvedAst;
+
+  /// Sometimes for resolution the resolved AST element needs to change (for
+  /// example, if we're inlining, or if we're in a constructor, but then also
+  /// constructing the field values). We keep track of this with a stack.
+  final List<ResolvedAst> _resolvedAstStack = <ResolvedAst>[];
 
   KernelAstAdapter(this.kernel, this._backend, this._resolvedAst,
       this._nodeToAst, this._nodeToElement) {
@@ -69,6 +74,19 @@
     _typeConverter = new DartTypeConverter(this);
   }
 
+  /// Push the existing resolved AST on the stack and shift the current resolved
+  /// AST to the AST that this kernel node points to.
+  void pushResolvedAst(ir.Node node) {
+    _resolvedAstStack.add(_resolvedAst);
+    _resolvedAst = (getElement(node) as AstElement).resolvedAst;
+  }
+
+  /// Pop the resolved AST stack to reset it to the previous resolved AST node.
+  void popResolvedAstStack() {
+    assert(_resolvedAstStack.isNotEmpty);
+    _resolvedAst = _resolvedAstStack.removeLast();
+  }
+
   Compiler get _compiler => _backend.compiler;
   TreeElements get elements => _resolvedAst.elements;
   DiagnosticReporter get reporter => _compiler.reporter;
@@ -299,6 +317,10 @@
   }
 
   ConstantValue getConstantFor(ir.Node node) {
+    // Some `null`s are not mapped when they correspond to errors, e.g. missing
+    // `const` initializers.
+    if (node is ir.NullLiteral) return new NullConstantValue();
+
     ConstantValue constantValue =
         _backend.constants.getConstantValueForNode(getNode(node), elements);
     assert(invariant(getNode(node), constantValue != null,
diff --git a/pkg/compiler/lib/src/ssa/kernel_impact.dart b/pkg/compiler/lib/src/ssa/kernel_impact.dart
index 740d723..fbfacea 100644
--- a/pkg/compiler/lib/src/ssa/kernel_impact.dart
+++ b/pkg/compiler/lib/src/ssa/kernel_impact.dart
@@ -332,8 +332,8 @@
         }
         ir.Node argument = node.arguments.positional.first;
         if (argument is ir.TypeLiteral && argument.type is ir.InterfaceType) {
-          impactBuilder.registerTypeUse(
-              new TypeUse.instantiation(astAdapter.getDartType(argument.type)));
+          ResolutionInterfaceType type = astAdapter.getDartType(argument.type);
+          impactBuilder.registerTypeUse(new TypeUse.instantiation(type));
         }
         break;
       case ForeignKind.NONE:
diff --git a/pkg/compiler/lib/src/ssa/nodes.dart b/pkg/compiler/lib/src/ssa/nodes.dart
index 429178e..2ce5fac 100644
--- a/pkg/compiler/lib/src/ssa/nodes.dart
+++ b/pkg/compiler/lib/src/ssa/nodes.dart
@@ -79,6 +79,7 @@
   R visitRangeConversion(HRangeConversion node);
   R visitReadModifyWrite(HReadModifyWrite node);
   R visitRef(HRef node);
+  R visitRemainder(HRemainder node);
   R visitReturn(HReturn node);
   R visitShiftLeft(HShiftLeft node);
   R visitShiftRight(HShiftRight node);
@@ -386,6 +387,7 @@
   visitRangeConversion(HRangeConversion node) => visitCheck(node);
   visitReadModifyWrite(HReadModifyWrite node) => visitInstruction(node);
   visitRef(HRef node) => node.value.accept(this);
+  visitRemainder(HRemainder node) => visitBinaryArithmetic(node);
   visitReturn(HReturn node) => visitControlFlow(node);
   visitShiftLeft(HShiftLeft node) => visitBinaryBitOp(node);
   visitShiftRight(HShiftRight node) => visitBinaryBitOp(node);
@@ -881,6 +883,7 @@
   static const int TYPE_INFO_EXPRESSION_TYPECODE = 40;
 
   static const int FOREIGN_CODE_TYPECODE = 41;
+  static const int REMAINDER_TYPECODE = 42;
 
   HInstruction(this.inputs, this.instructionType)
       : id = idCounter++,
@@ -2008,6 +2011,19 @@
   bool dataEquals(HInstruction other) => true;
 }
 
+class HRemainder extends HBinaryArithmetic {
+  HRemainder(
+      HInstruction left, HInstruction right, Selector selector, TypeMask type)
+      : super(left, right, selector, type);
+  accept(HVisitor visitor) => visitor.visitRemainder(this);
+
+  BinaryOperation operation(ConstantSystem constantSystem) =>
+      constantSystem.remainder;
+  int typeCode() => HInstruction.REMAINDER_TYPECODE;
+  bool typeEquals(other) => other is HRemainder;
+  bool dataEquals(HInstruction other) => true;
+}
+
 /**
  * An [HSwitch] instruction has one input for the incoming
  * value, and one input per constant that it can switch on.
diff --git a/pkg/compiler/lib/src/ssa/ssa_tracer.dart b/pkg/compiler/lib/src/ssa/ssa_tracer.dart
index df84e84..c76b592 100644
--- a/pkg/compiler/lib/src/ssa/ssa_tracer.dart
+++ b/pkg/compiler/lib/src/ssa/ssa_tracer.dart
@@ -452,6 +452,10 @@
     return handleInvokeBinary(node, 'TruncatingDivide');
   }
 
+  String visitRemainder(HRemainder node) {
+    return handleInvokeBinary(node, 'Remainder');
+  }
+
   String visitExitTry(HExitTry node) {
     return "ExitTry";
   }
diff --git a/pkg/compiler/lib/src/ssa/type_builder.dart b/pkg/compiler/lib/src/ssa/type_builder.dart
index 03d0ad1..a624e13 100644
--- a/pkg/compiler/lib/src/ssa/type_builder.dart
+++ b/pkg/compiler/lib/src/ssa/type_builder.dart
@@ -10,7 +10,6 @@
 import '../types/types.dart';
 import '../elements/elements.dart';
 import '../io/source_information.dart';
-import '../universe/selector.dart' show Selector;
 import '../universe/use.dart' show TypeUse;
 
 /// Functions to insert type checking, coercion, and instruction insertion
@@ -29,7 +28,7 @@
     if (!type.isInterfaceType) return original;
     if (type.isObject) return original;
     // The type element is either a class or the void element.
-    Element element = type.element;
+    ClassElement element = type.element;
     TypeMask mask = new TypeMask.subtype(element, builder.closedWorld);
     return new HTypeKnown.pinned(mask, original);
   }
@@ -235,8 +234,9 @@
     type = type.unaliased;
     assert(assertTypeInContext(type, original));
     if (type.isInterfaceType && !type.treatAsRaw) {
+      ResolutionInterfaceType interfaceType = type;
       TypeMask subtype =
-          new TypeMask.subtype(type.element, builder.closedWorld);
+          new TypeMask.subtype(interfaceType.element, builder.closedWorld);
       HInstruction representations =
           buildTypeArgumentRepresentations(type, builder.sourceElement);
       builder.add(representations);
diff --git a/pkg/compiler/lib/src/ssa/types_propagation.dart b/pkg/compiler/lib/src/ssa/types_propagation.dart
index dd21826..0500c92 100644
--- a/pkg/compiler/lib/src/ssa/types_propagation.dart
+++ b/pkg/compiler/lib/src/ssa/types_propagation.dart
@@ -144,6 +144,11 @@
     return instruction.instructionType;
   }
 
+  TypeMask visitRemainder(HRemainder instruction) {
+    // Always as initialized.
+    return instruction.instructionType;
+  }
+
   TypeMask visitNegate(HNegate instruction) {
     HInstruction operand = instruction.operand;
     // We have integer subclasses that represent ranges, so widen any int
diff --git a/pkg/compiler/lib/src/ssa/value_range_analyzer.dart b/pkg/compiler/lib/src/ssa/value_range_analyzer.dart
index 3f041a0..7e53d06 100644
--- a/pkg/compiler/lib/src/ssa/value_range_analyzer.dart
+++ b/pkg/compiler/lib/src/ssa/value_range_analyzer.dart
@@ -814,8 +814,8 @@
     HInstruction right = invoke.inputs[2];
     Range divisor = ranges[right];
     if (divisor != null) {
-      // For Integer values we can be precise in the upper bound,
-      // so special case those.
+      // For Integer values we can be precise in the upper bound, so special
+      // case those.
       if (left.isInteger(closedWorld) && right.isInteger(closedWorld)) {
         if (divisor.isPositive) {
           return info.newNormalizedRange(
@@ -836,6 +836,30 @@
     return info.newUnboundRange();
   }
 
+  Range visitRemainder(HRemainder instruction) {
+    HInstruction left = instruction.inputs[0];
+    HInstruction right = instruction.inputs[1];
+    Range dividend = ranges[left];
+    // If both operands are >=0, the result is >= 0 and bounded by the divisor.
+    if ((dividend != null && dividend.isPositive) ||
+        left.isPositiveInteger(closedWorld)) {
+      Range divisor = ranges[right];
+      if (divisor != null) {
+        if (divisor.isPositive) {
+          // For Integer values we can be precise in the upper bound.
+          if (left.isInteger(closedWorld) && right.isInteger(closedWorld)) {
+            return info.newNormalizedRange(
+                info.intZero, divisor.upper - info.intOne);
+          }
+          if (left.isNumber(closedWorld) && right.isNumber(closedWorld)) {
+            return info.newNormalizedRange(info.intZero, divisor.upper);
+          }
+        }
+      }
+    }
+    return info.newUnboundRange();
+  }
+
   Range visitInvokeDynamicMethod(HInvokeDynamicMethod invoke) {
     if ((invoke.inputs.length == 3) && (invoke.selector.name == "%"))
       return handleInvokeModulo(invoke);
diff --git a/pkg/compiler/lib/src/types/flat_type_mask.dart b/pkg/compiler/lib/src/types/flat_type_mask.dart
index 80a4734..15caf64 100644
--- a/pkg/compiler/lib/src/types/flat_type_mask.dart
+++ b/pkg/compiler/lib/src/types/flat_type_mask.dart
@@ -512,7 +512,8 @@
    * invoked on this type mask. [selector] is used to ensure library
    * privacy is taken into account.
    */
-  bool canHit(Element element, Selector selector, ClosedWorld closedWorld) {
+  bool canHit(
+      MemberElement element, Selector selector, ClosedWorld closedWorld) {
     BackendClasses backendClasses = closedWorld.backendClasses;
     assert(element.name == selector.name);
     if (isEmpty) return false;
@@ -521,37 +522,28 @@
           backendClasses.nullImplementation, selector, element);
     }
 
-    // TODO(kasperl): Can't we just avoid creating typed selectors
-    // based of function types?
-    Element self = base;
-    if (self.isTypedef) {
-      // A typedef is a function type that doesn't have any
-      // user-defined members.
-      return false;
-    }
-
-    ClassElement other = element.enclosingClass;
+    ClassEntity other = element.enclosingClass.declaration;
     if (other == backendClasses.nullImplementation) {
       return isNullable;
     } else if (isExact) {
-      return closedWorld.hasElementIn(self, selector, element);
+      return closedWorld.hasElementIn(base, selector, element);
     } else if (isSubclass) {
-      return closedWorld.hasElementIn(self, selector, element) ||
-          other.isSubclassOf(self) ||
-          closedWorld.hasAnySubclassThatMixes(self, other);
+      return closedWorld.hasElementIn(base, selector, element) ||
+          closedWorld.isSubclassOf(other, base) ||
+          closedWorld.hasAnySubclassThatMixes(base, other);
     } else {
       assert(isSubtype);
-      bool result = closedWorld.hasElementIn(self, selector, element) ||
-          other.implementsInterface(self) ||
+      bool result = closedWorld.hasElementIn(base, selector, element) ||
+          closedWorld.isSubtypeOf(other, base) ||
           closedWorld.hasAnySubclassThatImplements(other, base) ||
           closedWorld.hasAnySubclassOfMixinUseThatImplements(other, base);
       if (result) return true;
       // If the class is used as a mixin, we have to check if the element
       // can be hit from any of the mixin applications.
-      Iterable<ClassElement> mixinUses = closedWorld.mixinUsesOf(self);
+      Iterable<ClassEntity> mixinUses = closedWorld.mixinUsesOf(base);
       return mixinUses.any((mixinApplication) =>
           closedWorld.hasElementIn(mixinApplication, selector, element) ||
-          other.isSubclassOf(mixinApplication) ||
+          closedWorld.isSubclassOf(other, mixinApplication) ||
           closedWorld.hasAnySubclassThatMixes(mixinApplication, other));
     }
   }
@@ -574,9 +566,11 @@
             : (isSubclass ? ClassQuery.SUBCLASS : ClassQuery.SUBTYPE));
   }
 
-  Element locateSingleElement(Selector selector, ClosedWorld closedWorld) {
+  MemberElement locateSingleElement(
+      Selector selector, ClosedWorld closedWorld) {
     if (isEmptyOrNull) return null;
-    Iterable<Element> targets = closedWorld.allFunctions.filter(selector, this);
+    Iterable<MemberElement> targets =
+        closedWorld.allFunctions.filter(selector, this);
     if (targets.length != 1) return null;
     Element result = targets.first;
     ClassElement enclosing = result.enclosingClass.declaration;
diff --git a/pkg/compiler/lib/src/types/forwarding_type_mask.dart b/pkg/compiler/lib/src/types/forwarding_type_mask.dart
index 775fee0..73ac59d 100644
--- a/pkg/compiler/lib/src/types/forwarding_type_mask.dart
+++ b/pkg/compiler/lib/src/types/forwarding_type_mask.dart
@@ -97,11 +97,12 @@
     return forwardTo.needsNoSuchMethodHandling(selector, closedWorld);
   }
 
-  bool canHit(Element element, Selector selector, ClosedWorld closedWorld) {
+  bool canHit(
+      MemberEntity element, Selector selector, ClosedWorld closedWorld) {
     return forwardTo.canHit(element, selector, closedWorld);
   }
 
-  Element locateSingleElement(Selector selector, ClosedWorld closedWorld) {
+  MemberEntity locateSingleElement(Selector selector, ClosedWorld closedWorld) {
     return forwardTo.locateSingleElement(selector, closedWorld);
   }
 
diff --git a/pkg/compiler/lib/src/types/masks.dart b/pkg/compiler/lib/src/types/masks.dart
index 01dff02..8e86799 100644
--- a/pkg/compiler/lib/src/types/masks.dart
+++ b/pkg/compiler/lib/src/types/masks.dart
@@ -6,9 +6,9 @@
 
 import '../common.dart';
 import '../common/backend_api.dart' show BackendClasses;
-import '../compiler.dart' show Compiler;
 import '../constants/values.dart' show PrimitiveConstantValue;
 import '../elements/elements.dart';
+import '../elements/entities.dart';
 import '../inferrer/type_graph_inferrer.dart' show TypeGraphInferrer;
 import '../tree/tree.dart';
 import '../universe/selector.dart' show Selector;
diff --git a/pkg/compiler/lib/src/types/type_mask.dart b/pkg/compiler/lib/src/types/type_mask.dart
index c2872cd..d6e68da 100644
--- a/pkg/compiler/lib/src/types/type_mask.dart
+++ b/pkg/compiler/lib/src/types/type_mask.dart
@@ -12,7 +12,7 @@
   Set<TypeMask> _masks;
 
   @override
-  bool applies(Element element, Selector selector, ClosedWorld world) {
+  bool applies(MemberElement element, Selector selector, ClosedWorld world) {
     if (isAll) return true;
     if (_masks == null) return false;
     for (TypeMask mask in _masks) {
@@ -84,19 +84,19 @@
 
   const factory TypeMask.empty() = FlatTypeMask.empty;
 
-  factory TypeMask.exact(Entity base, ClosedWorld closedWorld) {
+  factory TypeMask.exact(ClassEntity base, ClosedWorld closedWorld) {
     assert(invariant(base, closedWorld.isInstantiated(base),
         message: () => "Cannot create exact type mask for uninstantiated "
             "class $base.\n${closedWorld.dump(base)}"));
     return new FlatTypeMask.exact(base);
   }
 
-  factory TypeMask.exactOrEmpty(Entity base, ClosedWorld closedWorld) {
+  factory TypeMask.exactOrEmpty(ClassEntity base, ClosedWorld closedWorld) {
     if (closedWorld.isInstantiated(base)) return new FlatTypeMask.exact(base);
     return const TypeMask.empty();
   }
 
-  factory TypeMask.subclass(Entity base, ClosedWorld closedWorld) {
+  factory TypeMask.subclass(ClassEntity base, ClosedWorld closedWorld) {
     assert(invariant(base, closedWorld.isInstantiated(base),
         message: () => "Cannot create subclass type mask for uninstantiated "
             "class $base.\n${closedWorld.dump(base)}"));
@@ -110,7 +110,7 @@
     }
   }
 
-  factory TypeMask.subtype(Entity base, ClosedWorld closedWorld) {
+  factory TypeMask.subtype(ClassEntity base, ClosedWorld closedWorld) {
     Entity topmost = closedWorld.getLubOfInstantiatedSubtypes(base);
     if (topmost == null) {
       return new TypeMask.empty();
@@ -127,25 +127,26 @@
 
   const factory TypeMask.nonNullEmpty() = FlatTypeMask.nonNullEmpty;
 
-  factory TypeMask.nonNullExact(Entity base, ClosedWorld closedWorld) {
+  factory TypeMask.nonNullExact(ClassEntity base, ClosedWorld closedWorld) {
     assert(invariant(base, closedWorld.isInstantiated(base),
         message: () => "Cannot create exact type mask for uninstantiated "
             "class $base.\n${closedWorld.dump(base)}"));
     return new FlatTypeMask.nonNullExact(base);
   }
 
-  factory TypeMask.nonNullExactOrEmpty(Entity base, ClosedWorld closedWorld) {
+  factory TypeMask.nonNullExactOrEmpty(
+      ClassEntity base, ClosedWorld closedWorld) {
     if (closedWorld.isInstantiated(base)) {
       return new FlatTypeMask.nonNullExact(base);
     }
     return const TypeMask.nonNullEmpty();
   }
 
-  factory TypeMask.nonNullSubclass(Entity base, ClosedWorld closedWorld) {
+  factory TypeMask.nonNullSubclass(ClassEntity base, ClosedWorld closedWorld) {
     assert(invariant(base, closedWorld.isInstantiated(base),
         message: () => "Cannot create subclass type mask for uninstantiated "
             "class $base.\n${closedWorld.dump(base)}"));
-    Entity topmost = closedWorld.getLubOfInstantiatedSubclasses(base);
+    ClassEntity topmost = closedWorld.getLubOfInstantiatedSubclasses(base);
     if (topmost == null) {
       return new TypeMask.nonNullEmpty();
     } else if (closedWorld.hasAnyStrictSubclass(topmost)) {
@@ -155,8 +156,8 @@
     }
   }
 
-  factory TypeMask.nonNullSubtype(Entity base, ClosedWorld closedWorld) {
-    Entity topmost = closedWorld.getLubOfInstantiatedSubtypes(base);
+  factory TypeMask.nonNullSubtype(ClassEntity base, ClosedWorld closedWorld) {
+    ClassEntity topmost = closedWorld.getLubOfInstantiatedSubtypes(base);
     if (topmost == null) {
       return new TypeMask.nonNullEmpty();
     }
@@ -327,9 +328,9 @@
    */
   bool containsAll(ClosedWorld closedWorld);
 
-  /// Returns the [Entity] if this type represents a single class, otherwise
-  /// returns `null`.  This method is conservative.
-  Entity singleClass(ClosedWorld closedWorld);
+  /// Returns the [ClassEntity] if this type represents a single class,
+  /// otherwise returns `null`.  This method is conservative.
+  ClassEntity singleClass(ClosedWorld closedWorld);
 
   /**
    * Returns a type mask representing the union of [this] and [other].
@@ -349,13 +350,12 @@
    * invoked on this type mask. [selector] is used to ensure library
    * privacy is taken into account.
    */
-  bool canHit(
-      MemberElement element, Selector selector, ClosedWorld closedWorld);
+  bool canHit(MemberEntity element, Selector selector, ClosedWorld closedWorld);
 
   /**
    * Returns the [element] that is known to always be hit at runtime
    * on this mask. Returns null if there is none.
    */
   // TODO(johnniwinther): Move this method to [World].
-  Element locateSingleElement(Selector selector, ClosedWorld closedWorld);
+  MemberEntity locateSingleElement(Selector selector, ClosedWorld closedWorld);
 }
diff --git a/pkg/compiler/lib/src/types/types.dart b/pkg/compiler/lib/src/types/types.dart
index 200185b..cd9e860 100644
--- a/pkg/compiler/lib/src/types/types.dart
+++ b/pkg/compiler/lib/src/types/types.dart
@@ -9,8 +9,8 @@
 import '../common/tasks.dart' show CompilerTask;
 import '../compiler.dart' show Compiler;
 import '../elements/elements.dart';
-import '../inferrer/type_graph_inferrer.dart'
-    show TypeGraphInferrer, TypeInformationSystem;
+import '../inferrer/type_graph_inferrer.dart' show TypeGraphInferrer;
+import '../inferrer/type_system.dart';
 import '../tree/tree.dart';
 import '../universe/selector.dart' show Selector;
 import '../util/util.dart' show Maplet;
@@ -211,8 +211,8 @@
             dynamicType));
   }
 
-  GlobalTypeInferenceResults(this._inferrer, this._compiler, this.closedWorld,
-      TypeInformationSystem types);
+  GlobalTypeInferenceResults(
+      this._inferrer, this._compiler, this.closedWorld, TypeSystem types);
 
   TypeMask get dynamicType => closedWorld.commonMasks.dynamicType;
 
diff --git a/pkg/compiler/lib/src/types/union_type_mask.dart b/pkg/compiler/lib/src/types/union_type_mask.dart
index 3c7dfcc..40305cc 100644
--- a/pkg/compiler/lib/src/types/union_type_mask.dart
+++ b/pkg/compiler/lib/src/types/union_type_mask.dart
@@ -330,14 +330,16 @@
         .any((e) => e.needsNoSuchMethodHandling(selector, closedWorld));
   }
 
-  bool canHit(Element element, Selector selector, ClosedWorld closedWorld) {
+  bool canHit(
+      MemberElement element, Selector selector, ClosedWorld closedWorld) {
     return disjointMasks.any((e) => e.canHit(element, selector, closedWorld));
   }
 
-  Element locateSingleElement(Selector selector, ClosedWorld closedWorld) {
-    Element candidate;
+  MemberElement locateSingleElement(
+      Selector selector, ClosedWorld closedWorld) {
+    MemberElement candidate;
     for (FlatTypeMask mask in disjointMasks) {
-      Element current = mask.locateSingleElement(selector, closedWorld);
+      MemberElement current = mask.locateSingleElement(selector, closedWorld);
       if (current == null) {
         return null;
       } else if (candidate == null) {
diff --git a/pkg/compiler/lib/src/universe/function_set.dart b/pkg/compiler/lib/src/universe/function_set.dart
index b99e1fe..385e89c 100644
--- a/pkg/compiler/lib/src/universe/function_set.dart
+++ b/pkg/compiler/lib/src/universe/function_set.dart
@@ -5,8 +5,8 @@
 library universe.function_set;
 
 import '../common/names.dart' show Identifiers, Selectors;
-import '../compiler.dart' show Compiler;
-import '../elements/elements.dart';
+import '../elements/elements.dart' show MemberElement;
+import '../elements/entities.dart';
 import '../types/types.dart';
 import '../util/util.dart' show Hashing, Setlet;
 import '../world.dart' show ClosedWorld;
@@ -18,7 +18,7 @@
 
   FunctionSetNode newNode(String name) => new FunctionSetNode(name);
 
-  void add(Element element) {
+  void add(MemberElement element) {
     assert(element.isInstanceMember);
     assert(!element.isAbstract);
     String name = element.name;
@@ -26,7 +26,7 @@
     node.add(element);
   }
 
-  void remove(Element element) {
+  void remove(MemberElement element) {
     assert(element.isInstanceMember);
     assert(!element.isAbstract);
     String name = element.name;
@@ -50,7 +50,7 @@
 
   FunctionSet(this.closedWorld, this.nodes);
 
-  bool contains(Element element) {
+  bool contains(MemberElement element) {
     assert(element.isInstanceMember);
     assert(!element.isAbstract);
     String name = element.name;
@@ -62,7 +62,8 @@
   /// receiver with the given [constraint]. The returned elements may include
   /// noSuchMethod handlers that are potential targets indirectly through the
   /// noSuchMethod mechanism.
-  Iterable<Element> filter(Selector selector, ReceiverConstraint constraint) {
+  Iterable<MemberElement> filter(
+      Selector selector, ReceiverConstraint constraint) {
     return query(selector, constraint).functions;
   }
 
@@ -133,7 +134,7 @@
 
   String get name => selector.name;
 
-  bool applies(Element element, ClosedWorld closedWorld) {
+  bool applies(MemberEntity element, ClosedWorld closedWorld) {
     if (!selector.appliesUnnamed(element)) return false;
     return constraint.canHit(element, selector, closedWorld);
   }
@@ -161,12 +162,12 @@
   // compact than a hash set. Once we get enough elements, we change
   // the representation to be a set to get faster contains checks.
   static const int MAX_ELEMENTS_IN_LIST = 8;
-  var elements = <Element>[];
+  var elements = <MemberElement>[];
   bool isList = true;
 
   FunctionSetNode(this.name);
 
-  void add(Element element) {
+  void add(MemberElement element) {
     assert(element.name == name);
     // We try to avoid clearing the cache unless we have to. For that
     // reason we keep the explicit contains check even though the add
@@ -181,13 +182,13 @@
     }
   }
 
-  void remove(Element element) {
+  void remove(MemberElement element) {
     assert(element.name == name);
     if (isList) {
       List list = elements;
       int index = list.indexOf(element);
       if (index < 0) return;
-      Element last = list.removeLast();
+      MemberElement last = list.removeLast();
       if (index != list.length) {
         list[index] = last;
       }
@@ -203,7 +204,7 @@
     }
   }
 
-  bool contains(Element element) {
+  bool contains(MemberElement element) {
     assert(element.name == name);
     return elements.contains(element);
   }
@@ -220,14 +221,14 @@
     FunctionSetQuery result = cache[selectorMask];
     if (result != null) return result;
 
-    Setlet<Element> functions;
-    for (Element element in elements) {
+    Setlet<MemberElement> functions;
+    for (MemberElement element in elements) {
       if (selectorMask.applies(element, closedWorld)) {
         if (functions == null) {
           // Defer the allocation of the functions set until we are
           // sure we need it. This allows us to return immutable empty
           // lists when the filtering produced no results.
-          functions = new Setlet<Element>();
+          functions = new Setlet<MemberElement>();
         }
         functions.add(element);
       }
@@ -242,7 +243,8 @@
           noSuchMethods.query(noSuchMethodMask, closedWorld);
       if (!noSuchMethodQuery.functions.isEmpty) {
         if (functions == null) {
-          functions = new Setlet<Element>.from(noSuchMethodQuery.functions);
+          functions =
+              new Setlet<MemberElement>.from(noSuchMethodQuery.functions);
         } else {
           functions.addAll(noSuchMethodQuery.functions);
         }
@@ -264,7 +266,7 @@
   TypeMask computeMask(ClosedWorld closedWorld);
 
   /// Returns all potential targets of this function set.
-  Iterable<Element> get functions;
+  Iterable<MemberElement> get functions;
 }
 
 class EmptyFunctionSetQuery implements FunctionSetQuery {
@@ -275,12 +277,12 @@
       const TypeMask.nonNullEmpty();
 
   @override
-  Iterable<Element> get functions => const <Element>[];
+  Iterable<MemberElement> get functions => const <MemberElement>[];
 }
 
 class FullFunctionSetQuery implements FunctionSetQuery {
   @override
-  final Iterable<Element> functions;
+  final Iterable<MemberElement> functions;
 
   TypeMask _mask;
 
@@ -292,14 +294,14 @@
         .hasAnyStrictSubclass(closedWorld.commonElements.objectClass));
     if (_mask != null) return _mask;
     return _mask = new TypeMask.unionOf(
-        functions.expand((element) {
-          ClassElement cls = element.enclosingClass;
+        functions.expand((MemberElement element) {
+          ClassEntity cls = element.enclosingClass.declaration;
           return [cls]..addAll(closedWorld.mixinUsesOf(cls));
         }).map((cls) {
           if (closedWorld.backendClasses.nullImplementation == cls) {
             return const TypeMask.empty();
-          } else if (closedWorld.isInstantiated(cls.declaration)) {
-            return new TypeMask.nonNullSubclass(cls.declaration, closedWorld);
+          } else if (closedWorld.isInstantiated(cls)) {
+            return new TypeMask.nonNullSubclass(cls, closedWorld);
           } else {
             // TODO(johnniwinther): Avoid the need for this case.
             return const TypeMask.empty();
diff --git a/pkg/compiler/lib/src/universe/selector.dart b/pkg/compiler/lib/src/universe/selector.dart
index 8ca8637..647c3fb 100644
--- a/pkg/compiler/lib/src/universe/selector.dart
+++ b/pkg/compiler/lib/src/universe/selector.dart
@@ -10,9 +10,9 @@
     show
         Element,
         Elements,
-        FunctionElement,
         FunctionSignature,
         MemberElement,
+        MethodElement,
         Name,
         LibraryElement,
         PublicName;
@@ -218,12 +218,12 @@
     return kind;
   }
 
-  bool appliesUnnamed(Element element) {
+  bool appliesUnnamed(MemberElement element) {
     assert(name == element.name);
     return appliesUntyped(element);
   }
 
-  bool appliesUntyped(Element element) {
+  bool appliesUntyped(MemberElement element) {
     assert(name == element.name);
     if (Elements.isUnresolved(element)) return false;
     if (memberName.isPrivate && memberName.library != element.library) {
@@ -243,7 +243,7 @@
     return signatureApplies(element);
   }
 
-  bool signatureApplies(FunctionElement function) {
+  bool signatureApplies(MethodElement function) {
     if (Elements.isUnresolved(function)) return false;
     return callStructure.signatureApplies(function.functionSignature);
   }
diff --git a/pkg/compiler/lib/src/universe/use.dart b/pkg/compiler/lib/src/universe/use.dart
index 0354b12..a2ad411 100644
--- a/pkg/compiler/lib/src/universe/use.dart
+++ b/pkg/compiler/lib/src/universe/use.dart
@@ -18,7 +18,7 @@
 
 import '../closure.dart' show BoxFieldElement;
 import '../common.dart';
-import '../elements/resolution_types.dart';
+import '../elements/types.dart';
 import '../elements/elements.dart';
 import '../util/util.dart' show Hashing;
 import '../world.dart' show World;
@@ -89,10 +89,10 @@
   final Element element;
   final StaticUseKind kind;
   final int hashCode;
-  final ResolutionDartType type;
+  final DartType type;
 
   StaticUse.internal(Element element, StaticUseKind kind,
-      [ResolutionDartType type = null])
+      [DartType type = null])
       : this.element = element,
         this.kind = kind,
         this.type = type,
@@ -252,8 +252,8 @@
 
   /// Constructor invocation of [element] with the given [callStructure] on
   /// [type].
-  factory StaticUse.typedConstructorInvoke(ConstructorElement element,
-      CallStructure callStructure, ResolutionDartType type) {
+  factory StaticUse.typedConstructorInvoke(
+      ConstructorElement element, CallStructure callStructure, DartType type) {
     assert(invariant(element, type != null,
         message: "No type provided for constructor invocation."));
     // TODO(johnniwinther): Use the [callStructure].
@@ -263,8 +263,8 @@
 
   /// Constant constructor invocation of [element] with the given
   /// [callStructure] on [type].
-  factory StaticUse.constConstructorInvoke(ConstructorElement element,
-      CallStructure callStructure, ResolutionDartType type) {
+  factory StaticUse.constConstructorInvoke(
+      ConstructorElement element, CallStructure callStructure, DartType type) {
     assert(invariant(element, type != null,
         message: "No type provided for constructor invocation."));
     // TODO(johnniwinther): Use the [callStructure].
@@ -274,7 +274,7 @@
 
   /// Constructor redirection to [element] on [type].
   factory StaticUse.constructorRedirect(
-      ConstructorElement element, ResolutionInterfaceType type) {
+      ConstructorElement element, InterfaceType type) {
     assert(invariant(element, type != null,
         message: "No type provided for constructor invocation."));
     return new StaticUse.internal(element, StaticUseKind.REDIRECTION, type);
@@ -343,52 +343,52 @@
 
 /// Use of a [ResolutionDartType].
 class TypeUse {
-  final ResolutionDartType type;
+  final DartType type;
   final TypeUseKind kind;
   final int hashCode;
 
-  TypeUse.internal(ResolutionDartType type, TypeUseKind kind)
+  TypeUse.internal(DartType type, TypeUseKind kind)
       : this.type = type,
         this.kind = kind,
         this.hashCode = Hashing.objectHash(type, Hashing.objectHash(kind));
 
   /// [type] used in an is check, like `e is T` or `e is! T`.
-  factory TypeUse.isCheck(ResolutionDartType type) {
+  factory TypeUse.isCheck(DartType type) {
     return new TypeUse.internal(type, TypeUseKind.IS_CHECK);
   }
 
   /// [type] used in an as cast, like `e as T`.
-  factory TypeUse.asCast(ResolutionDartType type) {
+  factory TypeUse.asCast(DartType type) {
     return new TypeUse.internal(type, TypeUseKind.AS_CAST);
   }
 
   /// [type] used as a type annotation, like `T foo;`.
-  factory TypeUse.checkedModeCheck(ResolutionDartType type) {
+  factory TypeUse.checkedModeCheck(DartType type) {
     return new TypeUse.internal(type, TypeUseKind.CHECKED_MODE_CHECK);
   }
 
   /// [type] used in a on type catch clause, like `try {} on T catch (e) {}`.
-  factory TypeUse.catchType(ResolutionDartType type) {
+  factory TypeUse.catchType(DartType type) {
     return new TypeUse.internal(type, TypeUseKind.CATCH_TYPE);
   }
 
   /// [type] used as a type literal, like `foo() => T;`.
-  factory TypeUse.typeLiteral(ResolutionDartType type) {
+  factory TypeUse.typeLiteral(DartType type) {
     return new TypeUse.internal(type, TypeUseKind.TYPE_LITERAL);
   }
 
   /// [type] used in an instantiation, like `new T();`.
-  factory TypeUse.instantiation(ResolutionInterfaceType type) {
+  factory TypeUse.instantiation(InterfaceType type) {
     return new TypeUse.internal(type, TypeUseKind.INSTANTIATION);
   }
 
   /// [type] used in an instantiation through mirrors.
-  factory TypeUse.mirrorInstantiation(ResolutionInterfaceType type) {
+  factory TypeUse.mirrorInstantiation(InterfaceType type) {
     return new TypeUse.internal(type, TypeUseKind.MIRROR_INSTANTIATION);
   }
 
   /// [type] used in a native instantiation.
-  factory TypeUse.nativeInstantiation(ResolutionInterfaceType type) {
+  factory TypeUse.nativeInstantiation(InterfaceType type) {
     return new TypeUse.internal(type, TypeUseKind.NATIVE_INSTANTIATION);
   }
 
diff --git a/pkg/compiler/lib/src/universe/world_builder.dart b/pkg/compiler/lib/src/universe/world_builder.dart
index 9ae7a13..651d62a 100644
--- a/pkg/compiler/lib/src/universe/world_builder.dart
+++ b/pkg/compiler/lib/src/universe/world_builder.dart
@@ -81,7 +81,7 @@
   ///
   /// Ideally the selector constraints for calls `foo` with two positional
   /// arguments apply to `A.foo` but `B.foo`.
-  bool applies(Element element, Selector selector, World world);
+  bool applies(MemberElement element, Selector selector, World world);
 
   /// Returns `true` if at least one of the receivers matching these constraints
   /// in the closed [world] have no implementation matching [selector].
diff --git a/pkg/compiler/lib/src/world.dart b/pkg/compiler/lib/src/world.dart
index 50c708f..845e568 100644
--- a/pkg/compiler/lib/src/world.dart
+++ b/pkg/compiler/lib/src/world.dart
@@ -9,16 +9,18 @@
 import 'common.dart';
 import 'constants/constant_system.dart';
 import 'core_types.dart' show CommonElements;
-import 'elements/resolution_types.dart';
+import 'elements/entities.dart';
 import 'elements/elements.dart'
     show
         ClassElement,
         Element,
+        Entity,
         FunctionElement,
         MemberElement,
         MixinApplicationElement,
         TypedefElement,
         FieldElement;
+import 'elements/resolution_types.dart';
 import 'js_backend/backend.dart' show JavaScriptBackend;
 import 'ordered_typeset.dart';
 import 'types/masks.dart' show CommonMasks, FlatTypeMask, TypeMask;
@@ -51,11 +53,11 @@
   ConstantSystem get constantSystem;
 
   /// Returns `true` if [cls] is either directly or indirectly instantiated.
-  bool isInstantiated(ClassElement cls);
+  bool isInstantiated(ClassEntity cls);
 
   /// Returns `true` if [cls] is directly instantiated. This means that at
   /// runtime instances of exactly [cls] are assumed to exist.
-  bool isDirectlyInstantiated(ClassElement cls);
+  bool isDirectlyInstantiated(ClassEntity cls);
 
   /// Returns `true` if [cls] is abstractly instantiated. This means that at
   /// runtime instances of [cls] or unknown subclasses of [cls] are assumed to
@@ -66,121 +68,121 @@
   /// so [cls] here represents the root of the subclasses. For reflectable
   /// classes we need event abstract classes to be 'live' even though they
   /// cannot themselves be instantiated.
-  bool isAbstractlyInstantiated(ClassElement cls);
+  bool isAbstractlyInstantiated(ClassEntity cls);
 
   /// Returns `true` if [cls] is either directly or abstractly instantiated.
   ///
   /// See [isDirectlyInstantiated] and [isAbstractlyInstantiated].
-  bool isExplicitlyInstantiated(ClassElement cls);
+  bool isExplicitlyInstantiated(ClassEntity cls);
 
   /// Returns `true` if [cls] is indirectly instantiated, that is through a
   /// subclass.
-  bool isIndirectlyInstantiated(ClassElement cls);
+  bool isIndirectlyInstantiated(ClassEntity cls);
 
   /// Returns `true` if [cls] is abstract and thus can only be instantiated
   /// through subclasses.
-  bool isAbstract(ClassElement cls);
+  bool isAbstract(ClassEntity cls);
 
   /// Returns `true` if [cls] is implemented by an instantiated class.
-  bool isImplemented(ClassElement cls);
+  bool isImplemented(ClassEntity cls);
 
   /// Return `true` if [x] is a subclass of [y].
-  bool isSubclassOf(ClassElement x, ClassElement y);
+  bool isSubclassOf(ClassEntity x, ClassEntity y);
 
   /// Returns `true` if [x] is a subtype of [y], that is, if [x] implements an
   /// instance of [y].
-  bool isSubtypeOf(ClassElement x, ClassElement y);
+  bool isSubtypeOf(ClassEntity x, ClassEntity y);
 
   /// Returns an iterable over the live classes that extend [cls] including
   /// [cls] itself.
-  Iterable<ClassElement> subclassesOf(ClassElement cls);
+  Iterable<ClassEntity> subclassesOf(ClassEntity cls);
 
   /// Returns an iterable over the live classes that extend [cls] _not_
   /// including [cls] itself.
-  Iterable<ClassElement> strictSubclassesOf(ClassElement cls);
+  Iterable<ClassEntity> strictSubclassesOf(ClassEntity cls);
 
   /// Returns the number of live classes that extend [cls] _not_
   /// including [cls] itself.
-  int strictSubclassCount(ClassElement cls);
+  int strictSubclassCount(ClassEntity cls);
 
   /// Applies [f] to each live class that extend [cls] _not_ including [cls]
   /// itself.
   void forEachStrictSubclassOf(
-      ClassElement cls, IterationStep f(ClassElement cls));
+      ClassEntity cls, IterationStep f(ClassEntity cls));
 
   /// Returns `true` if [predicate] applies to any live class that extend [cls]
   /// _not_ including [cls] itself.
-  bool anyStrictSubclassOf(ClassElement cls, bool predicate(ClassElement cls));
+  bool anyStrictSubclassOf(ClassEntity cls, bool predicate(ClassEntity cls));
 
   /// Returns an iterable over the directly instantiated that implement [cls]
   /// possibly including [cls] itself, if it is live.
-  Iterable<ClassElement> subtypesOf(ClassElement cls);
+  Iterable<ClassElement> subtypesOf(ClassEntity cls);
 
   /// Returns an iterable over the live classes that implement [cls] _not_
   /// including [cls] if it is live.
-  Iterable<ClassElement> strictSubtypesOf(ClassElement cls);
+  Iterable<ClassElement> strictSubtypesOf(ClassEntity cls);
 
   /// Returns the number of live classes that implement [cls] _not_
   /// including [cls] itself.
-  int strictSubtypeCount(ClassElement cls);
+  int strictSubtypeCount(ClassEntity cls);
 
   /// Applies [f] to each live class that implements [cls] _not_ including [cls]
   /// itself.
   void forEachStrictSubtypeOf(
-      ClassElement cls, IterationStep f(ClassElement cls));
+      ClassEntity cls, IterationStep f(ClassEntity cls));
 
   /// Returns `true` if [predicate] applies to any live class that implements
   /// [cls] _not_ including [cls] itself.
-  bool anyStrictSubtypeOf(ClassElement cls, bool predicate(ClassElement cls));
+  bool anyStrictSubtypeOf(ClassEntity cls, bool predicate(ClassEntity cls));
 
   /// Returns `true` if [a] and [b] have any known common subtypes.
-  bool haveAnyCommonSubtypes(ClassElement a, ClassElement b);
+  bool haveAnyCommonSubtypes(ClassEntity a, ClassEntity b);
 
   /// Returns `true` if any live class other than [cls] extends [cls].
-  bool hasAnyStrictSubclass(ClassElement cls);
+  bool hasAnyStrictSubclass(ClassEntity cls);
 
   /// Returns `true` if any live class other than [cls] implements [cls].
-  bool hasAnyStrictSubtype(ClassElement cls);
+  bool hasAnyStrictSubtype(ClassEntity cls);
 
   /// Returns `true` if all live classes that implement [cls] extend it.
-  bool hasOnlySubclasses(ClassElement cls);
+  bool hasOnlySubclasses(ClassEntity cls);
 
   /// Returns the most specific subclass of [cls] (including [cls]) that is
   /// directly instantiated or a superclass of all directly instantiated
   /// subclasses. If [cls] is not instantiated, `null` is returned.
-  ClassElement getLubOfInstantiatedSubclasses(ClassElement cls);
+  ClassEntity getLubOfInstantiatedSubclasses(ClassEntity cls);
 
   /// Returns the most specific subtype of [cls] (including [cls]) that is
   /// directly instantiated or a superclass of all directly instantiated
   /// subtypes. If no subtypes of [cls] are instantiated, `null` is returned.
-  ClassElement getLubOfInstantiatedSubtypes(ClassElement cls);
+  ClassEntity getLubOfInstantiatedSubtypes(ClassEntity cls);
 
   /// Returns an iterable over the common supertypes of the [classes].
-  Iterable<ClassElement> commonSupertypesOf(Iterable<ClassElement> classes);
+  Iterable<ClassEntity> commonSupertypesOf(Iterable<ClassEntity> classes);
 
   /// Returns an iterable over the live mixin applications that mixin [cls].
-  Iterable<MixinApplicationElement> mixinUsesOf(ClassElement cls);
+  Iterable<ClassEntity> mixinUsesOf(ClassEntity cls);
 
   /// Returns `true` if [cls] is mixed into a live class.
-  bool isUsedAsMixin(ClassElement cls);
+  bool isUsedAsMixin(ClassEntity cls);
 
   /// Returns `true` if any live class that mixes in [cls] implements [type].
   bool hasAnySubclassOfMixinUseThatImplements(
-      ClassElement cls, ClassElement type);
+      ClassEntity cls, ClassEntity type);
 
   /// Returns `true` if any live class that mixes in [mixin] is also a subclass
   /// of [superclass].
-  bool hasAnySubclassThatMixes(ClassElement superclass, ClassElement mixin);
+  bool hasAnySubclassThatMixes(ClassEntity superclass, ClassEntity mixin);
 
   /// Returns `true` if [cls] or any superclass mixes in [mixin].
-  bool isSubclassOfMixinUseOf(ClassElement cls, ClassElement mixin);
+  bool isSubclassOfMixinUseOf(ClassEntity cls, ClassEntity mixin);
 
   /// Returns `true` if every subtype of [x] is a subclass of [y] or a subclass
   /// of a mixin application of [y].
-  bool everySubtypeIsSubclassOfOrMixinUseOf(ClassElement x, ClassElement y);
+  bool everySubtypeIsSubclassOfOrMixinUseOf(ClassEntity x, ClassEntity y);
 
   /// Returns `true` if any subclass of [superclass] implements [type].
-  bool hasAnySubclassThatImplements(ClassElement superclass, ClassElement type);
+  bool hasAnySubclassThatImplements(ClassEntity superclass, ClassEntity type);
 
   /// Returns `true` if a call of [selector] on [cls] and/or subclasses/subtypes
   /// need noSuchMethod handling.
@@ -221,38 +223,38 @@
   ///
   /// If we're calling bar on an object of type A we do need the handler because
   /// we may have to call B.noSuchMethod since B does not implement bar.
-  bool needsNoSuchMethod(ClassElement cls, Selector selector, ClassQuery query);
+  bool needsNoSuchMethod(ClassEntity cls, Selector selector, ClassQuery query);
 
   /// Returns whether [element] will be the one used at runtime when being
   /// invoked on an instance of [cls]. [selector] is used to ensure library
   /// privacy is taken into account.
-  bool hasElementIn(ClassElement cls, Selector selector, Element element);
+  bool hasElementIn(ClassEntity cls, Selector selector, Entity element);
 
   /// Returns [ClassHierarchyNode] for [cls] used to model the class hierarchies
   /// of known classes.
   ///
   /// This method is only provided for testing. For queries on classes, use the
   /// methods defined in [ClosedWorld].
-  ClassHierarchyNode getClassHierarchyNode(ClassElement cls);
+  ClassHierarchyNode getClassHierarchyNode(ClassEntity cls);
 
   /// Returns [ClassSet] for [cls] used to model the extends and implements
   /// relations of known classes.
   ///
   /// This method is only provided for testing. For queries on classes, use the
   /// methods defined in [ClosedWorld].
-  ClassSet getClassSet(ClassElement cls);
+  ClassSet getClassSet(ClassEntity cls);
 
   /// Return the cached mask for [base] with the given flags, or
   /// calls [createMask] to create the mask and cache it.
   // TODO(johnniwinther): Find a better strategy for caching these?
-  TypeMask getCachedMask(ClassElement base, int flags, TypeMask createMask());
+  TypeMask getCachedMask(ClassEntity base, int flags, TypeMask createMask());
 
   /// Returns the [FunctionSet] containing all live functions in the closed
   /// world.
   FunctionSet get allFunctions;
 
   /// Returns `true` if the field [element] is known to be effectively final.
-  bool fieldNeverChanges(MemberElement element);
+  bool fieldNeverChanges(MemberEntity element);
 
   /// Extends the receiver type [mask] for calling [selector] to take live
   /// `noSuchMethod` handlers into account.
@@ -263,12 +265,12 @@
 
   /// Returns the single [Element] that matches a call to [selector] on a
   /// receiver of type [mask]. If multiple targets exist, `null` is returned.
-  MemberElement locateSingleElement(Selector selector, TypeMask mask);
+  MemberEntity locateSingleElement(Selector selector, TypeMask mask);
 
   /// Returns the single field that matches a call to [selector] on a
   /// receiver of type [mask]. If multiple targets exist or the single target
   /// is not a field, `null` is returned.
-  FieldElement locateSingleField(Selector selector, TypeMask mask);
+  FieldEntity locateSingleField(Selector selector, TypeMask mask);
 
   /// Returns the side effects of executing [element].
   SideEffects getSideEffectsOfElement(Element element);
@@ -292,7 +294,7 @@
   /// Returns a string representation of the closed world.
   ///
   /// If [cls] is provided, the dump will contain only classes related to [cls].
-  String dump([ClassElement cls]);
+  String dump([ClassEntity cls]);
 }
 
 /// Interface for computing side effects and uses of elements. This is used
@@ -989,7 +991,7 @@
     return (result != null && result.isField) ? result : null;
   }
 
-  Element locateSingleElement(Selector selector, TypeMask mask) {
+  MemberElement locateSingleElement(Selector selector, TypeMask mask) {
     assert(isClosed);
     mask ??= commonMasks.dynamicType;
     return mask.locateSingleElement(selector, this);
@@ -1066,7 +1068,7 @@
     // We're not tracking side effects of closures.
     if (selector.isClosureCall) return new SideEffects();
     SideEffects sideEffects = new SideEffects.empty();
-    for (Element e in allFunctions.filter(selector, mask)) {
+    for (MemberElement e in allFunctions.filter(selector, mask)) {
       if (e.isField) {
         if (selector.isGetter) {
           if (!fieldNeverChanges(e)) {
diff --git a/pkg/compiler/tool/perf.dart b/pkg/compiler/tool/perf.dart
index 4725014..194c392 100644
--- a/pkg/compiler/tool/perf.dart
+++ b/pkg/compiler/tool/perf.dart
@@ -33,7 +33,7 @@
 import 'package:package_config/src/util.dart' show checkValidPackageUri;
 
 /// Cumulative total number of chars scanned.
-int scanTotalChars = 0;
+int inputSize = 0;
 
 /// Cumulative time spent scanning.
 Stopwatch scanTimer = new Stopwatch();
@@ -47,32 +47,17 @@
     print('usage: perf.dart <bench-id> <entry.dart>');
     exit(1);
   }
-  var totalTimer = new Stopwatch()..start();
-
   var bench = args[0];
   var entryUri = Uri.base.resolve(args[1]);
 
   await setup(entryUri);
 
+  Set<SourceFile> files = await scanReachableFiles(entryUri);
   var handlers = {
-    'scan': () async {
-      Set<SourceFile> files = await scanReachableFiles(entryUri);
-      // TODO(sigmund): replace the warmup with instrumented snapshots.
-      for (int i = 0; i < 10; i++) scanFiles(files);
-    },
-    'parse': () async {
-      Set<SourceFile> files = await scanReachableFiles(entryUri);
-      // TODO(sigmund): replace the warmup with instrumented snapshots.
-      for (int i = 0; i < 10; i++) parseFiles(files);
-    },
+    'scan': () async => scanFiles(files),
+    'parse': () async => parseFiles(files),
     'kernel_gen_e2e': () async {
-      // TODO(sigmund): remove. This is used to compute the input size, we
-      // should extract input size from frontend instead.
-      await scanReachableFiles(entryUri);
-      // TODO(sigmund): replace this warmup. Note that for very large programs,
-      // the GC pressure on the VM seems to make this worse with time (maybe we
-      // are leaking memory?). That's why we run it twice and not 10 times.
-      for (int i = 0; i < 2; i++) await generateKernel(entryUri);
+      await generateKernel(entryUri);
     },
   };
 
@@ -80,12 +65,19 @@
   if (handler == null) {
     // TODO(sigmund): implement the remaining benchmarks.
     print('unsupported bench-id: $bench. Please specify one of the following: '
-        '${handler.keys.join(", ")}');
+        '${handlers.keys.join(", ")}');
     exit(1);
   }
-  await handler();
-  totalTimer.stop();
-  report("total", totalTimer.elapsedMicroseconds);
+
+  // TODO(sigmund): replace the warmup with instrumented snapshots.
+  int iterations = bench.contains('kernel_gen') ? 2 : 10;
+  for (int i = 0; i < iterations; i++) {
+    var totalTimer = new Stopwatch()..start();
+    print('== iteration $i');
+    await handler();
+    totalTimer.stop();
+    report('total', totalTimer.elapsedMicroseconds);
+  }
 }
 
 Future setup(Uri entryUri) async {
@@ -100,71 +92,56 @@
 Future<Set<SourceFile>> scanReachableFiles(Uri entryUri) async {
   var files = new Set<SourceFile>();
   var loadTimer = new Stopwatch()..start();
+  scanTimer = new Stopwatch();
   var entrypoints = [
     entryUri,
-    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"),
+    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'),
   ];
   for (var entry in entrypoints) {
     await collectSources(await loader.loadFile(entry), files);
   }
   loadTimer.stop();
 
-  print('input size: ${scanTotalChars} chars');
+  inputSize = 0;
+  for (var source in files) inputSize += source.length;
+  print('input size: ${inputSize} chars');
   var loadTime = loadTimer.elapsedMicroseconds - scanTimer.elapsedMicroseconds;
-  report("load", loadTime);
-  report("scan", scanTimer.elapsedMicroseconds);
+  report('load', loadTime);
+  report('scan', scanTimer.elapsedMicroseconds);
   return files;
 }
 
 /// Scans every file in [files] and reports the time spent doing so.
 void scanFiles(Set<SourceFile> files) {
-  // The code below will record again how many chars are scanned and how long it
-  // takes to scan them, even though we already did so in [scanReachableFiles].
-  // Recording and reporting this twice is unnecessary, but we do so for now to
-  // validate that the results are consistent.
   scanTimer = new Stopwatch();
-  var old = scanTotalChars;
-  scanTotalChars = 0;
   for (var source in files) {
     tokenize(source);
   }
-
-  // Report size and scanning time again. See discussion above.
-  if (old != scanTotalChars) print('input size changed? ${old} chars');
-  report("scan", scanTimer.elapsedMicroseconds);
+  report('scan', scanTimer.elapsedMicroseconds);
 }
 
 /// Parses every file in [files] and reports the time spent doing so.
 void parseFiles(Set<SourceFile> files) {
-  // The code below will record again how many chars are scanned and how long it
-  // takes to scan them, even though we already did so in [scanReachableFiles].
-  // Recording and reporting this twice is unnecessary, but we do so for now to
-  // validate that the results are consistent.
   scanTimer = new Stopwatch();
-  var old = scanTotalChars;
-  scanTotalChars = 0;
   var parseTimer = new Stopwatch()..start();
   for (var source in files) {
     parseFull(source);
   }
   parseTimer.stop();
 
-  // Report size and scanning time again. See discussion above.
-  if (old != scanTotalChars) print('input size changed? ${old} chars');
-  report("scan", scanTimer.elapsedMicroseconds);
-
+  report('scan', scanTimer.elapsedMicroseconds);
   report(
-      "parse", parseTimer.elapsedMicroseconds - scanTimer.elapsedMicroseconds);
+      'parse', parseTimer.elapsedMicroseconds - scanTimer.elapsedMicroseconds);
 }
 
 /// Add to [files] all sources reachable from [start].
@@ -198,18 +175,19 @@
 /// Scan [source] and return the first token produced by the scanner.
 Token tokenize(SourceFile source) {
   scanTimer.start();
-  scanTotalChars += source.length;
   var token = new Scanner(source).tokenize();
   scanTimer.stop();
   return token;
 }
 
 /// Report that metric [name] took [time] micro-seconds to process
-/// [scanTotalChars] characters.
+/// [inputSize] characters.
 void report(String name, int time) {
   var sb = new StringBuffer();
-  sb.write('$name: $time us, ${time ~/ 1000} ms');
-  sb.write(', ${scanTotalChars * 1000 ~/ time} chars/ms');
+  var padding = ' ' * (20 - name.length);
+  sb.write('$name:$padding $time us, ${time ~/ 1000} ms');
+  var invSpeed = (time * 1000 / inputSize).toStringAsFixed(2);
+  sb.write(', $invSpeed ns/char');
   print('$sb');
 }
 
@@ -246,7 +224,7 @@
 }
 
 Uri _libraryRoot = Platform.script.resolve('../../../sdk/');
-Uri _platformConfigUri = _libraryRoot.resolve("lib/dart_server.platform");
+Uri _platformConfigUri = _libraryRoot.resolve('lib/dart_server.platform');
 
 class FakeReporter extends DiagnosticReporter {
   final hasReportedError = false;
@@ -282,9 +260,15 @@
   }
 }
 
-class FakeReporterOptions {
+class FakeReporterOptions implements DiagnosticOptions {
   bool get suppressHints => false;
   bool get hidePackageWarnings => false;
+
+  bool get fatalWarnings => false;
+  bool get terseDiagnostics => false;
+  bool get suppressWarnings => false;
+  bool get showAllPackageWarnings => true;
+  bool showPackageWarningsFor(Uri uri) => true;
 }
 
 class _Loader {
@@ -333,6 +317,10 @@
 }
 
 generateKernel(Uri entryUri) async {
+  // TODO(sigmund): this is here only to compute the input size,
+  // we should extract the input size from the frontend instead.
+  scanReachableFiles(entryUri);
+
   var timer = new Stopwatch()..start();
   var options = new CompilerOptions(
       entryPoint: entryUri,
@@ -347,7 +335,7 @@
   var compiler = new MyCompiler(inputProvider, diagnosticHandler, options);
   await compiler.run(entryUri);
   timer.stop();
-  report("kernel_gen_e2e", timer.elapsedMicroseconds);
+  report('kernel_gen_e2e', timer.elapsedMicroseconds);
 }
 
 // We subclass compiler to skip phases and stop after creating kernel.
@@ -358,7 +346,7 @@
 
   /// Performs the compilation when all libraries have been loaded.
   void compileLoadedLibraries() =>
-      selfTask.measureSubtask("KernelCompiler.compileLoadedLibraries", () {
+      selfTask.measureSubtask('KernelCompiler.compileLoadedLibraries', () {
         WorldImpact mainImpact = computeMain();
         mirrorUsageAnalyzerTask.analyzeUsage(mainApp);
 
@@ -377,8 +365,8 @@
         });
 
         if (deferredLoadTask.isProgramSplit) {
-          enqueuer.resolution.applyImpact(
-              backend.computeDeferredLoadingImpact());
+          enqueuer.resolution
+              .applyImpact(backend.computeDeferredLoadingImpact());
         }
         enqueuer.resolution.applyImpact(backend.computeHelpersImpact());
         resolveLibraryMetadata();
@@ -391,7 +379,7 @@
 
         if (compilationFailed) {
           // TODO(sigmund): more diagnostics?
-          print("compilation failed!");
+          print('compilation failed!');
           exit(1);
         }
 
diff --git a/pkg/compiler/tool/perf_test.dart b/pkg/compiler/tool/perf_test.dart
index 20b6478..d4afa17 100644
--- a/pkg/compiler/tool/perf_test.dart
+++ b/pkg/compiler/tool/perf_test.dart
@@ -8,4 +8,4 @@
 
 import 'perf.dart' as m;
 
-main() => print('done ${m.scanTotalChars}');
+main() => print('done ${m.inputSize}');
diff --git a/pkg/dev_compiler/lib/js/amd/dart_sdk.js b/pkg/dev_compiler/lib/js/amd/dart_sdk.js
index a215552..9d6ddd8 100644
--- a/pkg/dev_compiler/lib/js/amd/dart_sdk.js
+++ b/pkg/dev_compiler/lib/js/amd/dart_sdk.js
@@ -583,6 +583,7 @@
   let EventStreamProviderOfDeviceOrientationEvent = () => (EventStreamProviderOfDeviceOrientationEvent = dart.constFn(html$.EventStreamProvider$(html$.DeviceOrientationEvent)))();
   let EventStreamProviderOfAnimationEvent = () => (EventStreamProviderOfAnimationEvent = dart.constFn(html$.EventStreamProvider$(html$.AnimationEvent)))();
   let EventStreamProviderOfBeforeUnloadEvent = () => (EventStreamProviderOfBeforeUnloadEvent = dart.constFn(html$.EventStreamProvider$(html$.BeforeUnloadEvent)))();
+  let _EventStreamOfBeforeUnloadEvent = () => (_EventStreamOfBeforeUnloadEvent = dart.constFn(html$._EventStream$(html$.BeforeUnloadEvent)))();
   let StreamControllerOfBeforeUnloadEvent = () => (StreamControllerOfBeforeUnloadEvent = dart.constFn(async.StreamController$(html$.BeforeUnloadEvent)))();
   let _ElementEventStreamImplOfBeforeUnloadEvent = () => (_ElementEventStreamImplOfBeforeUnloadEvent = dart.constFn(html$._ElementEventStreamImpl$(html$.BeforeUnloadEvent)))();
   let _ElementListEventStreamImplOfBeforeUnloadEvent = () => (_ElementListEventStreamImplOfBeforeUnloadEvent = dart.constFn(html$._ElementListEventStreamImpl$(html$.BeforeUnloadEvent)))();
@@ -881,7 +882,6 @@
   let dynamicToMap = () => (dynamicToMap = dart.constFn(dart.definiteFunctionType(core.Map, [dart.dynamic])))();
   let ListToIsolate = () => (ListToIsolate = dart.constFn(dart.definiteFunctionType(isolate.Isolate, [core.List])))();
   let dynamicTo_DartObject = () => (dynamicTo_DartObject = dart.constFn(dart.definiteFunctionType(js._DartObject, [dart.dynamic])))();
-  let dynamicToJsObject = () => (dynamicToJsObject = dart.constFn(dart.definiteFunctionType(js.JsObject, [dart.dynamic])))();
   let dynamicAnddynamicAndFnToObject = () => (dynamicAnddynamicAndFnToObject = dart.constFn(dart.definiteFunctionType(core.Object, [dart.dynamic, dart.dynamic, dynamicTodynamic()])))();
   let FToF = () => (FToF = dart.constFn(dart.definiteFunctionType(F => [F, [F]])))();
   let FunctionToFunction = () => (FunctionToFunction = dart.constFn(dart.definiteFunctionType(core.Function, [core.Function])))();
@@ -925,6 +925,7 @@
   let RtcStatsResponseTovoid = () => (RtcStatsResponseTovoid = dart.constFn(dart.definiteFunctionType(dart.void, [html$.RtcStatsResponse])))();
   let OptionElementTobool = () => (OptionElementTobool = dart.constFn(dart.definiteFunctionType(core.bool, [html$.OptionElement])))();
   let numTovoid = () => (numTovoid = dart.constFn(dart.definiteFunctionType(dart.void, [core.num])))();
+  let BeforeUnloadEventTovoid = () => (BeforeUnloadEventTovoid = dart.constFn(dart.definiteFunctionType(dart.void, [html$.BeforeUnloadEvent])))();
   let ElementTovoid$ = () => (ElementTovoid$ = dart.constFn(dart.definiteFunctionType(dart.void, [html$.Element])))();
   let ElementToCssClassSet = () => (ElementToCssClassSet = dart.constFn(dart.definiteFunctionType(html$.CssClassSet, [html$.Element])))();
   let CssClassSetImplTovoid = () => (CssClassSetImplTovoid = dart.constFn(dart.definiteFunctionType(dart.void, [html_common.CssClassSetImpl])))();
@@ -3335,7 +3336,7 @@
         protoChain[dartx.add](current);
         current = _debugger.safeGetProperty(current, '__proto__');
       }
-      for (/* Unimplemented unknown name */current of protoChain) {
+      for (current of protoChain) {
         for (let symbol of _debugger.getOwnPropertySymbols(current)) {
           let dartName = _debugger.symbolName(symbol);
           if (dart.test(_debugger.hasMethod(object, dartName))) {
@@ -3351,7 +3352,7 @@
           properties.add(new _debugger.NameValuePair({name: dartName, value: value}));
         }
       }
-      for (/* Unimplemented unknown name */current of protoChain) {
+      for (current of protoChain) {
         let className = dart.dload(dart.getReifiedType(current), 'name');
         for (let name of _debugger.getOwnPropertyNames(current)) {
           if (dart.test(_debugger.ObjectFormatter._customNames.contains(name)) || dart.equals(name, className)) continue;
@@ -52593,7 +52594,7 @@
   });
   dart.defineLazy(js, {
     get context() {
-      return js._wrapToDart(js._global);
+      return js.JsObject._check(js._wrapToDart(js._global));
     }
   });
   const _jsObject = Symbol('_jsObject');
@@ -52606,22 +52607,22 @@
       if (arguments$ === void 0) arguments$ = null;
       let ctor = constructor[_jsObject];
       if (arguments$ == null) {
-        return js._wrapToDart(new ctor());
+        return js.JsObject._check(js._wrapToDart(new ctor()));
       }
       let unwrapped = core.List.from(arguments$[dartx.map](dart.dynamic)(js._convertToJS));
-      return js._wrapToDart(new ctor(...unwrapped));
+      return js.JsObject._check(js._wrapToDart(new ctor(...unwrapped)));
     }
     static fromBrowserObject(object) {
       if (typeof object == 'number' || typeof object == 'string' || typeof object == 'boolean' || object == null) {
         dart.throw(new core.ArgumentError("object cannot be a num, string, bool, or null"));
       }
-      return js._wrapToDart(js._convertToJS(object));
+      return js.JsObject._check(js._wrapToDart(js._convertToJS(object)));
     }
     static jsify(object) {
       if (!core.Map.is(object) && !core.Iterable.is(object)) {
         dart.throw(new core.ArgumentError("object must be a Map or Iterable"));
       }
-      return js._wrapToDart(js.JsObject._convertDataTree(object));
+      return js.JsObject._check(js._wrapToDart(js.JsObject._convertDataTree(object)));
     }
     static _convertDataTree(data) {
       let _convertedObjects = collection.HashMap.identity();
@@ -52949,9 +52950,9 @@
   };
   dart.fn(js._convertToDart, dynamicToObject());
   js._wrapToDart = function(o) {
-    return js.JsObject._check(js._putIfAbsent(js._dartProxies, o, js._wrapToDartHelper));
+    return js._putIfAbsent(js._dartProxies, o, js._wrapToDartHelper);
   };
-  dart.fn(js._wrapToDart, dynamicToJsObject());
+  dart.fn(js._wrapToDart, dynamicToObject());
   js._wrapToDartHelper = function(o) {
     if (typeof o == "function") {
       return new js.JsFunction._fromJs(o);
@@ -52961,7 +52962,7 @@
     }
     return new js.JsObject._fromJs(o);
   };
-  dart.fn(js._wrapToDartHelper, dynamicToJsObject());
+  dart.fn(js._wrapToDartHelper, dynamicToObject());
   dart.defineLazy(js, {
     get _dartProxies() {
       return new WeakMap();
@@ -93234,12 +93235,12 @@
     }
     forTarget(e, opts) {
       let useCapture = opts && 'useCapture' in opts ? opts.useCapture : false;
-      let stream = new (_EventStreamOfEvent())(e, this[_eventType], useCapture);
+      let stream = new (_EventStreamOfBeforeUnloadEvent())(e, this[_eventType], useCapture);
       let controller = StreamControllerOfBeforeUnloadEvent().new({sync: true});
       stream.listen(dart.fn(event => {
         let wrapped = new html$._BeforeUnloadEvent(event);
         controller.add(wrapped);
-      }, EventTovoid$()));
+      }, BeforeUnloadEventTovoid()));
       return controller.stream;
     }
     getEventType(target) {
@@ -96401,7 +96402,7 @@
         this[_target$0] = target;
         this[_eventType] = eventType;
         this[_useCapture] = useCapture;
-        this[_onData$0] = html$._wrapZone(html$.Event, dart.dynamic)(_wrapZoneCallbackOfEvent$dynamic()._check(onData));
+        this[_onData$0] = onData == null ? null : html$._wrapZone(html$.Event, dart.dynamic)(dart.fn(e => dart.dcall(onData, e), EventTodynamic()));
         this[_pauseCount$0] = 0;
         this[_tryResume]();
       }
@@ -96452,10 +96453,12 @@
           this[_target$0][dartx.removeEventListener](this[_eventType], this[_onData$0], this[_useCapture]);
         }
       }
-      asFuture(futureValue) {
-        if (futureValue === void 0) futureValue = null;
-        let completer = async.Completer.new();
-        return completer.future;
+      asFuture(E) {
+        return futureValue => {
+          if (futureValue === void 0) futureValue = null;
+          let completer = async.Completer$(E).new();
+          return completer.future;
+        };
       }
     }
     dart.setSignature(_EventStreamSubscription, {
@@ -96480,7 +96483,7 @@
         resume: dart.definiteFunctionType(dart.void, []),
         [_tryResume]: dart.definiteFunctionType(dart.void, []),
         [_unlisten]: dart.definiteFunctionType(dart.void, []),
-        asFuture: dart.definiteFunctionType(async.Future, [], [dart.dynamic])
+        asFuture: dart.definiteFunctionType(E => [async.Future$(E), [], [E]])
       })
     });
     return _EventStreamSubscription;
diff --git a/pkg/dev_compiler/lib/js/common/dart_sdk.js b/pkg/dev_compiler/lib/js/common/dart_sdk.js
index deef7b3..2b4c910 100644
--- a/pkg/dev_compiler/lib/js/common/dart_sdk.js
+++ b/pkg/dev_compiler/lib/js/common/dart_sdk.js
@@ -583,6 +583,7 @@
   let EventStreamProviderOfDeviceOrientationEvent = () => (EventStreamProviderOfDeviceOrientationEvent = dart.constFn(html$.EventStreamProvider$(html$.DeviceOrientationEvent)))();
   let EventStreamProviderOfAnimationEvent = () => (EventStreamProviderOfAnimationEvent = dart.constFn(html$.EventStreamProvider$(html$.AnimationEvent)))();
   let EventStreamProviderOfBeforeUnloadEvent = () => (EventStreamProviderOfBeforeUnloadEvent = dart.constFn(html$.EventStreamProvider$(html$.BeforeUnloadEvent)))();
+  let _EventStreamOfBeforeUnloadEvent = () => (_EventStreamOfBeforeUnloadEvent = dart.constFn(html$._EventStream$(html$.BeforeUnloadEvent)))();
   let StreamControllerOfBeforeUnloadEvent = () => (StreamControllerOfBeforeUnloadEvent = dart.constFn(async.StreamController$(html$.BeforeUnloadEvent)))();
   let _ElementEventStreamImplOfBeforeUnloadEvent = () => (_ElementEventStreamImplOfBeforeUnloadEvent = dart.constFn(html$._ElementEventStreamImpl$(html$.BeforeUnloadEvent)))();
   let _ElementListEventStreamImplOfBeforeUnloadEvent = () => (_ElementListEventStreamImplOfBeforeUnloadEvent = dart.constFn(html$._ElementListEventStreamImpl$(html$.BeforeUnloadEvent)))();
@@ -881,7 +882,6 @@
   let dynamicToMap = () => (dynamicToMap = dart.constFn(dart.definiteFunctionType(core.Map, [dart.dynamic])))();
   let ListToIsolate = () => (ListToIsolate = dart.constFn(dart.definiteFunctionType(isolate.Isolate, [core.List])))();
   let dynamicTo_DartObject = () => (dynamicTo_DartObject = dart.constFn(dart.definiteFunctionType(js._DartObject, [dart.dynamic])))();
-  let dynamicToJsObject = () => (dynamicToJsObject = dart.constFn(dart.definiteFunctionType(js.JsObject, [dart.dynamic])))();
   let dynamicAnddynamicAndFnToObject = () => (dynamicAnddynamicAndFnToObject = dart.constFn(dart.definiteFunctionType(core.Object, [dart.dynamic, dart.dynamic, dynamicTodynamic()])))();
   let FToF = () => (FToF = dart.constFn(dart.definiteFunctionType(F => [F, [F]])))();
   let FunctionToFunction = () => (FunctionToFunction = dart.constFn(dart.definiteFunctionType(core.Function, [core.Function])))();
@@ -925,6 +925,7 @@
   let RtcStatsResponseTovoid = () => (RtcStatsResponseTovoid = dart.constFn(dart.definiteFunctionType(dart.void, [html$.RtcStatsResponse])))();
   let OptionElementTobool = () => (OptionElementTobool = dart.constFn(dart.definiteFunctionType(core.bool, [html$.OptionElement])))();
   let numTovoid = () => (numTovoid = dart.constFn(dart.definiteFunctionType(dart.void, [core.num])))();
+  let BeforeUnloadEventTovoid = () => (BeforeUnloadEventTovoid = dart.constFn(dart.definiteFunctionType(dart.void, [html$.BeforeUnloadEvent])))();
   let ElementTovoid$ = () => (ElementTovoid$ = dart.constFn(dart.definiteFunctionType(dart.void, [html$.Element])))();
   let ElementToCssClassSet = () => (ElementToCssClassSet = dart.constFn(dart.definiteFunctionType(html$.CssClassSet, [html$.Element])))();
   let CssClassSetImplTovoid = () => (CssClassSetImplTovoid = dart.constFn(dart.definiteFunctionType(dart.void, [html_common.CssClassSetImpl])))();
@@ -3335,7 +3336,7 @@
         protoChain[dartx.add](current);
         current = _debugger.safeGetProperty(current, '__proto__');
       }
-      for (/* Unimplemented unknown name */current of protoChain) {
+      for (current of protoChain) {
         for (let symbol of _debugger.getOwnPropertySymbols(current)) {
           let dartName = _debugger.symbolName(symbol);
           if (dart.test(_debugger.hasMethod(object, dartName))) {
@@ -3351,7 +3352,7 @@
           properties.add(new _debugger.NameValuePair({name: dartName, value: value}));
         }
       }
-      for (/* Unimplemented unknown name */current of protoChain) {
+      for (current of protoChain) {
         let className = dart.dload(dart.getReifiedType(current), 'name');
         for (let name of _debugger.getOwnPropertyNames(current)) {
           if (dart.test(_debugger.ObjectFormatter._customNames.contains(name)) || dart.equals(name, className)) continue;
@@ -52593,7 +52594,7 @@
   });
   dart.defineLazy(js, {
     get context() {
-      return js._wrapToDart(js._global);
+      return js.JsObject._check(js._wrapToDart(js._global));
     }
   });
   const _jsObject = Symbol('_jsObject');
@@ -52606,22 +52607,22 @@
       if (arguments$ === void 0) arguments$ = null;
       let ctor = constructor[_jsObject];
       if (arguments$ == null) {
-        return js._wrapToDart(new ctor());
+        return js.JsObject._check(js._wrapToDart(new ctor()));
       }
       let unwrapped = core.List.from(arguments$[dartx.map](dart.dynamic)(js._convertToJS));
-      return js._wrapToDart(new ctor(...unwrapped));
+      return js.JsObject._check(js._wrapToDart(new ctor(...unwrapped)));
     }
     static fromBrowserObject(object) {
       if (typeof object == 'number' || typeof object == 'string' || typeof object == 'boolean' || object == null) {
         dart.throw(new core.ArgumentError("object cannot be a num, string, bool, or null"));
       }
-      return js._wrapToDart(js._convertToJS(object));
+      return js.JsObject._check(js._wrapToDart(js._convertToJS(object)));
     }
     static jsify(object) {
       if (!core.Map.is(object) && !core.Iterable.is(object)) {
         dart.throw(new core.ArgumentError("object must be a Map or Iterable"));
       }
-      return js._wrapToDart(js.JsObject._convertDataTree(object));
+      return js.JsObject._check(js._wrapToDart(js.JsObject._convertDataTree(object)));
     }
     static _convertDataTree(data) {
       let _convertedObjects = collection.HashMap.identity();
@@ -52949,9 +52950,9 @@
   };
   dart.fn(js._convertToDart, dynamicToObject());
   js._wrapToDart = function(o) {
-    return js.JsObject._check(js._putIfAbsent(js._dartProxies, o, js._wrapToDartHelper));
+    return js._putIfAbsent(js._dartProxies, o, js._wrapToDartHelper);
   };
-  dart.fn(js._wrapToDart, dynamicToJsObject());
+  dart.fn(js._wrapToDart, dynamicToObject());
   js._wrapToDartHelper = function(o) {
     if (typeof o == "function") {
       return new js.JsFunction._fromJs(o);
@@ -52961,7 +52962,7 @@
     }
     return new js.JsObject._fromJs(o);
   };
-  dart.fn(js._wrapToDartHelper, dynamicToJsObject());
+  dart.fn(js._wrapToDartHelper, dynamicToObject());
   dart.defineLazy(js, {
     get _dartProxies() {
       return new WeakMap();
@@ -93234,12 +93235,12 @@
     }
     forTarget(e, opts) {
       let useCapture = opts && 'useCapture' in opts ? opts.useCapture : false;
-      let stream = new (_EventStreamOfEvent())(e, this[_eventType], useCapture);
+      let stream = new (_EventStreamOfBeforeUnloadEvent())(e, this[_eventType], useCapture);
       let controller = StreamControllerOfBeforeUnloadEvent().new({sync: true});
       stream.listen(dart.fn(event => {
         let wrapped = new html$._BeforeUnloadEvent(event);
         controller.add(wrapped);
-      }, EventTovoid$()));
+      }, BeforeUnloadEventTovoid()));
       return controller.stream;
     }
     getEventType(target) {
@@ -96401,7 +96402,7 @@
         this[_target$0] = target;
         this[_eventType] = eventType;
         this[_useCapture] = useCapture;
-        this[_onData$0] = html$._wrapZone(html$.Event, dart.dynamic)(_wrapZoneCallbackOfEvent$dynamic()._check(onData));
+        this[_onData$0] = onData == null ? null : html$._wrapZone(html$.Event, dart.dynamic)(dart.fn(e => dart.dcall(onData, e), EventTodynamic()));
         this[_pauseCount$0] = 0;
         this[_tryResume]();
       }
@@ -96452,10 +96453,12 @@
           this[_target$0][dartx.removeEventListener](this[_eventType], this[_onData$0], this[_useCapture]);
         }
       }
-      asFuture(futureValue) {
-        if (futureValue === void 0) futureValue = null;
-        let completer = async.Completer.new();
-        return completer.future;
+      asFuture(E) {
+        return futureValue => {
+          if (futureValue === void 0) futureValue = null;
+          let completer = async.Completer$(E).new();
+          return completer.future;
+        };
       }
     }
     dart.setSignature(_EventStreamSubscription, {
@@ -96480,7 +96483,7 @@
         resume: dart.definiteFunctionType(dart.void, []),
         [_tryResume]: dart.definiteFunctionType(dart.void, []),
         [_unlisten]: dart.definiteFunctionType(dart.void, []),
-        asFuture: dart.definiteFunctionType(async.Future, [], [dart.dynamic])
+        asFuture: dart.definiteFunctionType(E => [async.Future$(E), [], [E]])
       })
     });
     return _EventStreamSubscription;
diff --git a/pkg/dev_compiler/lib/js/es6/dart_sdk.js b/pkg/dev_compiler/lib/js/es6/dart_sdk.js
index 76961b9..10c4a9a 100644
--- a/pkg/dev_compiler/lib/js/es6/dart_sdk.js
+++ b/pkg/dev_compiler/lib/js/es6/dart_sdk.js
@@ -581,6 +581,7 @@
 let EventStreamProviderOfDeviceOrientationEvent = () => (EventStreamProviderOfDeviceOrientationEvent = dart.constFn(html.EventStreamProvider$(html.DeviceOrientationEvent)))();
 let EventStreamProviderOfAnimationEvent = () => (EventStreamProviderOfAnimationEvent = dart.constFn(html.EventStreamProvider$(html.AnimationEvent)))();
 let EventStreamProviderOfBeforeUnloadEvent = () => (EventStreamProviderOfBeforeUnloadEvent = dart.constFn(html.EventStreamProvider$(html.BeforeUnloadEvent)))();
+let _EventStreamOfBeforeUnloadEvent = () => (_EventStreamOfBeforeUnloadEvent = dart.constFn(html._EventStream$(html.BeforeUnloadEvent)))();
 let StreamControllerOfBeforeUnloadEvent = () => (StreamControllerOfBeforeUnloadEvent = dart.constFn(async.StreamController$(html.BeforeUnloadEvent)))();
 let _ElementEventStreamImplOfBeforeUnloadEvent = () => (_ElementEventStreamImplOfBeforeUnloadEvent = dart.constFn(html._ElementEventStreamImpl$(html.BeforeUnloadEvent)))();
 let _ElementListEventStreamImplOfBeforeUnloadEvent = () => (_ElementListEventStreamImplOfBeforeUnloadEvent = dart.constFn(html._ElementListEventStreamImpl$(html.BeforeUnloadEvent)))();
@@ -879,7 +880,6 @@
 let dynamicToMap = () => (dynamicToMap = dart.constFn(dart.definiteFunctionType(core.Map, [dart.dynamic])))();
 let ListToIsolate = () => (ListToIsolate = dart.constFn(dart.definiteFunctionType(isolate.Isolate, [core.List])))();
 let dynamicTo_DartObject = () => (dynamicTo_DartObject = dart.constFn(dart.definiteFunctionType(js._DartObject, [dart.dynamic])))();
-let dynamicToJsObject = () => (dynamicToJsObject = dart.constFn(dart.definiteFunctionType(js.JsObject, [dart.dynamic])))();
 let dynamicAnddynamicAndFnToObject = () => (dynamicAnddynamicAndFnToObject = dart.constFn(dart.definiteFunctionType(core.Object, [dart.dynamic, dart.dynamic, dynamicTodynamic()])))();
 let FToF = () => (FToF = dart.constFn(dart.definiteFunctionType(F => [F, [F]])))();
 let FunctionToFunction = () => (FunctionToFunction = dart.constFn(dart.definiteFunctionType(core.Function, [core.Function])))();
@@ -923,6 +923,7 @@
 let RtcStatsResponseTovoid = () => (RtcStatsResponseTovoid = dart.constFn(dart.definiteFunctionType(dart.void, [html.RtcStatsResponse])))();
 let OptionElementTobool = () => (OptionElementTobool = dart.constFn(dart.definiteFunctionType(core.bool, [html.OptionElement])))();
 let numTovoid = () => (numTovoid = dart.constFn(dart.definiteFunctionType(dart.void, [core.num])))();
+let BeforeUnloadEventTovoid = () => (BeforeUnloadEventTovoid = dart.constFn(dart.definiteFunctionType(dart.void, [html.BeforeUnloadEvent])))();
 let ElementTovoid = () => (ElementTovoid = dart.constFn(dart.definiteFunctionType(dart.void, [html.Element])))();
 let ElementToCssClassSet = () => (ElementToCssClassSet = dart.constFn(dart.definiteFunctionType(html.CssClassSet, [html.Element])))();
 let CssClassSetImplTovoid = () => (CssClassSetImplTovoid = dart.constFn(dart.definiteFunctionType(dart.void, [html_common.CssClassSetImpl])))();
@@ -3333,7 +3334,7 @@
       protoChain[dartx.add](current);
       current = _debugger.safeGetProperty(current, '__proto__');
     }
-    for (/* Unimplemented unknown name */current of protoChain) {
+    for (current of protoChain) {
       for (let symbol of _debugger.getOwnPropertySymbols(current)) {
         let dartName = _debugger.symbolName(symbol);
         if (dart.test(_debugger.hasMethod(object, dartName))) {
@@ -3349,7 +3350,7 @@
         properties.add(new _debugger.NameValuePair({name: dartName, value: value}));
       }
     }
-    for (/* Unimplemented unknown name */current of protoChain) {
+    for (current of protoChain) {
       let className = dart.dload(dart.getReifiedType(current), 'name');
       for (let name of _debugger.getOwnPropertyNames(current)) {
         if (dart.test(_debugger.ObjectFormatter._customNames.contains(name)) || dart.equals(name, className)) continue;
@@ -52591,7 +52592,7 @@
 });
 dart.defineLazy(js, {
   get context() {
-    return js._wrapToDart(js._global);
+    return js.JsObject._check(js._wrapToDart(js._global));
   }
 });
 const _jsObject = Symbol('_jsObject');
@@ -52604,22 +52605,22 @@
     if (arguments$ === void 0) arguments$ = null;
     let ctor = constructor[_jsObject];
     if (arguments$ == null) {
-      return js._wrapToDart(new ctor());
+      return js.JsObject._check(js._wrapToDart(new ctor()));
     }
     let unwrapped = core.List.from(arguments$[dartx.map](dart.dynamic)(js._convertToJS));
-    return js._wrapToDart(new ctor(...unwrapped));
+    return js.JsObject._check(js._wrapToDart(new ctor(...unwrapped)));
   }
   static fromBrowserObject(object) {
     if (typeof object == 'number' || typeof object == 'string' || typeof object == 'boolean' || object == null) {
       dart.throw(new core.ArgumentError("object cannot be a num, string, bool, or null"));
     }
-    return js._wrapToDart(js._convertToJS(object));
+    return js.JsObject._check(js._wrapToDart(js._convertToJS(object)));
   }
   static jsify(object) {
     if (!core.Map.is(object) && !core.Iterable.is(object)) {
       dart.throw(new core.ArgumentError("object must be a Map or Iterable"));
     }
-    return js._wrapToDart(js.JsObject._convertDataTree(object));
+    return js.JsObject._check(js._wrapToDart(js.JsObject._convertDataTree(object)));
   }
   static _convertDataTree(data) {
     let _convertedObjects = collection.HashMap.identity();
@@ -52947,9 +52948,9 @@
 };
 dart.fn(js._convertToDart, dynamicToObject());
 js._wrapToDart = function(o) {
-  return js.JsObject._check(js._putIfAbsent(js._dartProxies, o, js._wrapToDartHelper));
+  return js._putIfAbsent(js._dartProxies, o, js._wrapToDartHelper);
 };
-dart.fn(js._wrapToDart, dynamicToJsObject());
+dart.fn(js._wrapToDart, dynamicToObject());
 js._wrapToDartHelper = function(o) {
   if (typeof o == "function") {
     return new js.JsFunction._fromJs(o);
@@ -52959,7 +52960,7 @@
   }
   return new js.JsObject._fromJs(o);
 };
-dart.fn(js._wrapToDartHelper, dynamicToJsObject());
+dart.fn(js._wrapToDartHelper, dynamicToObject());
 dart.defineLazy(js, {
   get _dartProxies() {
     return new WeakMap();
@@ -93232,12 +93233,12 @@
   }
   forTarget(e, opts) {
     let useCapture = opts && 'useCapture' in opts ? opts.useCapture : false;
-    let stream = new (_EventStreamOfEvent())(e, this[_eventType], useCapture);
+    let stream = new (_EventStreamOfBeforeUnloadEvent())(e, this[_eventType], useCapture);
     let controller = StreamControllerOfBeforeUnloadEvent().new({sync: true});
     stream.listen(dart.fn(event => {
       let wrapped = new html._BeforeUnloadEvent(event);
       controller.add(wrapped);
-    }, EventTovoid()));
+    }, BeforeUnloadEventTovoid()));
     return controller.stream;
   }
   getEventType(target) {
@@ -96399,7 +96400,7 @@
       this[_target] = target;
       this[_eventType] = eventType;
       this[_useCapture] = useCapture;
-      this[_onData] = html._wrapZone(html.Event, dart.dynamic)(_wrapZoneCallbackOfEvent$dynamic()._check(onData));
+      this[_onData] = onData == null ? null : html._wrapZone(html.Event, dart.dynamic)(dart.fn(e => dart.dcall(onData, e), EventTodynamic()));
       this[_pauseCount] = 0;
       this[_tryResume]();
     }
@@ -96450,10 +96451,12 @@
         this[_target][dartx.removeEventListener](this[_eventType], this[_onData], this[_useCapture]);
       }
     }
-    asFuture(futureValue) {
-      if (futureValue === void 0) futureValue = null;
-      let completer = async.Completer.new();
-      return completer.future;
+    asFuture(E) {
+      return futureValue => {
+        if (futureValue === void 0) futureValue = null;
+        let completer = async.Completer$(E).new();
+        return completer.future;
+      };
     }
   }
   dart.setSignature(_EventStreamSubscription, {
@@ -96478,7 +96481,7 @@
       resume: dart.definiteFunctionType(dart.void, []),
       [_tryResume]: dart.definiteFunctionType(dart.void, []),
       [_unlisten]: dart.definiteFunctionType(dart.void, []),
-      asFuture: dart.definiteFunctionType(async.Future, [], [dart.dynamic])
+      asFuture: dart.definiteFunctionType(E => [async.Future$(E), [], [E]])
     })
   });
   return _EventStreamSubscription;
diff --git a/pkg/dev_compiler/lib/js/legacy/dart_sdk.js b/pkg/dev_compiler/lib/js/legacy/dart_sdk.js
index 23e0714..7820c1b 100644
--- a/pkg/dev_compiler/lib/js/legacy/dart_sdk.js
+++ b/pkg/dev_compiler/lib/js/legacy/dart_sdk.js
@@ -584,6 +584,7 @@
   let EventStreamProviderOfDeviceOrientationEvent = () => (EventStreamProviderOfDeviceOrientationEvent = dart.constFn(html$.EventStreamProvider$(html$.DeviceOrientationEvent)))();
   let EventStreamProviderOfAnimationEvent = () => (EventStreamProviderOfAnimationEvent = dart.constFn(html$.EventStreamProvider$(html$.AnimationEvent)))();
   let EventStreamProviderOfBeforeUnloadEvent = () => (EventStreamProviderOfBeforeUnloadEvent = dart.constFn(html$.EventStreamProvider$(html$.BeforeUnloadEvent)))();
+  let _EventStreamOfBeforeUnloadEvent = () => (_EventStreamOfBeforeUnloadEvent = dart.constFn(html$._EventStream$(html$.BeforeUnloadEvent)))();
   let StreamControllerOfBeforeUnloadEvent = () => (StreamControllerOfBeforeUnloadEvent = dart.constFn(async.StreamController$(html$.BeforeUnloadEvent)))();
   let _ElementEventStreamImplOfBeforeUnloadEvent = () => (_ElementEventStreamImplOfBeforeUnloadEvent = dart.constFn(html$._ElementEventStreamImpl$(html$.BeforeUnloadEvent)))();
   let _ElementListEventStreamImplOfBeforeUnloadEvent = () => (_ElementListEventStreamImplOfBeforeUnloadEvent = dart.constFn(html$._ElementListEventStreamImpl$(html$.BeforeUnloadEvent)))();
@@ -882,7 +883,6 @@
   let dynamicToMap = () => (dynamicToMap = dart.constFn(dart.definiteFunctionType(core.Map, [dart.dynamic])))();
   let ListToIsolate = () => (ListToIsolate = dart.constFn(dart.definiteFunctionType(isolate.Isolate, [core.List])))();
   let dynamicTo_DartObject = () => (dynamicTo_DartObject = dart.constFn(dart.definiteFunctionType(js._DartObject, [dart.dynamic])))();
-  let dynamicToJsObject = () => (dynamicToJsObject = dart.constFn(dart.definiteFunctionType(js.JsObject, [dart.dynamic])))();
   let dynamicAnddynamicAndFnToObject = () => (dynamicAnddynamicAndFnToObject = dart.constFn(dart.definiteFunctionType(core.Object, [dart.dynamic, dart.dynamic, dynamicTodynamic()])))();
   let FToF = () => (FToF = dart.constFn(dart.definiteFunctionType(F => [F, [F]])))();
   let FunctionToFunction = () => (FunctionToFunction = dart.constFn(dart.definiteFunctionType(core.Function, [core.Function])))();
@@ -926,6 +926,7 @@
   let RtcStatsResponseTovoid = () => (RtcStatsResponseTovoid = dart.constFn(dart.definiteFunctionType(dart.void, [html$.RtcStatsResponse])))();
   let OptionElementTobool = () => (OptionElementTobool = dart.constFn(dart.definiteFunctionType(core.bool, [html$.OptionElement])))();
   let numTovoid = () => (numTovoid = dart.constFn(dart.definiteFunctionType(dart.void, [core.num])))();
+  let BeforeUnloadEventTovoid = () => (BeforeUnloadEventTovoid = dart.constFn(dart.definiteFunctionType(dart.void, [html$.BeforeUnloadEvent])))();
   let ElementTovoid$ = () => (ElementTovoid$ = dart.constFn(dart.definiteFunctionType(dart.void, [html$.Element])))();
   let ElementToCssClassSet = () => (ElementToCssClassSet = dart.constFn(dart.definiteFunctionType(html$.CssClassSet, [html$.Element])))();
   let CssClassSetImplTovoid = () => (CssClassSetImplTovoid = dart.constFn(dart.definiteFunctionType(dart.void, [html_common.CssClassSetImpl])))();
@@ -3336,7 +3337,7 @@
         protoChain[dartx.add](current);
         current = _debugger.safeGetProperty(current, '__proto__');
       }
-      for (/* Unimplemented unknown name */current of protoChain) {
+      for (current of protoChain) {
         for (let symbol of _debugger.getOwnPropertySymbols(current)) {
           let dartName = _debugger.symbolName(symbol);
           if (dart.test(_debugger.hasMethod(object, dartName))) {
@@ -3352,7 +3353,7 @@
           properties.add(new _debugger.NameValuePair({name: dartName, value: value}));
         }
       }
-      for (/* Unimplemented unknown name */current of protoChain) {
+      for (current of protoChain) {
         let className = dart.dload(dart.getReifiedType(current), 'name');
         for (let name of _debugger.getOwnPropertyNames(current)) {
           if (dart.test(_debugger.ObjectFormatter._customNames.contains(name)) || dart.equals(name, className)) continue;
@@ -52594,7 +52595,7 @@
   });
   dart.defineLazy(js, {
     get context() {
-      return js._wrapToDart(js._global);
+      return js.JsObject._check(js._wrapToDart(js._global));
     }
   });
   const _jsObject = Symbol('_jsObject');
@@ -52607,22 +52608,22 @@
       if (arguments$ === void 0) arguments$ = null;
       let ctor = constructor[_jsObject];
       if (arguments$ == null) {
-        return js._wrapToDart(new ctor());
+        return js.JsObject._check(js._wrapToDart(new ctor()));
       }
       let unwrapped = core.List.from(arguments$[dartx.map](dart.dynamic)(js._convertToJS));
-      return js._wrapToDart(new ctor(...unwrapped));
+      return js.JsObject._check(js._wrapToDart(new ctor(...unwrapped)));
     }
     static fromBrowserObject(object) {
       if (typeof object == 'number' || typeof object == 'string' || typeof object == 'boolean' || object == null) {
         dart.throw(new core.ArgumentError("object cannot be a num, string, bool, or null"));
       }
-      return js._wrapToDart(js._convertToJS(object));
+      return js.JsObject._check(js._wrapToDart(js._convertToJS(object)));
     }
     static jsify(object) {
       if (!core.Map.is(object) && !core.Iterable.is(object)) {
         dart.throw(new core.ArgumentError("object must be a Map or Iterable"));
       }
-      return js._wrapToDart(js.JsObject._convertDataTree(object));
+      return js.JsObject._check(js._wrapToDart(js.JsObject._convertDataTree(object)));
     }
     static _convertDataTree(data) {
       let _convertedObjects = collection.HashMap.identity();
@@ -52950,9 +52951,9 @@
   };
   dart.fn(js._convertToDart, dynamicToObject());
   js._wrapToDart = function(o) {
-    return js.JsObject._check(js._putIfAbsent(js._dartProxies, o, js._wrapToDartHelper));
+    return js._putIfAbsent(js._dartProxies, o, js._wrapToDartHelper);
   };
-  dart.fn(js._wrapToDart, dynamicToJsObject());
+  dart.fn(js._wrapToDart, dynamicToObject());
   js._wrapToDartHelper = function(o) {
     if (typeof o == "function") {
       return new js.JsFunction._fromJs(o);
@@ -52962,7 +52963,7 @@
     }
     return new js.JsObject._fromJs(o);
   };
-  dart.fn(js._wrapToDartHelper, dynamicToJsObject());
+  dart.fn(js._wrapToDartHelper, dynamicToObject());
   dart.defineLazy(js, {
     get _dartProxies() {
       return new WeakMap();
@@ -93235,12 +93236,12 @@
     }
     forTarget(e, opts) {
       let useCapture = opts && 'useCapture' in opts ? opts.useCapture : false;
-      let stream = new (_EventStreamOfEvent())(e, this[_eventType], useCapture);
+      let stream = new (_EventStreamOfBeforeUnloadEvent())(e, this[_eventType], useCapture);
       let controller = StreamControllerOfBeforeUnloadEvent().new({sync: true});
       stream.listen(dart.fn(event => {
         let wrapped = new html$._BeforeUnloadEvent(event);
         controller.add(wrapped);
-      }, EventTovoid$()));
+      }, BeforeUnloadEventTovoid()));
       return controller.stream;
     }
     getEventType(target) {
@@ -96402,7 +96403,7 @@
         this[_target$0] = target;
         this[_eventType] = eventType;
         this[_useCapture] = useCapture;
-        this[_onData$0] = html$._wrapZone(html$.Event, dart.dynamic)(_wrapZoneCallbackOfEvent$dynamic()._check(onData));
+        this[_onData$0] = onData == null ? null : html$._wrapZone(html$.Event, dart.dynamic)(dart.fn(e => dart.dcall(onData, e), EventTodynamic()));
         this[_pauseCount$0] = 0;
         this[_tryResume]();
       }
@@ -96453,10 +96454,12 @@
           this[_target$0][dartx.removeEventListener](this[_eventType], this[_onData$0], this[_useCapture]);
         }
       }
-      asFuture(futureValue) {
-        if (futureValue === void 0) futureValue = null;
-        let completer = async.Completer.new();
-        return completer.future;
+      asFuture(E) {
+        return futureValue => {
+          if (futureValue === void 0) futureValue = null;
+          let completer = async.Completer$(E).new();
+          return completer.future;
+        };
       }
     }
     dart.setSignature(_EventStreamSubscription, {
@@ -96481,7 +96484,7 @@
         resume: dart.definiteFunctionType(dart.void, []),
         [_tryResume]: dart.definiteFunctionType(dart.void, []),
         [_unlisten]: dart.definiteFunctionType(dart.void, []),
-        asFuture: dart.definiteFunctionType(async.Future, [], [dart.dynamic])
+        asFuture: dart.definiteFunctionType(E => [async.Future$(E), [], [E]])
       })
     });
     return _EventStreamSubscription;
diff --git a/pkg/dev_compiler/lib/sdk/ddc_sdk.sum b/pkg/dev_compiler/lib/sdk/ddc_sdk.sum
index 9ba0e1c..073b986 100644
--- a/pkg/dev_compiler/lib/sdk/ddc_sdk.sum
+++ b/pkg/dev_compiler/lib/sdk/ddc_sdk.sum
Binary files differ
diff --git a/pkg/dev_compiler/lib/src/compiler/code_generator.dart b/pkg/dev_compiler/lib/src/compiler/code_generator.dart
index 46ddce3..d406907 100644
--- a/pkg/dev_compiler/lib/src/compiler/code_generator.dart
+++ b/pkg/dev_compiler/lib/src/compiler/code_generator.dart
@@ -60,7 +60,7 @@
   final SummaryDataStore summaryData;
 
   final CompilerOptions options;
-  final rules = new StrongTypeSystemImpl();
+  final StrongTypeSystemImpl rules;
 
   /// The set of libraries we are currently compiling, and the temporaries used
   /// to refer to them.
@@ -159,6 +159,7 @@
   CodeGenerator(
       AnalysisContext c, this.summaryData, this.options, this._extensionTypes)
       : context = c,
+        rules = new StrongTypeSystemImpl(c.typeProvider),
         types = c.typeProvider,
         _asyncStreamIterator =
             _getLibrary(c, 'dart:async').getType('StreamIterator').type,
diff --git a/pkg/dev_compiler/test/worker/worker_test.dart b/pkg/dev_compiler/test/worker/worker_test.dart
index af70a38..7f2aa11 100644
--- a/pkg/dev_compiler/test/worker/worker_test.dart
+++ b/pkg/dev_compiler/test/worker/worker_test.dart
@@ -44,7 +44,7 @@
 
     test('can compile in worker mode', () async {
       var args = executableArgs.toList()..add('--persistent_worker');
-      var process = await Process.start('dart', args);
+      var process = await Process.start(Platform.executable, args);
       var messageGrouper = new AsyncMessageGrouper(process.stdout);
 
       var request = new WorkRequest();
@@ -76,7 +76,7 @@
 
     test('can compile in basic mode', () {
       var args = executableArgs.toList()..addAll(compilerArgs);
-      var result = Process.runSync('dart', args);
+      var result = Process.runSync(Platform.executable, args);
 
       expect(result.exitCode, EXIT_CODE_OK);
       expect(result.stdout, isEmpty);
@@ -88,7 +88,7 @@
       var args = new List<String>.from(executableArgs)
         ..add('--does-not-exist')
         ..addAll(compilerArgs);
-      var result = Process.runSync('dart', args);
+      var result = Process.runSync(Platform.executable, args);
 
       expect(result.exitCode, 64);
       expect(result.stdout,
@@ -102,7 +102,7 @@
         ..add('--does-not-exist')
         ..add('--ignore-unrecognized-flags')
         ..addAll(compilerArgs);
-      var result = Process.runSync('dart', args);
+      var result = Process.runSync(Platform.executable, args);
 
       expect(result.exitCode, EXIT_CODE_OK);
       expect(result.stdout, isEmpty);
@@ -114,7 +114,7 @@
       argsFile.createSync();
       argsFile.writeAsStringSync(compilerArgs.join('\n'));
       var args = executableArgs.toList()..add('@${argsFile.path}');
-      var process = await Process.start('dart', args);
+      var process = await Process.start(Platform.executable, args);
       stderr.addStream(process.stderr);
       var futureProcessOutput = process.stdout.map(UTF8.decode).toList();
 
@@ -148,7 +148,7 @@
 
     test('can compile in basic mode', () {
       final dartSdkSummary = new File('lib/sdk/ddc_sdk.sum').absolute;
-      var result = Process.runSync('dart', [
+      var result = Process.runSync(Platform.executable, [
         'bin/dartdevc.dart',
         '--summary-extension=api.ds',
         '--no-source-map',
@@ -164,7 +164,7 @@
       expect(greetingJS.existsSync(), isTrue);
       expect(greetingSummary.existsSync(), isTrue);
 
-      result = Process.runSync('dart', [
+      result = Process.runSync(Platform.executable, [
         'bin/dartdevc.dart',
         '--no-source-map',
         '--no-summarize',
@@ -195,7 +195,7 @@
     });
 
     test('incorrect usage', () {
-      var result = Process.runSync('dart', [
+      var result = Process.runSync(Platform.executable, [
         'bin/dartdevc.dart',
         '--dart-sdk-summary',
         dartSdkSummary.path,
@@ -209,7 +209,7 @@
 
     test('compile errors', () {
       badFileDart.writeAsStringSync('main() => "hello world"');
-      var result = Process.runSync('dart', [
+      var result = Process.runSync(Platform.executable, [
         'bin/dartdevc.dart',
         '--no-source-map',
         '--dart-sdk-summary',
@@ -245,7 +245,7 @@
     });
 
     test('works if part and library supplied', () {
-      var result = Process.runSync('dart', [
+      var result = Process.runSync(Platform.executable, [
         'bin/dartdevc.dart',
         '--no-summarize',
         '--no-source-map',
@@ -263,7 +263,7 @@
     });
 
     test('works if part is not supplied', () {
-      var result = Process.runSync('dart', [
+      var result = Process.runSync(Platform.executable, [
         'bin/dartdevc.dart',
         '--no-summarize',
         '--no-source-map',
@@ -280,7 +280,7 @@
     });
 
     test('part without library is silently ignored', () {
-      var result = Process.runSync('dart', [
+      var result = Process.runSync(Platform.executable, [
         'bin/dartdevc.dart',
         '--no-summarize',
         '--no-source-map',
diff --git a/pkg/dev_compiler/tool/input_sdk/lib/html/dart2js/html_dart2js.dart b/pkg/dev_compiler/tool/input_sdk/lib/html/dart2js/html_dart2js.dart
index 9798bbe..670e039 100644
--- a/pkg/dev_compiler/tool/input_sdk/lib/html/dart2js/html_dart2js.dart
+++ b/pkg/dev_compiler/tool/input_sdk/lib/html/dart2js/html_dart2js.dart
@@ -36568,7 +36568,9 @@
   const _BeforeUnloadEventStreamProvider(this._eventType);
 
   Stream<BeforeUnloadEvent> forTarget(EventTarget e, {bool useCapture: false}) {
-    var stream = new _EventStream(e, _eventType, useCapture);
+    // Specify the generic type for EventStream only in dart2js to avoid
+    // checked mode errors in dartium.
+    var stream = new _EventStream<BeforeUnloadEvent>(e, _eventType, useCapture);
     var controller = new StreamController<BeforeUnloadEvent>(sync: true);
 
     stream.listen((event) {
@@ -36584,12 +36586,16 @@
   }
 
   ElementStream<BeforeUnloadEvent> forElement(Element e, {bool useCapture: false}) {
-    return new _ElementEventStreamImpl(e, _eventType, useCapture);
+    // Specify the generic type for _ElementEventStreamImpl only in dart2js to
+    // avoid checked mode errors in dartium.
+    return new _ElementEventStreamImpl<BeforeUnloadEvent>(e, _eventType, useCapture);
   }
 
   ElementStream<BeforeUnloadEvent> _forElementList(ElementList e,
       {bool useCapture: false}) {
-    return new _ElementListEventStreamImpl(e, _eventType, useCapture);
+    // Specify the generic type for _ElementEventStreamImpl only in dart2js to
+    // avoid checked mode errors in dartium.
+    return new _ElementListEventStreamImpl<BeforeUnloadEvent>(e, _eventType, useCapture);
   }
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -39931,7 +39937,7 @@
    * [addEventListener](http://docs.webplatform.org/wiki/dom/methods/addEventListener)
    */
   ElementStream<T> _forElementList(ElementList e, {bool useCapture: false}) {
-    return new _ElementListEventStreamImpl(e, _eventType, useCapture);
+    return new _ElementListEventStreamImpl<T>(e, _eventType, useCapture);
   }
 
   /**
@@ -40081,13 +40087,21 @@
   EventListener _onData;
   final bool _useCapture;
 
-  // TODO(jacobr): for full strong mode correctness we should write
-  // _onData = onData == null ? null : _wrapZone/*<Event, dynamic>*/((e) => onData(e as T))
-  // but that breaks 114 co19 tests as well as multiple html tests as it is reasonable
-  // to pass the wrong type of event object to an event listener as part of a
-  // test.
+  // TODO(leafp): It would be better to write this as
+  // _onData = onData == null ? null :
+  //   onData is _wrapZoneCallback<Event, dynamic>
+  //     ? _wrapZone/*<Event, dynamic>*/(onData)
+  //     : _wrapZone/*<Event, dynamic>*/((e) => onData(e as T))
+  // In order to support existing tests which pass the wrong type of events but
+  // use a more general listener, without causing as much slowdown for things
+  // which are typed correctly.  But this currently runs afoul of restrictions
+  // on is checks for compatibility with the VM.
   _EventStreamSubscription(this._target, this._eventType, void onData(T event),
-      this._useCapture) : _onData = _wrapZone/*<Event, dynamic>*/(onData) {
+                           this._useCapture) :
+      _onData = onData == null
+      ? null
+      : _wrapZone/*<Event, dynamic>*/((e) => (onData as dynamic)(e))
+  {
     _tryResume();
   }
 
@@ -40149,9 +40163,9 @@
     }
   }
 
-  Future asFuture([var futureValue]) {
+  Future/*<E>*/ asFuture/*<E>*/([var/*=E*/ futureValue]) {
     // We just need a future that will never succeed or fail.
-    Completer completer = new Completer();
+    var completer = new Completer/*<E>*/();
     return completer.future;
   }
 }
@@ -42527,7 +42541,7 @@
 
   // Iterable APIs
 
-  Iterator<E> get iterator => new _WrappedIterator(_list.iterator);
+  Iterator<E> get iterator => new _WrappedIterator<E>(_list.iterator);
 
   int get length => _list.length;
 
@@ -43387,17 +43401,13 @@
   // For performance reasons avoid wrapping if we are in the root zone.
   if (Zone.current == Zone.ROOT) return callback;
   if (callback == null) return null;
-  // TODO(jacobr): we cast to _wrapZoneCallback/*<A, R>*/ to hack around missing
-  // generic method support in zones.
-  return Zone.current.bindUnaryCallback(callback, runGuarded: true) as _wrapZoneCallback/*<A, R>*/;
+  return Zone.current.bindUnaryCallback/*<R, A>*/(callback, runGuarded: true);
 }
 
 _wrapZoneBinaryCallback/*<A, B, R>*/ _wrapBinaryZone/*<A, B, R>*/(_wrapZoneBinaryCallback/*<A, B, R>*/ callback) {
   if (Zone.current == Zone.ROOT) return callback;
   if (callback == null) return null;
-  // We cast to _wrapZoneBinaryCallback/*<A, B, R>*/ to hack around missing
-  // generic method support in zones.
-  return Zone.current.bindBinaryCallback(callback, runGuarded: true) as _wrapZoneBinaryCallback/*<A, B, R>*/;
+  return Zone.current.bindBinaryCallback/*<R, A, B>*/(callback, runGuarded: true);
 }
 
 /**
diff --git a/pkg/dev_compiler/tool/input_sdk/lib/js/dart2js/js_dart2js.dart b/pkg/dev_compiler/tool/input_sdk/lib/js/dart2js/js_dart2js.dart
index ae590ad..eb15560 100644
--- a/pkg/dev_compiler/tool/input_sdk/lib/js/dart2js/js_dart2js.dart
+++ b/pkg/dev_compiler/tool/input_sdk/lib/js/dart2js/js_dart2js.dart
@@ -502,9 +502,9 @@
   }
 }
 
-JsObject _wrapToDart(o) => _putIfAbsent(_dartProxies, o, _wrapToDartHelper);
+Object _wrapToDart(o) => _putIfAbsent(_dartProxies, o, _wrapToDartHelper);
 
-JsObject _wrapToDartHelper(o) {
+Object _wrapToDartHelper(o) {
   if (JS('bool', 'typeof # == "function"', o)) {
     return new JsFunction._fromJs(o);
   }
diff --git a/pkg/dev_compiler/tool/sdk_expected_errors.txt b/pkg/dev_compiler/tool/sdk_expected_errors.txt
index dde8a4e..0a3d26e 100644
--- a/pkg/dev_compiler/tool/sdk_expected_errors.txt
+++ b/pkg/dev_compiler/tool/sdk_expected_errors.txt
@@ -16,7 +16,6 @@
 [error] Const constructors can't throw exceptions. (dart:core/int.dart, line 34, col 5)
 [error] Only redirecting factory constructors can be declared to be 'const'. (dart:core/string.dart, line 156, col 9)
 [error] Const constructors can't throw exceptions. (dart:core/string.dart, line 157, col 5)
-[error] Invalid override. The type of '_EventStreamSubscription.asFuture' ('([dynamic]) → Future<dynamic>') isn't a subtype of 'StreamSubscription<T>.asFuture' ('<E>([E]) → Future<E>'). (dart:html, line 40152, col 3)
 [error] Couldn't infer type parameter 'S'; 'RandomAccessFile' must be of type 'File'. (dart:io/file_impl.dart, line 216, col 19)
 [error] The argument type '([dynamic]) → void' can't be assigned to the parameter type '(_ConnectionInfo) → dynamic'. (dart:io/http_impl.dart, line 1633, col 19)
 [error] The return type 'StreamSubscription<int>' isn't a 'StreamSubscription<List<int>>', as defined by the method 'listen'. (dart:io/http_parser.dart, line 208, col 14)
@@ -78,8 +77,7 @@
 [warning] The final variables 'form', 'labels' and '5' more must be initialized. (dart:html, line 32069, col 3)
 [warning] The final variables 'readyState' and 'track' must be initialized. (dart:html, line 33056, col 3)
 [warning] The final variables 'decodedFrameCount', 'droppedFrameCount' and '2' more must be initialized. (dart:html, line 33754, col 3)
-[warning] Unsafe implicit cast from '(T) → void' to '(Event) → dynamic'. This usually indicates that type information was lost and resulted in 'dynamic' and/or a place that will have a failure at runtime. (dart:html, line 40090, col 67)
-[warning] Unsafe implicit cast from '(T) → void' to '(Event) → dynamic'. This usually indicates that type information was lost and resulted in 'dynamic' and/or a place that will have a failure at runtime. (dart:html, line 40112, col 45)
+[warning] Unsafe implicit cast from '(T) → void' to '(Event) → dynamic'. This usually indicates that type information was lost and resulted in 'dynamic' and/or a place that will have a failure at runtime. (dart:html, line 40126, col 45)
 [warning] Unsafe implicit cast from 'List<dynamic>' to 'List<int>'. This usually indicates that type information was lost and resulted in 'dynamic' and/or a place that will have a failure at runtime. (dart:io/data_transformer.dart, line 492, col 23)
 [warning] Unsafe implicit cast from 'Stream<dynamic>' to 'Stream<FileSystemEntity>'. This usually indicates that type information was lost and resulted in 'dynamic' and/or a place that will have a failure at runtime. (dart:io/directory_impl.dart, line 239, col 12)
 [warning] Unsafe implicit cast from 'Future<dynamic>' to 'Future<List<int>>'. This usually indicates that type information was lost and resulted in 'dynamic' and/or a place that will have a failure at runtime. (dart:io/file_impl.dart, line 484, col 14)
diff --git a/pkg/front_end/lib/dependency_grapher.dart b/pkg/front_end/lib/dependency_grapher.dart
index a743168..6120490 100644
--- a/pkg/front_end/lib/dependency_grapher.dart
+++ b/pkg/front_end/lib/dependency_grapher.dart
@@ -4,45 +4,18 @@
 
 import 'dart:async';
 
-import 'package:analyzer/dart/ast/ast.dart';
-import 'package:analyzer/error/listener.dart';
-import 'package:analyzer/src/dart/scanner/reader.dart';
-import 'package:analyzer/src/generated/parser.dart';
-import 'package:front_end/file_system.dart';
-import 'package:front_end/src/async_dependency_walker.dart';
-import 'package:front_end/src/base/uri_resolver.dart';
-import 'package:front_end/src/scanner/scanner.dart';
-import 'package:package_config/packages_file.dart' as package_config;
-
-import 'compiler_options.dart';
+import 'package:front_end/compiler_options.dart';
+import 'package:front_end/src/base/processed_options.dart';
+import 'package:front_end/src/dependency_grapher_impl.dart' as impl;
 
 /// Generates a representation of the dependency graph of a program.
 ///
 /// Given the Uri of one or more files, this function follows `import`,
 /// `export`, and `part` declarations to discover a graph of all files involved
 /// in the program.
-Future<Graph> graphForProgram(
-    List<Uri> sources, CompilerOptions options) async {
-  Map<String, Uri> packages;
-  if (options.packagesFilePath == null) {
-    throw new UnimplementedError(); // TODO(paulberry): search for .packages
-  } else if (options.packagesFilePath.isEmpty) {
-    packages = {};
-  } else {
-    var contents = await options.fileSystem
-        .entityForPath(options.packagesFilePath)
-        .readAsBytes();
-    var baseLocation =
-        options.fileSystem.context.toUri(options.packagesFilePath);
-    packages = package_config.parse(contents, baseLocation);
-  }
-  var sdkLibraries = <String, Uri>{}; // TODO(paulberry): support SDK libraries
-  var uriResolver =
-      new UriResolver(packages, sdkLibraries, options.fileSystem.context);
-  var walker = new _Walker(options.fileSystem, uriResolver, options.compileSdk);
-  var startingPoint = new _StartingPoint(walker, sources);
-  await walker.walk(startingPoint);
-  return walker.graph;
+Future<Graph> graphForProgram(List<Uri> sources, CompilerOptions options) {
+  var processedOptions = new ProcessedOptions(options);
+  return impl.graphForProgram(sources, processedOptions);
 }
 
 /// A representation of the dependency graph of a program.
@@ -52,8 +25,6 @@
   /// A list of all library cycles in the program, in topologically sorted order
   /// (each cycle only depends on libraries in the cycles that precede it).
   final topologicallySortedCycles = <LibraryCycleNode>[];
-
-  Graph._();
 }
 
 /// A representation of a single library cycle in the dependency graph of a
@@ -64,8 +35,6 @@
   /// A map of all the libraries in the cycle, keyed by the URI of their
   /// defining compilation unit.
   final libraries = <Uri, LibraryNode>{};
-
-  LibraryCycleNode._();
 }
 
 /// A representation of a single library in the dependency graph of a program.
@@ -81,115 +50,5 @@
   /// A list of all the other libraries this library directly depends on.
   final dependencies = <LibraryNode>[];
 
-  LibraryNode._(this.uri);
-}
-
-class _Scanner extends Scanner {
-  _Scanner(String contents) : super(new CharSequenceReader(contents)) {
-    preserveComments = false;
-  }
-
-  @override
-  void reportError(errorCode, int offset, List<Object> arguments) {
-    // TODO(paulberry): report errors.
-  }
-}
-
-class _StartingPoint extends _WalkerNode {
-  final List<Uri> sources;
-
-  _StartingPoint(_Walker walker, this.sources) : super(walker, null);
-
-  @override
-  Future<List<_WalkerNode>> computeDependencies() async =>
-      sources.map(walker.nodeForUri).toList();
-}
-
-class _Walker extends AsyncDependencyWalker<_WalkerNode> {
-  final FileSystem fileSystem;
-  final UriResolver uriResolver;
-  final _nodesByUri = <Uri, _WalkerNode>{};
-  final graph = new Graph._();
-  final bool compileSdk;
-
-  _Walker(this.fileSystem, this.uriResolver, this.compileSdk);
-
-  @override
-  Future<Null> evaluate(_WalkerNode v) {
-    if (v is _StartingPoint) return new Future.value();
-    return evaluateScc([v]);
-  }
-
-  @override
-  Future<Null> evaluateScc(List<_WalkerNode> scc) {
-    var cycle = new LibraryCycleNode._();
-    for (var walkerNode in scc) {
-      cycle.libraries[walkerNode.uri] = walkerNode.library;
-    }
-    graph.topologicallySortedCycles.add(cycle);
-    return new Future.value();
-  }
-
-  _WalkerNode nodeForUri(Uri referencedUri) {
-    var dependencyNode = _nodesByUri.putIfAbsent(
-        referencedUri, () => new _WalkerNode(this, referencedUri));
-    return dependencyNode;
-  }
-}
-
-class _WalkerNode extends Node<_WalkerNode> {
-  static final dartCoreUri = Uri.parse('dart:core');
-  final _Walker walker;
-  final Uri uri;
-  final LibraryNode library;
-
-  _WalkerNode(this.walker, Uri uri)
-      : uri = uri,
-        library = new LibraryNode._(uri);
-
-  @override
-  Future<List<_WalkerNode>> computeDependencies() async {
-    var dependencies = <_WalkerNode>[];
-    // TODO(paulberry): add error recovery if the file can't be read.
-    var path = walker.uriResolver.resolve(uri);
-    if (path == null) {
-      // TODO(paulberry): If an error reporter was provided, report the error
-      // in the proper way and continue.
-      throw new StateError('Invalid URI: $uri');
-    }
-    var contents = await walker.fileSystem.entityForPath(path).readAsString();
-    var scanner = new _Scanner(contents);
-    var token = scanner.tokenize();
-    // TODO(paulberry): report errors.
-    var parser = new Parser(null, AnalysisErrorListener.NULL_LISTENER);
-    var unit = parser.parseDirectives(token);
-    bool coreUriFound = false;
-    void handleDependency(Uri referencedUri) {
-      _WalkerNode dependencyNode = walker.nodeForUri(referencedUri);
-      library.dependencies.add(dependencyNode.library);
-      if (referencedUri.scheme != 'dart' || walker.compileSdk) {
-        dependencies.add(dependencyNode);
-      }
-      if (referencedUri == dartCoreUri) {
-        coreUriFound = true;
-      }
-    }
-
-    for (var directive in unit.directives) {
-      if (directive is UriBasedDirective) {
-        // TODO(paulberry): when we support SDK libraries, we'll need more
-        // complex logic here to find SDK parts correctly.
-        var referencedUri = uri.resolve(directive.uri.stringValue);
-        if (directive is PartDirective) {
-          library.parts.add(referencedUri);
-        } else {
-          handleDependency(referencedUri);
-        }
-      }
-    }
-    if (!coreUriFound) {
-      handleDependency(dartCoreUri);
-    }
-    return dependencies;
-  }
+  LibraryNode(this.uri);
 }
diff --git a/pkg/front_end/lib/src/base/library_info.dart b/pkg/front_end/lib/src/base/library_info.dart
index 3549454..a66b6d5 100644
--- a/pkg/front_end/lib/src/base/library_info.dart
+++ b/pkg/front_end/lib/src/base/library_info.dart
@@ -1,3 +1,7 @@
+// 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.
+
 /// A bit flag used by [LibraryInfo] indicating that a library is used by
 /// dart2js.
 ///
diff --git a/pkg/front_end/lib/src/base/processed_options.dart b/pkg/front_end/lib/src/base/processed_options.dart
new file mode 100644
index 0000000..e1a4ef4
--- /dev/null
+++ b/pkg/front_end/lib/src/base/processed_options.dart
@@ -0,0 +1,84 @@
+// 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 'dart:async';
+
+import 'package:front_end/compiler_options.dart';
+import 'package:front_end/file_system.dart';
+import 'package:front_end/src/base/uri_resolver.dart';
+import 'package:package_config/packages_file.dart' as package_config;
+
+/// Wrapper around [CompilerOptions] which exposes the options in a form useful
+/// to the front end implementation.
+///
+/// The intent is that the front end should immediately wrap any incoming
+/// [CompilerOptions] object in this class before doing further processing, and
+/// should thereafter access all options via the wrapper.  This ensures that
+/// options are interpreted in a consistent way and that data derived from
+/// options is not unnecessarily recomputed.
+class ProcessedOptions {
+  /// The raw [CompilerOptions] which this class wraps.
+  final CompilerOptions _raw;
+
+  /// The package map derived from the options, or `null` if the package map has
+  /// not been computed yet.
+  Map<String, Uri> _packages;
+
+  /// A URI resolver based on the options, or `null` if the URI resolver has not
+  /// been computed yet.
+  UriResolver _uriResolver;
+
+  /// Initializes a [ProcessedOptions] object wrapping the given [rawOptions].
+  ProcessedOptions(CompilerOptions rawOptions) : this._raw = rawOptions;
+
+  /// Determine whether to generate code for the SDK when compiling a
+  /// whole-program.
+  bool get compileSdk => _raw.compileSdk;
+
+  /// Get the [FileSystem] which should be used by the front end to access
+  /// files.
+  ///
+  /// If the client supplied bazel roots using [CompilerOptions.bazelRoots], the
+  /// returned [FileSystem] will automatically perform the appropriate mapping.
+  FileSystem get fileSystem {
+    // TODO(paulberry): support bazelRoots.
+    assert(_raw.bazelRoots.isEmpty);
+    return _raw.fileSystem;
+  }
+
+  /// Get the [UriResolver] which resolves "package:" and "dart:" URIs.
+  ///
+  /// This is an asynchronous getter since file system operations may be
+  /// required to locate/read the packages file as well as SDK metadata.
+  Future<UriResolver> getUriResolver() async {
+    if (_uriResolver == null) {
+      await _getPackages();
+      var sdkLibraries =
+          <String, Uri>{}; // TODO(paulberry): support SDK libraries
+      _uriResolver =
+          new UriResolver(_packages, sdkLibraries, fileSystem.context);
+    }
+    return _uriResolver;
+  }
+
+  /// Get the package map which maps package names to URIs.
+  ///
+  /// This is an asynchronous getter since file system operations may be
+  /// required to locate/read the packages file.
+  Future<Map<String, Uri>> _getPackages() async {
+    if (_packages == null) {
+      if (_raw.packagesFilePath == null) {
+        throw new UnimplementedError(); // TODO(paulberry): search for .packages
+      } else if (_raw.packagesFilePath.isEmpty) {
+        _packages = {};
+      } else {
+        var contents =
+            await fileSystem.entityForPath(_raw.packagesFilePath).readAsBytes();
+        var baseLocation = fileSystem.context.toUri(_raw.packagesFilePath);
+        _packages = package_config.parse(contents, baseLocation);
+      }
+    }
+    return _packages;
+  }
+}
diff --git a/pkg/front_end/lib/src/dependency_grapher_impl.dart b/pkg/front_end/lib/src/dependency_grapher_impl.dart
new file mode 100644
index 0000000..5dbe12d
--- /dev/null
+++ b/pkg/front_end/lib/src/dependency_grapher_impl.dart
@@ -0,0 +1,143 @@
+// 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 'dart:async';
+
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/error/listener.dart';
+import 'package:analyzer/src/dart/scanner/reader.dart';
+import 'package:analyzer/src/generated/parser.dart';
+import 'package:front_end/dependency_grapher.dart';
+import 'package:front_end/file_system.dart';
+import 'package:front_end/src/async_dependency_walker.dart';
+import 'package:front_end/src/base/processed_options.dart';
+import 'package:front_end/src/base/uri_resolver.dart';
+import 'package:front_end/src/scanner/scanner.dart';
+
+/// Generates a representation of the dependency graph of a program.
+///
+/// Given the Uri of one or more files, this function follows `import`,
+/// `export`, and `part` declarations to discover a graph of all files involved
+/// in the program.
+///
+/// This is intended for internal use by the front end.  Clients should use
+/// package:front_end/dependency_grapher.dart.
+Future<Graph> graphForProgram(
+    List<Uri> sources, ProcessedOptions options) async {
+  var uriResolver = await options.getUriResolver();
+  var walker = new _Walker(options.fileSystem, uriResolver, options.compileSdk);
+  var startingPoint = new _StartingPoint(walker, sources);
+  await walker.walk(startingPoint);
+  return walker.graph;
+}
+
+class _Scanner extends Scanner {
+  _Scanner(String contents) : super(new CharSequenceReader(contents)) {
+    preserveComments = false;
+  }
+
+  @override
+  void reportError(errorCode, int offset, List<Object> arguments) {
+    // TODO(paulberry): report errors.
+  }
+}
+
+class _StartingPoint extends _WalkerNode {
+  final List<Uri> sources;
+
+  _StartingPoint(_Walker walker, this.sources) : super(walker, null);
+
+  @override
+  Future<List<_WalkerNode>> computeDependencies() async =>
+      sources.map(walker.nodeForUri).toList();
+}
+
+class _Walker extends AsyncDependencyWalker<_WalkerNode> {
+  final FileSystem fileSystem;
+  final UriResolver uriResolver;
+  final _nodesByUri = <Uri, _WalkerNode>{};
+  final graph = new Graph();
+  final bool compileSdk;
+
+  _Walker(this.fileSystem, this.uriResolver, this.compileSdk);
+
+  @override
+  Future<Null> evaluate(_WalkerNode v) {
+    if (v is _StartingPoint) return new Future.value();
+    return evaluateScc([v]);
+  }
+
+  @override
+  Future<Null> evaluateScc(List<_WalkerNode> scc) {
+    var cycle = new LibraryCycleNode();
+    for (var walkerNode in scc) {
+      cycle.libraries[walkerNode.uri] = walkerNode.library;
+    }
+    graph.topologicallySortedCycles.add(cycle);
+    return new Future.value();
+  }
+
+  _WalkerNode nodeForUri(Uri referencedUri) {
+    var dependencyNode = _nodesByUri.putIfAbsent(
+        referencedUri, () => new _WalkerNode(this, referencedUri));
+    return dependencyNode;
+  }
+}
+
+class _WalkerNode extends Node<_WalkerNode> {
+  static final dartCoreUri = Uri.parse('dart:core');
+  final _Walker walker;
+  final Uri uri;
+  final LibraryNode library;
+
+  _WalkerNode(this.walker, Uri uri)
+      : uri = uri,
+        library = new LibraryNode(uri);
+
+  @override
+  Future<List<_WalkerNode>> computeDependencies() async {
+    var dependencies = <_WalkerNode>[];
+    // TODO(paulberry): add error recovery if the file can't be read.
+    var path = walker.uriResolver.resolve(uri);
+    if (path == null) {
+      // TODO(paulberry): If an error reporter was provided, report the error
+      // in the proper way and continue.
+      throw new StateError('Invalid URI: $uri');
+    }
+    var contents = await walker.fileSystem.entityForPath(path).readAsString();
+    var scanner = new _Scanner(contents);
+    var token = scanner.tokenize();
+    // TODO(paulberry): report errors.
+    var parser = new Parser(null, AnalysisErrorListener.NULL_LISTENER);
+    var unit = parser.parseDirectives(token);
+    bool coreUriFound = false;
+    void handleDependency(Uri referencedUri) {
+      _WalkerNode dependencyNode = walker.nodeForUri(referencedUri);
+      library.dependencies.add(dependencyNode.library);
+      if (referencedUri.scheme != 'dart' || walker.compileSdk) {
+        dependencies.add(dependencyNode);
+      }
+      if (referencedUri == dartCoreUri) {
+        coreUriFound = true;
+      }
+    }
+
+    for (var directive in unit.directives) {
+      if (directive is UriBasedDirective) {
+        // TODO(paulberry): when we support SDK libraries, we'll need more
+        // complex logic here to find SDK parts correctly.
+        var referencedUri = uri.resolve(directive.uri.stringValue);
+        if (directive is PartDirective) {
+          library.parts.add(referencedUri);
+        } else {
+          handleDependency(referencedUri);
+        }
+      }
+    }
+    if (!coreUriFound) {
+      handleDependency(dartCoreUri);
+    }
+    return dependencies;
+  }
+}
diff --git a/pkg/front_end/test/src/base/processed_options_test.dart b/pkg/front_end/test/src/base/processed_options_test.dart
new file mode 100644
index 0000000..ff34028
--- /dev/null
+++ b/pkg/front_end/test/src/base/processed_options_test.dart
@@ -0,0 +1,82 @@
+// 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:front_end/compiler_options.dart';
+import 'package:front_end/memory_file_system.dart';
+import 'package:front_end/src/base/processed_options.dart';
+import 'package:path/path.dart' as pathos;
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(ProcessedOptionsTest);
+  });
+}
+
+@reflectiveTest
+class ProcessedOptionsTest {
+  final fileSystem = new MemoryFileSystem(pathos.posix, '/');
+
+  test_compileSdk_false() {
+    for (var value in [false, true]) {
+      var raw = new CompilerOptions()..compileSdk = value;
+      var processed = new ProcessedOptions(raw);
+      expect(processed.compileSdk, value);
+    }
+  }
+
+  test_fileSystem_noBazelRoots() {
+    // When no bazel roots are specified, the filesystem should be passed
+    // through unmodified.
+    var raw = new CompilerOptions()..fileSystem = fileSystem;
+    var processed = new ProcessedOptions(raw);
+    expect(processed.fileSystem, same(fileSystem));
+  }
+
+  test_getUriResolver_explicitPackagesFile() async {
+    // This .packages file should be ignored.
+    fileSystem.entityForPath('/.packages').writeAsStringSync('foo:bar\n');
+    // This one should be used.
+    fileSystem
+        .entityForPath('/explicit.packages')
+        .writeAsStringSync('foo:baz\n');
+    var raw = new CompilerOptions()
+      ..fileSystem = fileSystem
+      ..packagesFilePath = '/explicit.packages';
+    var processed = new ProcessedOptions(raw);
+    var uriResolver = await processed.getUriResolver();
+    expect(uriResolver.packages, {'foo': Uri.parse('file:///baz/')});
+    expect(uriResolver.pathContext, same(fileSystem.context));
+  }
+
+  test_getUriResolver_explicitPackagesFile_withBaseLocation() async {
+    // This .packages file should be ignored.
+    fileSystem.entityForPath('/.packages').writeAsStringSync('foo:bar\n');
+    // This one should be used.
+    fileSystem
+        .entityForPath('/base/location/explicit.packages')
+        .writeAsStringSync('foo:baz\n');
+    var raw = new CompilerOptions()
+      ..fileSystem = fileSystem
+      ..packagesFilePath = '/base/location/explicit.packages';
+    var processed = new ProcessedOptions(raw);
+    var uriResolver = await processed.getUriResolver();
+    expect(
+        uriResolver.packages, {'foo': Uri.parse('file:///base/location/baz/')});
+    expect(uriResolver.pathContext, same(fileSystem.context));
+  }
+
+  test_getUriResolver_noPackages() async {
+    // .packages file should be ignored.
+    fileSystem.entityForPath('/.packages').writeAsStringSync('foo:bar\n');
+    var raw = new CompilerOptions()
+      ..fileSystem = fileSystem
+      ..packagesFilePath = '';
+    var processed = new ProcessedOptions(raw);
+    var uriResolver = await processed.getUriResolver();
+    expect(uriResolver.packages, isEmpty);
+    expect(uriResolver.pathContext, same(fileSystem.context));
+  }
+}
diff --git a/pkg/front_end/tool/perf.dart b/pkg/front_end/tool/perf.dart
index fb06d92..a69251b 100644
--- a/pkg/front_end/tool/perf.dart
+++ b/pkg/front_end/tool/perf.dart
@@ -37,95 +37,61 @@
     print('usage: perf.dart <bench-id> <entry.dart>');
     exit(1);
   }
-  var totalTimer = new Stopwatch()..start();
 
   var bench = args[0];
   var entryUri = Uri.base.resolve(args[1]);
 
   await setup(entryUri);
 
+  Set<Source> files = scanReachableFiles(entryUri);
   var handlers = {
-    'scan': () async {
-      Set<Source> files = scanReachableFiles(entryUri);
-      // TODO(sigmund): replace the warmup with instrumented snapshots.
-      for (int i = 0; i < 10; i++) scanFiles(files);
-    },
-    'parse': () async {
-      Set<Source> files = scanReachableFiles(entryUri);
-      // TODO(sigmund): replace the warmup with instrumented snapshots.
-      for (int i = 0; i < 10; i++) parseFiles(files);
-    },
+    'scan': () async => scanFiles(files),
+    'parse': () async => parseFiles(files),
     'kernel_gen_e2e': () async {
-      // TODO(sigmund): remove. This is used to compute the input size, we
-      // should extract input size from frontend instead.
-      scanReachableFiles(entryUri);
-      // TODO(sigmund): replace this warmup. Note that for very large programs,
-      // the GC pressure on the VM seems to make this worse with time (maybe we
-      // are leaking memory?). That's why we run it twice and not 10 times.
-      for (int i = 0; i < 2; i++) {
-        await generateKernel(entryUri, useSdkSummary: false);
-      }
+      await generateKernel(entryUri, useSdkSummary: false);
     },
     'kernel_gen_e2e_sum': () async {
-      // TODO(sigmund): remove. This is incorrect since it includes sizes for
-      // files that will not be loaded when using summaries. We need to extract
-      // input size from frontend instead.
-      scanReachableFiles(entryUri);
-      // TODO(sigmund): replace this warmup. Note that for very large programs,
-      // the GC pressure on the VM seems to make this worse with time (maybe we
-      // are leaking memory?). That's why we run it twice and not 10 times.
-      for (int i = 0; i < 2; i++) {
-        await generateKernel(entryUri, useSdkSummary: true, compileSdk: false);
-      }
+      await generateKernel(entryUri, useSdkSummary: true, compileSdk: false);
     },
-    'unlinked_summarize': () async {
-      Set<Source> files = scanReachableFiles(entryUri);
-      // TODO(sigmund): replace the warmup with instrumented snapshots.
-      for (int i = 0; i < 10; i++) unlinkedSummarizeFiles(files);
-    },
-    'prelinked_summarize': () async {
-      Set<Source> files = scanReachableFiles(entryUri);
-      // TODO(sigmund): replace the warmup with instrumented snapshots.
-      for (int i = 0; i < 10; i++) prelinkedSummarizeFiles(files);
-    },
-    'linked_summarize': () async {
-      Set<Source> files = scanReachableFiles(entryUri);
-      // TODO(sigmund): replace the warmup with instrumented snapshots.
-      for (int i = 0; i < 10; i++) linkedSummarizeFiles(files);
-    }
+    'unlinked_summarize': () async => summarize(files),
+    'unlinked_summarize_from_sources': () async => summarize(files),
+    'prelinked_summarize': () async => summarize(files, prelink: true),
+    'linked_summarize': () async => summarize(files, link: true),
   };
 
   var handler = handlers[bench];
   if (handler == null) {
-    // TODO(sigmund): implement the remaining benchmarks.
     print('unsupported bench-id: $bench. Please specify one of the following: '
         '${handlers.keys.join(", ")}');
     exit(1);
   }
-  await handler();
 
-  totalTimer.stop();
-  report("total", totalTimer.elapsedMicroseconds);
+  // TODO(sigmund): replace the warmup with instrumented snapshots.
+  int iterations = bench.contains('kernel_gen') ? 2 : 10;
+  for (int i = 0; i < iterations; i++) {
+    var totalTimer = new Stopwatch()..start();
+    print('== iteration $i');
+    await handler();
+    totalTimer.stop();
+    report('total', totalTimer.elapsedMicroseconds);
+  }
 }
 
 /// Cumulative time spent parsing.
 Stopwatch parseTimer = new Stopwatch();
 
-/// Cumulative time spent prelinking summaries.
-Stopwatch prelinkSummaryTimer = new Stopwatch();
+/// Cumulative time spent building unlinked summaries.
+Stopwatch unlinkedSummarizeTimer = new Stopwatch();
 
 /// Cumulative time spent scanning.
 Stopwatch scanTimer = new Stopwatch();
 
-/// Cumulative total number of chars scanned.
-int scanTotalChars = 0;
+/// Size of all sources.
+int inputSize = 0;
 
 /// Factory to load and resolve app, packages, and sdk sources.
 SourceFactory sources;
 
-/// Cumulative time spent building unlinked summaries.
-Stopwatch unlinkedSummarizeTimer = new Stopwatch();
-
 /// Add to [files] all sources reachable from [start].
 void collectSources(Source start, Set<Source> files) {
   if (!files.add(start)) return;
@@ -140,6 +106,10 @@
 
 Future<Program> generateKernel(Uri entryUri,
     {bool useSdkSummary: false, bool compileSdk: true}) async {
+  // TODO(sigmund): this is here only to compute the input size,
+  // we should extract the input size from the frontend instead.
+  scanReachableFiles(entryUri);
+
   var dartkTimer = new Stopwatch()..start();
   // TODO(sigmund): add a constructor with named args to compiler options.
   var options = new CompilerOptions()
@@ -157,15 +127,15 @@
   }
   Program program = await kernelForProgram(entryUri, options);
   dartkTimer.stop();
-  var suffix = useSdkSummary ? "_sum" : "";
-  report("kernel_gen_e2e${suffix}", dartkTimer.elapsedMicroseconds);
+  var suffix = useSdkSummary ? '_sum' : '';
+  report('kernel_gen_e2e${suffix}', dartkTimer.elapsedMicroseconds);
   return program;
 }
 
 /// Generates unlinkmed summaries for all files in [files], and returns them in
-/// an [UnlinkedSummaries] container.
-UnlinkedSummaries generateUnlinkedSummaries(Set<Source> files) {
-  var unlinkedSummaries = new UnlinkedSummaries();
+/// an [_UnlinkedSummaries] container.
+_UnlinkedSummaries generateUnlinkedSummaries(Set<Source> files) {
+  var unlinkedSummaries = new _UnlinkedSummaries();
   for (var source in files) {
     unlinkedSummaries.summariesByUri[source.uri.toString()] =
         unlinkedSummarize(source);
@@ -173,44 +143,45 @@
   return unlinkedSummaries;
 }
 
-/// Produces linked summaries for every file in [files] and reports the time
-/// spent doing so.
-void linkedSummarizeFiles(Set<Source> files) {
-  // The code below will record again how many chars are scanned and how long it
-  // takes to scan them, even though we already did so in [scanReachableFiles].
-  // Recording and reporting this twice is unnecessary, but we do so for now to
-  // validate that the results are consistent.
+/// Generates unlinked summaries for every file in [files] and, if requested via
+/// [prelink] or [link], generates the pre-linked and linked summaries as well.
+///
+/// This function also prints a report of the time spent on each action.
+void summarize(Set<Source> files, {bool prelink: false, bool link: false}) {
   scanTimer = new Stopwatch();
-  var old = scanTotalChars;
-  scanTotalChars = 0;
   parseTimer = new Stopwatch();
   unlinkedSummarizeTimer = new Stopwatch();
   var unlinkedSummaries = generateUnlinkedSummaries(files);
-  prelinkSummaryTimer = new Stopwatch();
-  Map<String, LinkedLibraryBuilder> prelinkedLibraries =
-      prelinkSummaries(files, unlinkedSummaries);
-  var linkTimer = new Stopwatch()..start();
-  LinkedLibrary getDependency(String uri) {
-    // getDependency should never be called because all dependencies are present
-    // in [prelinkedLibraries].
-    print('Warning: getDependency called for: $uri');
-    return null;
-  }
-
-  bool strong = true;
-  relink(prelinkedLibraries, getDependency, unlinkedSummaries.getUnit, strong);
-  linkTimer.stop();
-
-  if (old != scanTotalChars) print('input size changed? ${old} chars');
-  report("scan", scanTimer.elapsedMicroseconds);
-  report("parse", parseTimer.elapsedMicroseconds);
-  report('unlinked summarize', unlinkedSummarizeTimer.elapsedMicroseconds);
+  report('scan', scanTimer.elapsedMicroseconds);
+  report('parse', parseTimer.elapsedMicroseconds);
+  report('unlinked_summarize', unlinkedSummarizeTimer.elapsedMicroseconds);
   report(
-      'unlinked summarize + parse',
+      'unlinked_summarize_from_sources',
       unlinkedSummarizeTimer.elapsedMicroseconds +
-          parseTimer.elapsedMicroseconds);
-  report('prelink', prelinkSummaryTimer.elapsedMicroseconds);
-  report('link', linkTimer.elapsedMicroseconds);
+          parseTimer.elapsedMicroseconds +
+          scanTimer.elapsedMicroseconds);
+
+  if (prelink || link) {
+    var prelinkTimer = new Stopwatch()..start();
+    var prelinkedLibraries = prelinkSummaries(files, unlinkedSummaries);
+    prelinkTimer.stop();
+    report('prelinked_summarize', prelinkTimer.elapsedMicroseconds);
+
+    if (link) {
+      var linkTimer = new Stopwatch()..start();
+      LinkedLibrary getDependency(String uri) {
+        // getDependency should never be called because all dependencies are
+        // present in [prelinkedLibraries].
+        print('Warning: getDependency called for: $uri');
+        return null;
+      }
+
+      relink(prelinkedLibraries, getDependency, unlinkedSummaries.getUnit,
+          true /*strong*/);
+      linkTimer.stop();
+      report('linked_summarize', linkTimer.elapsedMicroseconds);
+    }
+  }
 }
 
 /// Uses the diet-parser to parse only directives in [source].
@@ -222,22 +193,14 @@
 
 /// Parses every file in [files] and reports the time spent doing so.
 void parseFiles(Set<Source> files) {
-  // The code below will record again how many chars are scanned and how long it
-  // takes to scan them, even though we already did so in [scanReachableFiles].
-  // Recording and reporting this twice is unnecessary, but we do so for now to
-  // validate that the results are consistent.
   scanTimer = new Stopwatch();
-  var old = scanTotalChars;
-  scanTotalChars = 0;
   parseTimer = new Stopwatch();
   for (var source in files) {
     parseFull(source);
   }
 
-  // Report size and scanning time again. See discussion above.
-  if (old != scanTotalChars) print('input size changed? ${old} chars');
-  report("scan", scanTimer.elapsedMicroseconds);
-  report("parse", parseTimer.elapsedMicroseconds);
+  report('scan', scanTimer.elapsedMicroseconds);
+  report('parse', parseTimer.elapsedMicroseconds);
 }
 
 /// Parse the full body of [source] and return it's compilation unit.
@@ -250,75 +213,42 @@
   return unit;
 }
 
-/// Produces prelinked summaries for every file in [files] and reports the time
-/// spent doing so.
-void prelinkedSummarizeFiles(Set<Source> files) {
-  // The code below will record again how many chars are scanned and how long it
-  // takes to scan them, even though we already did so in [scanReachableFiles].
-  // Recording and reporting this twice is unnecessary, but we do so for now to
-  // validate that the results are consistent.
-  scanTimer = new Stopwatch();
-  var old = scanTotalChars;
-  scanTotalChars = 0;
-  parseTimer = new Stopwatch();
-  unlinkedSummarizeTimer = new Stopwatch();
-  var unlinkedSummaries = generateUnlinkedSummaries(files);
-  prelinkSummaryTimer = new Stopwatch();
-  prelinkSummaries(files, unlinkedSummaries);
-
-  if (old != scanTotalChars) print('input size changed? ${old} chars');
-  report("scan", scanTimer.elapsedMicroseconds);
-  report("parse", parseTimer.elapsedMicroseconds);
-  report('unlinked summarize', unlinkedSummarizeTimer.elapsedMicroseconds);
-  report(
-      'unlinked summarize + parse',
-      unlinkedSummarizeTimer.elapsedMicroseconds +
-          parseTimer.elapsedMicroseconds);
-  report('prelink', prelinkSummaryTimer.elapsedMicroseconds);
-}
-
 /// Prelinks all the summaries for [files], using [unlinkedSummaries] to obtain
 /// their unlinked summaries.
 ///
 /// The return value is suitable for passing to the summary linker.
 Map<String, LinkedLibraryBuilder> prelinkSummaries(
-    Set<Source> files, UnlinkedSummaries unlinkedSummaries) {
-  prelinkSummaryTimer.start();
-  Set<String> libraryUris =
-      files.map((source) => source.uri.toString()).toSet();
+    Set<Source> files, _UnlinkedSummaries unlinkedSummaries) {
+  Set<String> libraryUris = files.map((source) => '${source.uri}').toSet();
 
   String getDeclaredVariable(String s) => null;
   var prelinkedLibraries =
       setupForLink(libraryUris, unlinkedSummaries.getUnit, getDeclaredVariable);
-  prelinkSummaryTimer.stop();
   return prelinkedLibraries;
 }
 
 /// Report that metric [name] took [time] micro-seconds to process
-/// [scanTotalChars] characters.
+/// [inputSize] characters.
 void report(String name, int time) {
   var sb = new StringBuffer();
-  sb.write('$name: $time us, ${time ~/ 1000} ms');
-  sb.write(', ${scanTotalChars * 1000 ~/ time} chars/ms');
+  var padding = ' ' * (20 - name.length);
+  sb.write('$name:$padding $time us, ${time ~/ 1000} ms');
+  var invSpeed = (time * 1000 / inputSize).toStringAsFixed(2);
+  sb.write(', $invSpeed ns/char');
   print('$sb');
 }
 
 /// Scans every file in [files] and reports the time spent doing so.
 void scanFiles(Set<Source> files) {
-  // The code below will record again how many chars are scanned and how long it
-  // takes to scan them, even though we already did so in [scanReachableFiles].
-  // Recording and reporting this twice is unnecessary, but we do so for now to
-  // validate that the results are consistent.
+  // `tokenize` records how many chars are scanned and how long it takes to scan
+  // them. As this function is called repeatedly when running as a benchmark, we
+  // make sure to clear the data and compute it again every time.
   scanTimer = new Stopwatch();
-  var old = scanTotalChars;
-  scanTotalChars = 0;
   for (var source in files) {
     tokenize(source);
   }
 
-  // Report size and scanning time again. See discussion above.
-  if (old != scanTotalChars) print('input size changed? ${old} chars');
-  report("scan", scanTimer.elapsedMicroseconds);
+  report('scan', scanTimer.elapsedMicroseconds);
 }
 
 /// Load and scans all files we need to process: files reachable from the
@@ -326,20 +256,21 @@
 Set<Source> scanReachableFiles(Uri entryUri) {
   var files = new Set<Source>();
   var loadTimer = new Stopwatch()..start();
+  scanTimer = new Stopwatch();
   collectSources(sources.forUri2(entryUri), files);
 
   var libs = [
-    "dart:async",
-    "dart:collection",
-    "dart:convert",
-    "dart:core",
-    "dart:developer",
-    "dart:_internal",
-    "dart:isolate",
-    "dart:math",
-    "dart:mirrors",
-    "dart:typed_data",
-    "dart:io"
+    'dart:async',
+    'dart:collection',
+    'dart:convert',
+    'dart:core',
+    'dart:developer',
+    'dart:_internal',
+    'dart:isolate',
+    'dart:math',
+    'dart:mirrors',
+    'dart:typed_data',
+    'dart:io'
   ];
 
   for (var lib in libs) {
@@ -348,10 +279,12 @@
 
   loadTimer.stop();
 
-  print('input size: ${scanTotalChars} chars');
+  inputSize = 0;
+  for (var s in files) inputSize += s.contents.data.length;
+  print('input size: ${inputSize} chars');
   var loadTime = loadTimer.elapsedMicroseconds - scanTimer.elapsedMicroseconds;
-  report("load", loadTime);
-  report("scan", scanTimer.elapsedMicroseconds);
+  report('load', loadTime);
+  report('scan', scanTimer.elapsedMicroseconds);
   return files;
 }
 
@@ -365,18 +298,16 @@
     new ResourceUriResolver(provider),
     new PackageMapUriResolver(provider, packageMap),
     new DartUriResolver(
-        new FolderBasedDartSdk(provider, provider.getFolder("sdk"))),
+        new FolderBasedDartSdk(provider, provider.getFolder('sdk'))),
   ]);
 }
 
 /// Scan [source] and return the first token produced by the scanner.
 Token tokenize(Source source) {
   scanTimer.start();
-  var contents = source.contents.data;
-  scanTotalChars += contents.length;
   // TODO(sigmund): is there a way to scan from a random-access-file without
   // first converting to String?
-  var scanner = new _Scanner(contents);
+  var scanner = new _Scanner(source.contents.data);
   var token = scanner.tokenize();
   scanTimer.stop();
   return token;
@@ -390,32 +321,8 @@
   return unlinkedUnit;
 }
 
-/// Produces unlinked summaries for every file in [files] and reports the time
-/// spent doing so.
-void unlinkedSummarizeFiles(Set<Source> files) {
-  // The code below will record again how many chars are scanned and how long it
-  // takes to scan them, even though we already did so in [scanReachableFiles].
-  // Recording and reporting this twice is unnecessary, but we do so for now to
-  // validate that the results are consistent.
-  scanTimer = new Stopwatch();
-  var old = scanTotalChars;
-  scanTotalChars = 0;
-  parseTimer = new Stopwatch();
-  unlinkedSummarizeTimer = new Stopwatch();
-  generateUnlinkedSummaries(files);
-
-  if (old != scanTotalChars) print('input size changed? ${old} chars');
-  report("scan", scanTimer.elapsedMicroseconds);
-  report("parse", parseTimer.elapsedMicroseconds);
-  report('unlinked summarize', unlinkedSummarizeTimer.elapsedMicroseconds);
-  report(
-      'unlinked summarize + parse',
-      unlinkedSummarizeTimer.elapsedMicroseconds +
-          parseTimer.elapsedMicroseconds);
-}
-
 /// Simple container for a mapping from URI string to an unlinked summary.
-class UnlinkedSummaries {
+class _UnlinkedSummaries {
   final summariesByUri = <String, UnlinkedUnit>{};
 
   /// Get the unlinked summary for the given URI, and report a warning if it
diff --git a/pkg/front_end/tool/perf_test.dart b/pkg/front_end/tool/perf_test.dart
index 5abc06f..66093ed 100644
--- a/pkg/front_end/tool/perf_test.dart
+++ b/pkg/front_end/tool/perf_test.dart
@@ -8,4 +8,4 @@
 
 import 'perf.dart' as m;
 
-main() => print('done ${m.scanTotalChars}');
+main() => print('done ${m.inputSize}');
diff --git a/pkg/pkg.status b/pkg/pkg.status
index 5d6b52b..e347260 100644
--- a/pkg/pkg.status
+++ b/pkg/pkg.status
@@ -296,6 +296,7 @@
 front_end/test/scanner_test: StaticWarning
 front_end/test/src/async_dependency_walker_test: StaticWarning
 front_end/test/src/base/libraries_reader_test: StaticWarning
+front_end/test/src/base/processed_options_test: StaticWarning
 front_end/test/src/base/uri_resolver_test: StaticWarning
 front_end/test/src/dependency_walker_test: StaticWarning
 front_end/tool/perf_test: StaticWarning
@@ -352,9 +353,10 @@
 lookup_map/test/version_check_test: SkipByDesign # Only meant to run in vm.
 typed_data/test/typed_buffers_test/01: Fail # Not supporting Int64List, Uint64List.
 front_end/test/memory_file_system_test: CompileTimeError # Issue 23773
+front_end/test/dependency_grapher_test: SkipByDesign # Uses dart:io
 front_end/test/physical_file_system_test: SkipByDesign # Uses dart:io
 front_end/test/src/base/libraries_reader_test: SkipByDesign # Uses dart:io
-front_end/test/dependency_grapher_test: SkipByDesign # Uses dart:io
+front_end/test/src/base/processed_options_test: SkipByDesign # Uses dart:io
 
 [ $compiler == dart2js && $fast_startup ]
 front_end/test/*: SkipByDesign # Tests written with dart:mirrors.
diff --git a/runtime/bin/BUILD.gn b/runtime/bin/BUILD.gn
index a377332..856f8e6 100644
--- a/runtime/bin/BUILD.gn
+++ b/runtime/bin/BUILD.gn
@@ -3,27 +3,7 @@
 # BSD-style license that can be found in the LICENSE file.
 
 import("gypi_contents.gni")
-
-declare_args() {
-  # Whether to fall back to built-in root certificates when they cannot be
-  # verified at the operating system level.
-  dart_use_fallback_root_certificates = false
-
-  # The BUILD.gn file that we pull from chromium as part of zlib has a
-  # dependence on //base, which we don't pull in. In a standalone build of the
-  # VM, we set this to //runtime/bin/zlib where we have a BUILD.gn file without
-  # a dependence on //base.
-  dart_zlib_path = "//third_party/zlib"
-
-  # Whether to link the standalone VM against tcmalloc. The standalone build of
-  # the VM enables this only for Linux builds.
-  dart_use_tcmalloc = false
-}
-
-# TODO(zra): Remove this when Fuchsia has a root cert cache on the filesystem.
-if (defined(is_fuchsia) && is_fuchsia) {
-  dart_use_fallback_root_certificates = true
-}
+import("../runtime_args.gni")
 
 # Generate a resources.cc file for the service isolate without Observatory.
 action("gen_resources_cc") {
@@ -590,12 +570,13 @@
              "$dart_zlib_path",
            ] + extra_deps
 
+    defines = extra_defines
+
     if (dart_use_tcmalloc) {
       deps += [ "//third_party/tcmalloc" ]
+      defines += [ "DART_USE_TCMALLOC" ]
     }
 
-    defines = extra_defines
-
     sources = [
                 "main.cc",
                 "vmservice_impl.cc",
@@ -810,6 +791,7 @@
 
   if (dart_use_tcmalloc) {
     deps += [ "//third_party/tcmalloc" ]
+    defines += [ "DART_USE_TCMALLOC" ]
   }
 
   # The VM sources are already included in libdart, so we just want to add in
diff --git a/runtime/bin/bin.gypi b/runtime/bin/bin.gypi
index 477cf08..b870838 100644
--- a/runtime/bin/bin.gypi
+++ b/runtime/bin/bin.gypi
@@ -1151,6 +1151,9 @@
           'dependencies': [
             '../third_party/tcmalloc/tcmalloc.gypi:tcmalloc',
           ],
+          'defines': [
+            'DART_USE_TCMALLOC'
+          ],
         }],
       ],
       'configurations': {
@@ -1402,6 +1405,9 @@
           'dependencies': [
             '../third_party/tcmalloc/tcmalloc.gypi:tcmalloc',
           ],
+          'defines': [
+            'DART_USE_TCMALLOC'
+          ],
         }],
       ],
       'configurations': {
diff --git a/runtime/bin/run_vm_tests_fuchsia.cc b/runtime/bin/run_vm_tests_fuchsia.cc
index 38d249a..c83a9cf 100644
--- a/runtime/bin/run_vm_tests_fuchsia.cc
+++ b/runtime/bin/run_vm_tests_fuchsia.cc
@@ -82,26 +82,6 @@
 
 // Bugs to fix, or things that are not yet implemented.
 const char* kBugs[] = {
-  // Need OS::GetCurrentThreadCPUMicros.
-  "Timeline_Dart_TimelineGetTraceOnlyDartEvents",
-  "Timeline_Dart_TimelineGetTraceWithDartEvents",
-  "Timeline_Dart_GlobalTimelineGetTrace",
-  "TimelineEventDuration",
-  "TimelineEventDurationPrintJSON",
-  "TimelineEventArguments",
-  "TimelineEventArgumentsPrintJSON",
-  "TimelineEventCallbackRecorderBasic",
-  "TimelineAnalysis_ThreadBlockCount",
-  "TimelineRingRecorderJSONOrder",
-  "TimelinePauses_BeginEnd",
-  "Timeline_Dart_TimelineGetTrace",
-  "Timeline_Dart_TimelineGetTraceGlobalOverride",
-  "Timeline_Dart_GlobalTimelineGetTrace_Threaded",
-
-  // Need VirtualMemory reservation with mmap.
-  "ArrayLengthMaxElements",
-  "Int8ListLengthMaxElements",
-
   // Assumes initial thread's stack is the same size as spawned thread stacks.
   "StackOverflowStackTraceInfo",
 };
@@ -269,7 +249,7 @@
   drain_fd(stderr_pipe, test_stderr);
 
   mx_status_t r =
-      mx_handle_wait_one(p, MX_SIGNAL_SIGNALED, MX_TIME_INFINITE, NULL);
+      mx_handle_wait_one(p, MX_PROCESS_SIGNALED, MX_TIME_INFINITE, NULL);
   RETURN_IF_ERROR(r);
 
   mx_info_process_t proc_info;
diff --git a/runtime/bin/thread.h b/runtime/bin/thread.h
index e33e7f2..5bf1f13 100644
--- a/runtime/bin/thread.h
+++ b/runtime/bin/thread.h
@@ -55,7 +55,6 @@
   static ThreadId GetCurrentThreadId();
   static intptr_t ThreadIdToIntPtr(ThreadId id);
   static bool Compare(ThreadId a, ThreadId b);
-  static void GetThreadCpuUsage(ThreadId thread_id, int64_t* cpu_usage);
 
   static void InitOnce();
 
diff --git a/runtime/bin/thread_android.cc b/runtime/bin/thread_android.cc
index cee224d..e3732fa 100644
--- a/runtime/bin/thread_android.cc
+++ b/runtime/bin/thread_android.cc
@@ -165,17 +165,6 @@
 }
 
 
-void Thread::GetThreadCpuUsage(ThreadId thread_id, int64_t* cpu_usage) {
-  ASSERT(thread_id == GetCurrentThreadId());
-  ASSERT(cpu_usage != NULL);
-  struct timespec ts;
-  int r = clock_gettime(CLOCK_THREAD_CPUTIME_ID, &ts);
-  ASSERT(r == 0);
-  *cpu_usage = (ts.tv_sec * kNanosecondsPerSecond + ts.tv_nsec) /
-               kNanosecondsPerMicrosecond;
-}
-
-
 void Thread::InitOnce() {
   // Nothing to be done.
 }
diff --git a/runtime/bin/thread_fuchsia.cc b/runtime/bin/thread_fuchsia.cc
index fa5397f..c4fb413 100644
--- a/runtime/bin/thread_fuchsia.cc
+++ b/runtime/bin/thread_fuchsia.cc
@@ -165,11 +165,6 @@
 }
 
 
-void Thread::GetThreadCpuUsage(ThreadId thread_id, int64_t* cpu_usage) {
-  UNIMPLEMENTED();
-}
-
-
 void Thread::InitOnce() {
   // Nothing to be done.
 }
diff --git a/runtime/bin/thread_linux.cc b/runtime/bin/thread_linux.cc
index 6e6971f..ed44b34 100644
--- a/runtime/bin/thread_linux.cc
+++ b/runtime/bin/thread_linux.cc
@@ -165,17 +165,6 @@
 }
 
 
-void Thread::GetThreadCpuUsage(ThreadId thread_id, int64_t* cpu_usage) {
-  ASSERT(thread_id == GetCurrentThreadId());
-  ASSERT(cpu_usage != NULL);
-  struct timespec ts;
-  int r = clock_gettime(CLOCK_THREAD_CPUTIME_ID, &ts);
-  ASSERT(r == 0);
-  *cpu_usage = (ts.tv_sec * kNanosecondsPerSecond + ts.tv_nsec) /
-               kNanosecondsPerMicrosecond;
-}
-
-
 void Thread::InitOnce() {
   // Nothing to be done.
 }
diff --git a/runtime/bin/thread_macos.cc b/runtime/bin/thread_macos.cc
index b63b0b9..dc76aaa 100644
--- a/runtime/bin/thread_macos.cc
+++ b/runtime/bin/thread_macos.cc
@@ -158,30 +158,6 @@
 }
 
 
-void Thread::GetThreadCpuUsage(ThreadId thread_id, int64_t* cpu_usage) {
-  ASSERT(thread_id == GetCurrentThreadId());
-  ASSERT(cpu_usage != NULL);
-  // TODO(johnmccutchan): Enable this after fixing issue with macos directory
-  // watcher.
-  const bool get_cpu_usage = false;
-  if (get_cpu_usage) {
-    mach_msg_type_number_t count = THREAD_BASIC_INFO_COUNT;
-    thread_basic_info_data_t info_data;
-    thread_basic_info_t info = &info_data;
-    mach_port_t thread_port = mach_thread_self();
-    kern_return_t r = thread_info(thread_port, THREAD_BASIC_INFO,
-                                  (thread_info_t)info, &count);
-    mach_port_deallocate(mach_task_self(), thread_port);
-    if (r == KERN_SUCCESS) {
-      *cpu_usage = (info->user_time.seconds * kMicrosecondsPerSecond) +
-                   info->user_time.microseconds;
-      return;
-    }
-  }
-  *cpu_usage = 0;
-}
-
-
 void Thread::InitOnce() {
   // Nothing to be done.
 }
diff --git a/runtime/bin/thread_win.cc b/runtime/bin/thread_win.cc
index b491a51..2bb0942 100644
--- a/runtime/bin/thread_win.cc
+++ b/runtime/bin/thread_win.cc
@@ -114,35 +114,6 @@
 }
 
 
-void Thread::GetThreadCpuUsage(ThreadId thread_id, int64_t* cpu_usage) {
-  static const int64_t kTimeEpoc = 116444736000000000LL;
-  static const int64_t kTimeScaler = 10;  // 100 ns to us.
-  // Although win32 uses 64-bit integers for representing timestamps,
-  // these are packed into a FILETIME structure. The FILETIME
-  // structure is just a struct representing a 64-bit integer. The
-  // TimeStamp union allows access to both a FILETIME and an integer
-  // representation of the timestamp. The Windows timestamp is in
-  // 100-nanosecond intervals since January 1, 1601.
-  union TimeStamp {
-    FILETIME ft_;
-    int64_t t_;
-  };
-  ASSERT(cpu_usage != NULL);
-  TimeStamp created;
-  TimeStamp exited;
-  TimeStamp kernel;
-  TimeStamp user;
-  HANDLE handle = OpenThread(THREAD_QUERY_INFORMATION, false, thread_id);
-  BOOL result =
-      GetThreadTimes(handle, &created.ft_, &exited.ft_, &kernel.ft_, &user.ft_);
-  CloseHandle(handle);
-  if (!result) {
-    FATAL1("GetThreadCpuUsage failed %d\n", GetLastError());
-  }
-  *cpu_usage = (user.t_ - kTimeEpoc) / kTimeScaler;
-}
-
-
 void Thread::SetThreadLocal(ThreadLocalKey key, uword value) {
   ASSERT(key != kUnsetThreadLocalKey);
   BOOL result = TlsSetValue(key, reinterpret_cast<void*>(value));
diff --git a/runtime/lib/object.cc b/runtime/lib/object.cc
index cc7614b..b67da4f 100644
--- a/runtime/lib/object.cc
+++ b/runtime/lib/object.cc
@@ -311,10 +311,8 @@
   ASSERT(!type.IsMalformed());
   ASSERT(!type.IsMalbounded());
   Error& bound_error = Error::Handle(zone);
-  if (instance.IsNull()) {
-    return instance.raw();
-  }
   const bool is_instance_of =
+      instance.IsNull() ||
       instance.IsInstanceOf(type, instantiator_type_arguments, &bound_error);
   if (FLAG_trace_type_checks) {
     const char* result_str = is_instance_of ? "true" : "false";
diff --git a/runtime/observatory/lib/src/elements/isolate_view.dart b/runtime/observatory/lib/src/elements/isolate_view.dart
index 706de4c..7e7599e 100644
--- a/runtime/observatory/lib/src/elements/isolate_view.dart
+++ b/runtime/observatory/lib/src/elements/isolate_view.dart
@@ -297,6 +297,19 @@
                         ..text = 'object store'
                     ]
                 ],
+              new DivElement()
+                ..classes = ['memberItem']
+                ..children = [
+                  new DivElement()
+                    ..classes = ['memberName']
+                    ..text = 'native memory usage high watermark'
+                    ..title = '''The maximum amount of native memory allocated
+                    by the isolate over it\'s life.''',
+                  new DivElement()
+                    ..classes = ['memberValue']
+                    ..text = Utils.formatSize(_isolate.memoryHighWatermark)
+                    ..title = '${_isolate.memoryHighWatermark}B'
+                ],
               new BRElement(),
               new DivElement()
                 ..classes = ['memberItem']
@@ -363,6 +376,11 @@
               ..classes = ['indent']
               ..text = 'kind ${t.kindString}',
             new DivElement()
+              ..classes = ['indent']
+              ..title = '${t.memoryHighWatermark}B'
+              ..text =
+              'native memory usage high watermark ${Utils.formatSize(t.memoryHighWatermark)}',
+            new DivElement()
               ..children = t.zones
                 .map((z) => new DivElement()
                 ..classes = ['indent']
diff --git a/runtime/observatory/lib/src/models/objects/isolate.dart b/runtime/observatory/lib/src/models/objects/isolate.dart
index 02d436d..8c1e367 100644
--- a/runtime/observatory/lib/src/models/objects/isolate.dart
+++ b/runtime/observatory/lib/src/models/objects/isolate.dart
@@ -54,6 +54,11 @@
   /// The list of threads associated with this isolate.
   Iterable<Thread> get threads;
 
+  /// The maximum amount of memory in bytes allocated by the isolate in all
+  /// threads at a given time. Calculated using the high watermarks of each
+  /// thread alive when a thread is unscheduled.
+  int get memoryHighWatermark;
+
   /// The number of zone handles currently held by this isolate.
   int get numZoneHandles;
 
diff --git a/runtime/observatory/lib/src/models/objects/thread.dart b/runtime/observatory/lib/src/models/objects/thread.dart
index a62353f..7bff72c 100644
--- a/runtime/observatory/lib/src/models/objects/thread.dart
+++ b/runtime/observatory/lib/src/models/objects/thread.dart
@@ -20,6 +20,10 @@
   /// The task type associated with the thread.
   ThreadKind get kind;
 
+  /// The maximum amount of memory in bytes allocated by a thread at a given
+  /// time throughout the entire life of the thread.
+  int get memoryHighWatermark;
+
   /// A list of all the zones held by the thread.
   Iterable<Zone> get zones;
 }
diff --git a/runtime/observatory/lib/src/service/object.dart b/runtime/observatory/lib/src/service/object.dart
index 9ff8200..ccc9054 100644
--- a/runtime/observatory/lib/src/service/object.dart
+++ b/runtime/observatory/lib/src/service/object.dart
@@ -1507,6 +1507,9 @@
   List<Thread> get threads => _threads;
   final List<Thread> _threads = new List<Thread>();
 
+  int get memoryHighWatermark => _memoryHighWatermark;
+  int _memoryHighWatermark;
+
   int get numZoneHandles => _numZoneHandles;
   int _numZoneHandles;
 
@@ -1638,10 +1641,12 @@
     }
 
     threads.clear();
-    if(map['threads'] != null) {
-      threads.addAll(map['threads']);
+    if(map['_threads'] != null) {
+      threads.addAll(map['_threads']);
     }
 
+    _memoryHighWatermark = int.parse(map['_memoryHighWatermark']);
+
     if (map['threads'] != null) {
       threads.addAll(map['threads']);
     }
@@ -3085,6 +3090,8 @@
   M.ThreadKind _kind;
   String get kindString => _kindString;
   String _kindString;
+  int get memoryHighWatermark => _memoryHighWatermark;
+  int _memoryHighWatermark;
   List<Zone> get zones => _zones;
   final List<Zone> _zones = new List<Zone>();
 
@@ -3122,6 +3129,9 @@
       default:
         assert(false);
     }
+
+    _memoryHighWatermark = int.parse(map['_memoryHighWatermark']);
+
     zones.clear();
     zoneList.forEach((zone) {
       int capacity = zone['capacity'];
diff --git a/runtime/observatory/tests/service/get_zone_memory_info_rpc_test.dart b/runtime/observatory/tests/service/get_zone_memory_info_rpc_test.dart
index 7d5f004..36876be 100644
--- a/runtime/observatory/tests/service/get_zone_memory_info_rpc_test.dart
+++ b/runtime/observatory/tests/service/get_zone_memory_info_rpc_test.dart
@@ -15,7 +15,7 @@
     // the correct fields needed to examine zone memory usage.
     for (Isolate isolate in vm.isolates) {
       await isolate.reload();
-
+      expect(isolate.memoryHighWatermark, isInt);
       expect(isolate.threads, isNotNull);
       List<Thread> threads = isolate.threads;
 
@@ -23,6 +23,7 @@
         expect(thread.type, equals('_Thread'));
         expect(thread.id, isNotNull);
         expect(thread.kind, isNotNull);
+        expect(thread.memoryHighWatermark, isInt);
         expect(thread.zones, isNotNull);
         List<Zone> zones = thread.zones;
 
diff --git a/runtime/observatory/tests/service/service.status b/runtime/observatory/tests/service/service.status
index 562604a..08d5bad 100644
--- a/runtime/observatory/tests/service/service.status
+++ b/runtime/observatory/tests/service/service.status
@@ -25,6 +25,9 @@
 debugger_location_second_test: Pass, Slow
 debugger_location_test: Pass, Slow
 
+# Can be slow in debug mode, as well.
+vm_restart_test: Pass, Slow
+
 # These tests are slow on simulators.
 [ $arch == simarm || $arch == simmips || $arch == simarm64 ]
 *: Pass, Slow
diff --git a/runtime/runtime_args.gni b/runtime/runtime_args.gni
new file mode 100644
index 0000000..52b2407
--- /dev/null
+++ b/runtime/runtime_args.gni
@@ -0,0 +1,24 @@
+# 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.
+
+declare_args() {
+  # Whether to fall back to built-in root certificates when they cannot be
+  # verified at the operating system level.
+  dart_use_fallback_root_certificates = false
+
+  # The BUILD.gn file that we pull from chromium as part of zlib has a
+  # dependence on //base, which we don't pull in. In a standalone build of the
+  # VM, we set this to //runtime/bin/zlib where we have a BUILD.gn file without
+  # a dependence on //base.
+  dart_zlib_path = "//third_party/zlib"
+
+  # Whether to link the standalone VM against tcmalloc. The standalone build of
+  # the VM enables this only for Linux builds.
+  dart_use_tcmalloc = false
+}
+
+# TODO(zra): Remove this when Fuchsia has a root cert cache on the filesystem.
+if (defined(is_fuchsia) && is_fuchsia) {
+  dart_use_fallback_root_certificates = true
+}
diff --git a/runtime/vm/BUILD.gn b/runtime/vm/BUILD.gn
index 1142e57..5683aee 100644
--- a/runtime/vm/BUILD.gn
+++ b/runtime/vm/BUILD.gn
@@ -5,6 +5,7 @@
 import("../../build/executable_suffix.gni")
 import("../../build/prebuilt_dart_sdk.gni")
 import("gypi_contents.gni")
+import("../runtime_args.gni")
 
 config("libdart_vm_config") {
   if (defined(is_fuchsia) && is_fuchsia) {
diff --git a/runtime/vm/aot_optimizer.cc b/runtime/vm/aot_optimizer.cc
index 93501ec..f630aae 100644
--- a/runtime/vm/aot_optimizer.cc
+++ b/runtime/vm/aot_optimizer.cc
@@ -1335,9 +1335,15 @@
     if (cls.NumTypeArguments() > 0) {
       return Bool::null();
     }
+    // As of Dart 1.5, the Null type is a subtype of (and is more specific than)
+    // any type. However, we are checking instances here and not types. The
+    // null instance is only an instance of Null, Object, and dynamic.
     const bool is_subtype =
-        cls.IsSubtypeOf(TypeArguments::Handle(Z), type_class,
-                        TypeArguments::Handle(Z), NULL, NULL, Heap::kOld);
+        cls.IsNullClass()
+            ? (type_class.IsNullClass() || type_class.IsObjectClass() ||
+               type_class.IsDynamicClass())
+            : cls.IsSubtypeOf(TypeArguments::Handle(Z), type_class,
+                              TypeArguments::Handle(Z), NULL, NULL, Heap::kOld);
     results->Add(cls.id());
     results->Add(is_subtype);
     if (prev.IsNull()) {
diff --git a/runtime/vm/ast.h b/runtime/vm/ast.h
index ef26563..ca75856 100644
--- a/runtime/vm/ast.h
+++ b/runtime/vm/ast.h
@@ -564,14 +564,18 @@
 class PrimaryNode : public AstNode {
  public:
   PrimaryNode(TokenPosition token_pos, const Object& primary)
-      : AstNode(token_pos), primary_(primary), is_deferred_reference_(false) {
+      : AstNode(token_pos), primary_(primary), prefix_(NULL) {
     ASSERT(primary_.IsNotTemporaryScopedHandle());
   }
 
   const Object& primary() const { return primary_; }
 
-  void set_is_deferred(bool value) { is_deferred_reference_ = value; }
-  bool is_deferred_reference() const { return is_deferred_reference_; }
+  void set_prefix(const LibraryPrefix* prefix) {
+    ASSERT(prefix->IsNotTemporaryScopedHandle());
+    prefix_ = prefix;
+  }
+  const LibraryPrefix* prefix() const { return prefix_; }
+  bool is_deferred_reference() const { return prefix_ != NULL; }
 
   bool IsSuper() const {
     return primary().IsString() && (primary().raw() == Symbols::Super().raw());
@@ -583,7 +587,7 @@
 
  private:
   const Object& primary_;
-  bool is_deferred_reference_;
+  const LibraryPrefix* prefix_;
 
   DISALLOW_IMPLICIT_CONSTRUCTORS(PrimaryNode);
 };
diff --git a/runtime/vm/class_finalizer.cc b/runtime/vm/class_finalizer.cc
index adf967e..f239661 100644
--- a/runtime/vm/class_finalizer.cc
+++ b/runtime/vm/class_finalizer.cc
@@ -1498,15 +1498,18 @@
       }
     }
   }
-  // Collect interfaces, super interfaces, and super classes of this class.
+  // If we check for bad overrides, collect interfaces, super interfaces, and
+  // super classes of this class.
   GrowableArray<const Class*> interfaces(zone, 4);
-  CollectInterfaces(cls, &interfaces);
-  // Include superclasses in list of interfaces and super interfaces.
-  super_class = cls.SuperClass();
-  while (!super_class.IsNull()) {
-    interfaces.Add(&Class::ZoneHandle(zone, super_class.raw()));
-    CollectInterfaces(super_class, &interfaces);
-    super_class = super_class.SuperClass();
+  if (Isolate::Current()->error_on_bad_override()) {
+    CollectInterfaces(cls, &interfaces);
+    // Include superclasses in list of interfaces and super interfaces.
+    super_class = cls.SuperClass();
+    while (!super_class.IsNull()) {
+      interfaces.Add(&Class::ZoneHandle(zone, super_class.raw()));
+      CollectInterfaces(super_class, &interfaces);
+      super_class = super_class.SuperClass();
+    }
   }
   // Resolve function signatures and check for conflicts in super classes and
   // interfaces.
@@ -1524,22 +1527,22 @@
         !function.IsGenerativeConstructor()) {
       // A constructor cannot override anything.
       for (intptr_t i = 0; i < interfaces.length(); i++) {
-        const Class* super_class = interfaces.At(i);
-        // Finalize superclass since overrides check relies on all members
-        // of the superclass to be finalized.
-        FinalizeClass(*super_class);
-        overridden_function = super_class->LookupDynamicFunction(name);
+        const Class* interface = interfaces.At(i);
+        // All interfaces should have been finalized since override checks
+        // rely on all interface members to be finalized.
+        ASSERT(interface->is_finalized());
+        overridden_function = interface->LookupDynamicFunction(name);
         if (!overridden_function.IsNull() &&
             !function.HasCompatibleParametersWith(overridden_function,
                                                   &error)) {
           const String& class_name = String::Handle(zone, cls.Name());
-          const String& super_cls_name =
-              String::Handle(zone, super_class->Name());
+          const String& interface_name =
+              String::Handle(zone, interface->Name());
           ReportErrors(error, cls, function.token_pos(),
-                       "class '%s' overrides method '%s' of super "
-                       "class '%s' with incompatible parameters",
+                       "class '%s' overrides method '%s' of super class or "
+                       "interface '%s' with incompatible parameters",
                        class_name.ToCString(), name.ToCString(),
-                       super_cls_name.ToCString());
+                       interface_name.ToCString());
         }
       }
     }
@@ -2479,17 +2482,25 @@
     cls.set_is_finalized();
     return;
   }
+  // Ensure super class is finalized.
+  const Class& super = Class::Handle(cls.SuperClass());
+  if (!super.IsNull()) {
+    FinalizeClass(super);
+  }
+  // Ensure interfaces are finalized in case we check for bad overrides.
+  if (Isolate::Current()->error_on_bad_override()) {
+    GrowableArray<const Class*> interfaces(4);
+    CollectInterfaces(cls, &interfaces);
+    for (intptr_t i = 0; i < interfaces.length(); i++) {
+      FinalizeClass(*interfaces.At(i));
+    }
+  }
   if (cls.IsMixinApplication()) {
     // Copy instance methods and fields from the mixin class.
     // This has to happen before the check whether the methods of
     // the class conflict with inherited methods.
     ApplyMixinMembers(cls);
   }
-  // Ensure super class is finalized.
-  const Class& super = Class::Handle(cls.SuperClass());
-  if (!super.IsNull()) {
-    FinalizeClass(super);
-  }
   // Mark as parsed and finalized.
   cls.Finalize();
   // Mixin app alias classes may still lack their forwarding constructor.
diff --git a/runtime/vm/dart.cc b/runtime/vm/dart.cc
index 2f9e6d7..42b6cfd 100644
--- a/runtime/vm/dart.cc
+++ b/runtime/vm/dart.cc
@@ -580,13 +580,16 @@
     StubCode::Init(I);
   }
 
-#if !defined(DART_PRECOMPILED_RUNTIME)
-  // When running precompiled, the megamorphic miss function/code comes from the
-  // snapshot.
-  if (!Snapshot::IncludesCode(Dart::snapshot_kind())) {
+#if defined(DART_PRECOMPILED_RUNTIME)
+  // AOT: The megamorphic miss function and code come from the snapshot.
+  ASSERT(I->object_store()->megamorphic_miss_code() != Code::null());
+#else
+  // JIT: The megamorphic miss function and code come from the snapshot in JIT
+  // app snapshot, otherwise create them.
+  if (I->object_store()->megamorphic_miss_code() == Code::null()) {
     MegamorphicCacheTable::InitMissHandler(I);
   }
-#endif
+#endif  // defined(DART_PRECOMPILED_RUNTIME)
 
   const Code& miss_code =
       Code::Handle(I->object_store()->megamorphic_miss_code());
diff --git a/runtime/vm/dart_api_impl_test.cc b/runtime/vm/dart_api_impl_test.cc
index 1b26eb5..6e1675a 100644
--- a/runtime/vm/dart_api_impl_test.cc
+++ b/runtime/vm/dart_api_impl_test.cc
@@ -1007,6 +1007,7 @@
 
 
 TEST_CASE(ArrayValues) {
+  EXPECT(!Dart_IsList(Dart_Null()));
   const int kArrayLength = 10;
   Dart_Handle str = NewString("test");
   EXPECT(!Dart_IsList(str));
@@ -1473,6 +1474,7 @@
 
 
 TEST_CASE(MapAccess) {
+  EXPECT(!Dart_IsMap(Dart_Null()));
   const char* kScriptChars =
       "Map testMain() {"
       "  return {"
diff --git a/runtime/vm/flow_graph_compiler_arm.cc b/runtime/vm/flow_graph_compiler_arm.cc
index 4e61306..3a565ea 100644
--- a/runtime/vm/flow_graph_compiler_arm.cc
+++ b/runtime/vm/flow_graph_compiler_arm.cc
@@ -550,7 +550,7 @@
 
 // If instanceof type test cannot be performed successfully at compile time and
 // therefore eliminated, optimize it by adding inlined tests for:
-// - NULL -> return false.
+// - NULL -> return type == Null (type is not Object or dynamic).
 // - Smi -> compile time subtype check (only if dst class is not parameterized).
 // - Class equality (only if class is not parameterized).
 // Inputs:
@@ -564,6 +564,7 @@
                                            bool negate_result,
                                            LocationSummary* locs) {
   ASSERT(type.IsFinalized() && !type.IsMalformed() && !type.IsMalbounded());
+  ASSERT(!type.IsObjectType() && !type.IsDynamicType());
 
   // Preserve instantiator type arguments (R1).
   __ Push(R1);
@@ -572,13 +573,13 @@
   // If type is instantiated and non-parameterized, we can inline code
   // checking whether the tested instance is a Smi.
   if (type.IsInstantiated()) {
-    // A null object is only an instance of Object and dynamic, which has
-    // already been checked above (if the type is instantiated). So we can
-    // return false here if the instance is null (and if the type is
-    // instantiated).
+    // A null object is only an instance of Null, Object, and dynamic.
+    // Object and dynamic have already been checked above (if the type is
+    // instantiated). So we can return false here if the instance is null,
+    // unless the type is Null (and if the type is instantiated).
     // We can only inline this null check if the type is instantiated at compile
-    // time, since an uninstantiated type at compile time could be Object or
-    // dynamic at run time.
+    // time, since an uninstantiated type at compile time could be Null, Object,
+    // or dynamic at run time.
     __ CompareObject(R0, Object::null_object());
     __ b(type.IsNullType() ? &is_instance : &is_not_instance, EQ);
   }
diff --git a/runtime/vm/flow_graph_compiler_arm64.cc b/runtime/vm/flow_graph_compiler_arm64.cc
index 85c0a76f..27430d6 100644
--- a/runtime/vm/flow_graph_compiler_arm64.cc
+++ b/runtime/vm/flow_graph_compiler_arm64.cc
@@ -543,7 +543,7 @@
 
 // If instanceof type test cannot be performed successfully at compile time and
 // therefore eliminated, optimize it by adding inlined tests for:
-// - NULL -> return false.
+// - NULL -> return type == Null (type is not Object or dynamic).
 // - Smi -> compile time subtype check (only if dst class is not parameterized).
 // - Class equality (only if class is not parameterized).
 // Inputs:
@@ -557,6 +557,7 @@
                                            bool negate_result,
                                            LocationSummary* locs) {
   ASSERT(type.IsFinalized() && !type.IsMalformed() && !type.IsMalbounded());
+  ASSERT(!type.IsObjectType() && !type.IsDynamicType());
 
   // Preserve instantiator type arguments (R1).
   __ Push(R1);
@@ -565,13 +566,13 @@
   // If type is instantiated and non-parameterized, we can inline code
   // checking whether the tested instance is a Smi.
   if (type.IsInstantiated()) {
-    // A null object is only an instance of Object and dynamic, which has
-    // already been checked above (if the type is instantiated). So we can
-    // return false here if the instance is null (and if the type is
-    // instantiated).
+    // A null object is only an instance of Null, Object, and dynamic.
+    // Object and dynamic have already been checked above (if the type is
+    // instantiated). So we can return false here if the instance is null,
+    // unless the type is Null (and if the type is instantiated).
     // We can only inline this null check if the type is instantiated at compile
-    // time, since an uninstantiated type at compile time could be Object or
-    // dynamic at run time.
+    // time, since an uninstantiated type at compile time could be Null, Object,
+    // or dynamic at run time.
     __ CompareObject(R0, Object::null_object());
     __ b(type.IsNullType() ? &is_instance : &is_not_instance, EQ);
   }
diff --git a/runtime/vm/flow_graph_compiler_ia32.cc b/runtime/vm/flow_graph_compiler_ia32.cc
index fbc891e..d679be9 100644
--- a/runtime/vm/flow_graph_compiler_ia32.cc
+++ b/runtime/vm/flow_graph_compiler_ia32.cc
@@ -554,7 +554,7 @@
 
 // If instanceof type test cannot be performed successfully at compile time and
 // therefore eliminated, optimize it by adding inlined tests for:
-// - NULL -> return false.
+// - NULL -> return type == Null (type is not Object or dynamic).
 // - Smi -> compile time subtype check (only if dst class is not parameterized).
 // - Class equality (only if class is not parameterized).
 // Inputs:
@@ -569,6 +569,7 @@
                                            bool negate_result,
                                            LocationSummary* locs) {
   ASSERT(type.IsFinalized() && !type.IsMalformedOrMalbounded());
+  ASSERT(!type.IsObjectType() && !type.IsDynamicType());
 
   const Immediate& raw_null =
       Immediate(reinterpret_cast<intptr_t>(Object::null()));
@@ -577,13 +578,13 @@
   // If type is instantiated and non-parameterized, we can inline code
   // checking whether the tested instance is a Smi.
   if (type.IsInstantiated()) {
-    // A null object is only an instance of Object and dynamic, which has
-    // already been checked above (if the type is instantiated). So we can
-    // return false here if the instance is null (and if the type is
-    // instantiated).
+    // A null object is only an instance of Null, Object, and dynamic.
+    // Object and dynamic have already been checked above (if the type is
+    // instantiated). So we can return false here if the instance is null,
+    // unless the type is Null (and if the type is instantiated).
     // We can only inline this null check if the type is instantiated at compile
-    // time, since an uninstantiated type at compile time could be Object or
-    // dynamic at run time.
+    // time, since an uninstantiated type at compile time could be Null, Object,
+    // or dynamic at run time.
     __ cmpl(EAX, raw_null);
     __ j(EQUAL, type.IsNullType() ? &is_instance : &is_not_instance);
   }
diff --git a/runtime/vm/flow_graph_compiler_mips.cc b/runtime/vm/flow_graph_compiler_mips.cc
index fddc901..5bb23c1 100644
--- a/runtime/vm/flow_graph_compiler_mips.cc
+++ b/runtime/vm/flow_graph_compiler_mips.cc
@@ -538,7 +538,7 @@
 
 // If instanceof type test cannot be performed successfully at compile time and
 // therefore eliminated, optimize it by adding inlined tests for:
-// - NULL -> return false.
+// - NULL -> return type == Null (type is not Object or dynamic).
 // - Smi -> compile time subtype check (only if dst class is not parameterized).
 // - Class equality (only if class is not parameterized).
 // Inputs:
@@ -552,6 +552,7 @@
                                            bool negate_result,
                                            LocationSummary* locs) {
   ASSERT(type.IsFinalized() && !type.IsMalformed() && !type.IsMalbounded());
+  ASSERT(!type.IsObjectType() && !type.IsDynamicType());
 
   // Preserve instantiator type arguments (A1).
   __ addiu(SP, SP, Immediate(-1 * kWordSize));
@@ -561,13 +562,13 @@
   // If type is instantiated and non-parameterized, we can inline code
   // checking whether the tested instance is a Smi.
   if (type.IsInstantiated()) {
-    // A null object is only an instance of Object and dynamic, which has
-    // already been checked above (if the type is instantiated). So we can
-    // return false here if the instance is null (and if the type is
-    // instantiated).
+    // A null object is only an instance of Null, Object, and dynamic.
+    // Object and dynamic have already been checked above (if the type is
+    // instantiated). So we can return false here if the instance is null,
+    // unless the type is Null (and if the type is instantiated).
     // We can only inline this null check if the type is instantiated at compile
-    // time, since an uninstantiated type at compile time could be Object or
-    // dynamic at run time.
+    // time, since an uninstantiated type at compile time could be Null, Object,
+    // or dynamic at run time.
     __ BranchEqual(A0, Object::null_object(),
                    type.IsNullType() ? &is_instance : &is_not_instance);
   }
diff --git a/runtime/vm/flow_graph_compiler_x64.cc b/runtime/vm/flow_graph_compiler_x64.cc
index 0944b5e..01b4c08 100644
--- a/runtime/vm/flow_graph_compiler_x64.cc
+++ b/runtime/vm/flow_graph_compiler_x64.cc
@@ -549,7 +549,7 @@
 
 // If instanceof type test cannot be performed successfully at compile time and
 // therefore eliminated, optimize it by adding inlined tests for:
-// - NULL -> return false.
+// - NULL -> return type == Null (type is not Object or dynamic).
 // - Smi -> compile time subtype check (only if dst class is not parameterized).
 // - Class equality (only if class is not parameterized).
 // Inputs:
@@ -564,19 +564,20 @@
                                            bool negate_result,
                                            LocationSummary* locs) {
   ASSERT(type.IsFinalized() && !type.IsMalformedOrMalbounded());
+  ASSERT(!type.IsObjectType() && !type.IsDynamicType());
 
   Label is_instance, is_not_instance;
   __ pushq(RDX);  // Store instantiator type arguments.
   // If type is instantiated and non-parameterized, we can inline code
   // checking whether the tested instance is a Smi.
   if (type.IsInstantiated()) {
-    // A null object is only an instance of Object and dynamic, which has
-    // already been checked above (if the type is instantiated). So we can
-    // return false here if the instance is null (and if the type is
-    // instantiated).
+    // A null object is only an instance of Null, Object, and dynamic.
+    // Object and dynamic have already been checked above (if the type is
+    // instantiated). So we can return false here if the instance is null,
+    // unless the type is Null (and if the type is instantiated).
     // We can only inline this null check if the type is instantiated at compile
-    // time, since an uninstantiated type at compile time could be Object or
-    // dynamic at run time.
+    // time, since an uninstantiated type at compile time could be Null, Object,
+    // or dynamic at run time.
     __ CompareObject(RAX, Object::null_object());
     __ j(EQUAL, type.IsNullType() ? &is_instance : &is_not_instance);
   }
diff --git a/runtime/vm/flow_graph_type_propagator.cc b/runtime/vm/flow_graph_type_propagator.cc
index 9f96d7d..928c533 100644
--- a/runtime/vm/flow_graph_type_propagator.cc
+++ b/runtime/vm/flow_graph_type_propagator.cc
@@ -604,7 +604,7 @@
   const AbstractType& compile_type = *ToAbstractType();
 
   // The compile-type of a value should never be void. The result of a void
-  // function must always be null, which wass checked to be null at the return
+  // function must always be null, which was checked to be null at the return
   // statement inside the function.
   ASSERT(!compile_type.IsVoidType());
 
@@ -612,13 +612,13 @@
     return false;
   }
 
-  // The Null type is only a subtype of Object and of dynamic.
+  // The null instance is an instance of Null, of Object, and of dynamic.
   // Functions that do not explicitly return a value, implicitly return null,
   // except generative constructors, which return the object being constructed.
   // It is therefore acceptable for void functions to return null.
   if (compile_type.IsNullType()) {
     *is_instance = is_nullable || type.IsObjectType() || type.IsDynamicType() ||
-                   type.IsVoidType();
+                   type.IsNullType() || type.IsVoidType();
     return true;
   }
 
diff --git a/runtime/vm/heap.cc b/runtime/vm/heap.cc
index da9e679..fce8cfe 100644
--- a/runtime/vm/heap.cc
+++ b/runtime/vm/heap.cc
@@ -87,14 +87,9 @@
   // memory.
   Thread* thread = Thread::Current();
   if (thread->CanCollectGarbage()) {
-    {
-      MonitorLocker ml(old_space_.tasks_lock());
-      addr = old_space_.TryAllocate(size, type);
-      while ((addr == 0) && (old_space_.tasks() > 0)) {
-        ml.WaitWithSafepointCheck(thread);
-        addr = old_space_.TryAllocate(size, type);
-      }
-    }
+    // Wait for any GC tasks that are in progress.
+    WaitForSweeperTasks(thread);
+    addr = old_space_.TryAllocate(size, type);
     if (addr != 0) {
       return addr;
     }
@@ -105,14 +100,8 @@
       return addr;
     }
     // Wait for all of the concurrent tasks to finish before giving up.
-    {
-      MonitorLocker ml(old_space_.tasks_lock());
-      addr = old_space_.TryAllocate(size, type);
-      while ((addr == 0) && (old_space_.tasks() > 0)) {
-        ml.WaitWithSafepointCheck(thread);
-        addr = old_space_.TryAllocate(size, type);
-      }
-    }
+    WaitForSweeperTasks(thread);
+    addr = old_space_.TryAllocate(size, type);
     if (addr != 0) {
       return addr;
     }
@@ -123,12 +112,7 @@
     }
     // Before throwing an out-of-memory error try a synchronous GC.
     CollectAllGarbage();
-    {
-      MonitorLocker ml(old_space_.tasks_lock());
-      while (old_space_.tasks() > 0) {
-        ml.WaitWithSafepointCheck(thread);
-      }
-    }
+    WaitForSweeperTasks(thread);
   }
   addr = old_space_.TryAllocate(size, type, PageSpace::kForceGrowth);
   if (addr != 0) {
@@ -445,17 +429,12 @@
 }
 
 
-#if defined(DEBUG)
-void Heap::WaitForSweeperTasks() {
-  Thread* thread = Thread::Current();
-  {
-    MonitorLocker ml(old_space_.tasks_lock());
-    while (old_space_.tasks() > 0) {
-      ml.WaitWithSafepointCheck(thread);
-    }
+void Heap::WaitForSweeperTasks(Thread* thread) {
+  MonitorLocker ml(old_space_.tasks_lock());
+  while (old_space_.tasks() > 0) {
+    ml.WaitWithSafepointCheck(thread);
   }
 }
-#endif
 
 
 void Heap::UpdateGlobalMaxUsed() {
diff --git a/runtime/vm/heap.h b/runtime/vm/heap.h
index 92c201c..8154987 100644
--- a/runtime/vm/heap.h
+++ b/runtime/vm/heap.h
@@ -114,9 +114,7 @@
     return old_space_.NeedsGarbageCollection();
   }
 
-#if defined(DEBUG)
-  void WaitForSweeperTasks();
-#endif
+  void WaitForSweeperTasks(Thread* thread);
 
   // Enables growth control on the page space heaps.  This should be
   // called before any user code is executed.
diff --git a/runtime/vm/isolate.cc b/runtime/vm/isolate.cc
index 622f9c1..76159c8 100644
--- a/runtime/vm/isolate.cc
+++ b/runtime/vm/isolate.cc
@@ -776,6 +776,7 @@
       single_step_(false),
       thread_registry_(new ThreadRegistry()),
       safepoint_handler_(new SafepointHandler(this)),
+      memory_high_watermark_(0),
       message_notify_callback_(NULL),
       name_(NULL),
       debugger_name_(NULL),
@@ -2108,7 +2109,8 @@
     }
   }
 
-  jsobj.AddProperty("threads", thread_registry_);
+  jsobj.AddPropertyF("_memoryHighWatermark", "%" Pu "", memory_high_watermark_);
+  jsobj.AddProperty("_threads", thread_registry_);
 }
 #endif
 
@@ -2658,6 +2660,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);
@@ -2704,6 +2708,7 @@
     // Ensure that the thread reports itself as being at a safepoint.
     thread->EnterSafepoint();
   }
+  UpdateMemoryHighWatermark();
   OSThread* os_thread = thread->os_thread();
   ASSERT(os_thread != NULL);
   os_thread->DisableThreadInterrupts();
@@ -2724,6 +2729,15 @@
 }
 
 
+void Isolate::UpdateMemoryHighWatermark() {
+  const uintptr_t thread_watermarks_total =
+      thread_registry()->ThreadHighWatermarksTotalLocked();
+  if (thread_watermarks_total > memory_high_watermark_) {
+    memory_high_watermark_ = thread_watermarks_total;
+  }
+}
+
+
 static RawInstance* DeserializeObject(Thread* thread,
                                       uint8_t* obj_data,
                                       intptr_t obj_len) {
diff --git a/runtime/vm/isolate.h b/runtime/vm/isolate.h
index 10f44f0..79abc16 100644
--- a/runtime/vm/isolate.h
+++ b/runtime/vm/isolate.h
@@ -178,7 +178,7 @@
 
   ThreadRegistry* thread_registry() const { return thread_registry_; }
   SafepointHandler* safepoint_handler() const { return safepoint_handler_; }
-
+  uintptr_t memory_high_watermark() const { return memory_high_watermark_; }
   ClassTable* class_table() { return &class_table_; }
   static intptr_t class_table_offset() {
     return OFFSET_OF(Isolate, class_table_);
@@ -691,6 +691,10 @@
                         bool is_mutator,
                         bool bypass_safepoint = false);
 
+  // Updates the maximum memory usage in bytes of all zones in all threads of
+  // the current isolate.
+  void UpdateMemoryHighWatermark();
+
   // DEPRECATED: Use Thread's methods instead. During migration, these default
   // to using the mutator thread (which must also be the current thread).
   Zone* current_zone() const {
@@ -711,6 +715,7 @@
 
   ThreadRegistry* thread_registry_;
   SafepointHandler* safepoint_handler_;
+  uintptr_t memory_high_watermark_;
   Dart_MessageNotifyCallback message_notify_callback_;
   char* name_;
   char* debugger_name_;
diff --git a/runtime/vm/jit_optimizer.cc b/runtime/vm/jit_optimizer.cc
index ff691b0..d7ef3e3 100644
--- a/runtime/vm/jit_optimizer.cc
+++ b/runtime/vm/jit_optimizer.cc
@@ -1234,9 +1234,15 @@
     if (cls.NumTypeArguments() > 0) {
       return Bool::null();
     }
+    // As of Dart 1.5, the Null type is a subtype of (and is more specific than)
+    // any type. However, we are checking instances here and not types. The
+    // null instance is only an instance of Null, Object, and dynamic.
     const bool is_subtype =
-        cls.IsSubtypeOf(TypeArguments::Handle(Z), type_class,
-                        TypeArguments::Handle(Z), NULL, NULL, Heap::kOld);
+        cls.IsNullClass()
+            ? (type_class.IsNullClass() || type_class.IsObjectClass() ||
+               type_class.IsDynamicClass())
+            : cls.IsSubtypeOf(TypeArguments::Handle(Z), type_class,
+                              TypeArguments::Handle(Z), NULL, NULL, Heap::kOld);
     results->Add(cls.id());
     results->Add(is_subtype);
     if (prev.IsNull()) {
diff --git a/runtime/vm/malloc_hooks.cc b/runtime/vm/malloc_hooks.cc
new file mode 100644
index 0000000..65edca7
--- /dev/null
+++ b/runtime/vm/malloc_hooks.cc
@@ -0,0 +1,17 @@
+// 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.
+
+#if defined(DART_USE_TCMALLOC)
+
+#include "vm/malloc_hooks.h"
+
+namespace dart {
+
+void MallocHooks::Init() {
+  // TODO(bkonyi): Implement
+}
+
+}  // namespace dart
+
+#endif  // defined(DART_USE_TCMALLOC)
diff --git a/runtime/vm/malloc_hooks.h b/runtime/vm/malloc_hooks.h
new file mode 100644
index 0000000..ae09402
--- /dev/null
+++ b/runtime/vm/malloc_hooks.h
@@ -0,0 +1,22 @@
+// 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.
+
+#ifndef RUNTIME_VM_MALLOC_HOOKS_H_
+#define RUNTIME_VM_MALLOC_HOOKS_H_
+
+#include "vm/globals.h"
+
+namespace dart {
+
+class MallocHooks {
+  static void Init();
+
+ private:
+  DISALLOW_ALLOCATION();
+  DISALLOW_IMPLICIT_CONSTRUCTORS(MallocHooks);
+};
+
+}  // namespace dart
+
+#endif  // RUNTIME_VM_MALLOC_HOOKS_H_
diff --git a/runtime/vm/malloc_hooks_unsupported.cc b/runtime/vm/malloc_hooks_unsupported.cc
new file mode 100644
index 0000000..65edca7
--- /dev/null
+++ b/runtime/vm/malloc_hooks_unsupported.cc
@@ -0,0 +1,17 @@
+// 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.
+
+#if defined(DART_USE_TCMALLOC)
+
+#include "vm/malloc_hooks.h"
+
+namespace dart {
+
+void MallocHooks::Init() {
+  // TODO(bkonyi): Implement
+}
+
+}  // namespace dart
+
+#endif  // defined(DART_USE_TCMALLOC)
diff --git a/runtime/vm/megamorphic_cache_table.cc b/runtime/vm/megamorphic_cache_table.cc
index 77d32ae..33df09a 100644
--- a/runtime/vm/megamorphic_cache_table.cc
+++ b/runtime/vm/megamorphic_cache_table.cc
@@ -76,6 +76,8 @@
   // For inclusion in Snapshot::kAppJIT.
   function.set_unoptimized_code(code);
 
+  ASSERT(isolate->object_store()->megamorphic_miss_function() ==
+         Function::null());
   isolate->object_store()->SetMegamorphicMissHandler(code, function);
 }
 
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index 7fa4c2f..2da9eb6 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -3741,19 +3741,17 @@
     if (other.IsDynamicClass()) {
       return true;
     }
+    // Check for NullType, which, as of Dart 1.5, is a subtype of (and is more
+    // specific than) any type. Note that the null instance is not handled here.
+    if (thsi.IsNullClass()) {
+      return true;
+    }
     // In the case of a subtype test, each occurrence of DynamicType in type S
     // is interpreted as the bottom type, a subtype of all types.
     // However, DynamicType is not more specific than any type.
     if (thsi.IsDynamicClass()) {
       return test_kind == Class::kIsSubtypeOf;
     }
-    // Check for NullType, which is only a subtype of ObjectType, of
-    // DynamicType, or of itself, and which is more specific than any type.
-    if (thsi.IsNullClass()) {
-      // We already checked for other.IsDynamicClass() above.
-      return (test_kind == Class::kIsMoreSpecificThan) ||
-             other.IsObjectClass() || other.IsNullClass();
-    }
     // Check for ObjectType. Any type that is not NullType or DynamicType
     // (already checked above), is more specific than ObjectType.
     if (other.IsObjectClass()) {
@@ -15855,6 +15853,12 @@
     return false;
   }
   other_class = instantiated_other.type_class();
+  if (IsNull()) {
+    ASSERT(cls.IsNullClass());
+    // As of Dart 1.5, the null instance and Null type are handled differently.
+    // We already checked for other.IsDynamicType().
+    return other_class.IsNullClass() || other_class.IsObjectClass();
+  }
   return cls.IsSubtypeOf(type_arguments, other_class, other_type_arguments,
                          bound_error, NULL, Heap::kOld);
 }
@@ -16554,7 +16558,10 @@
     }
     return false;
   }
-  if (other.IsObjectType() || other.IsDynamicType()) {
+  // Any type is a subtype of (and is more specific than) Object and dynamic.
+  // As of Dart 1.5, the Null type is a subtype of (and is more specific than)
+  // any type.
+  if (other.IsObjectType() || other.IsDynamicType() || IsNullType()) {
     return true;
   }
   Zone* zone = Thread::Current()->zone();
diff --git a/runtime/vm/os_fuchsia.cc b/runtime/vm/os_fuchsia.cc
index 1e3fc48..9c850ed 100644
--- a/runtime/vm/os_fuchsia.cc
+++ b/runtime/vm/os_fuchsia.cc
@@ -99,8 +99,7 @@
 
 
 int64_t OS::GetCurrentThreadCPUMicros() {
-  UNIMPLEMENTED();
-  return 0;
+  return mx_time_get(MX_CLOCK_THREAD) / kNanosecondsPerMicrosecond;
 }
 
 
diff --git a/runtime/vm/pages.cc b/runtime/vm/pages.cc
index 4c7d49d..1d7cb9a 100644
--- a/runtime/vm/pages.cc
+++ b/runtime/vm/pages.cc
@@ -381,9 +381,6 @@
                                      bool is_locked) {
   ASSERT(size >= kObjectAlignment);
   ASSERT(Utils::IsAligned(size, kObjectAlignment));
-#ifdef DEBUG
-  SpaceUsage usage_before = GetCurrentUsage();
-#endif
   uword result = 0;
   if (size < kAllocatablePageSize) {
     if (is_locked) {
@@ -420,14 +417,6 @@
       }
     }
   }
-#ifdef DEBUG
-  if (result != 0) {
-    // A successful allocation should increase usage_.
-    ASSERT(usage_before.used_in_words < usage_.used_in_words);
-  }
-// Note we cannot assert that a failed allocation should not change
-// used_in_words as another thread could have changed used_in_words.
-#endif
   ASSERT((result & kObjectAlignmentMask) == kOldObjectAlignmentOffset);
   return result;
 }
diff --git a/runtime/vm/parser.cc b/runtime/vm/parser.cc
index c8d2aa1..7c250ae 100644
--- a/runtime/vm/parser.cc
+++ b/runtime/vm/parser.cc
@@ -10481,7 +10481,7 @@
   ArgumentListNode* arguments = new (Z) ArgumentListNode(call_pos);
 
   String& method_name = String::Handle(Z);
-  if (prefix == NULL) {
+  if (prefix == NULL || !prefix->is_deferred_load()) {
     method_name = Library::PrivateCoreLibName(Symbols::ThrowNew()).raw();
   } else {
     arguments->Add(new (Z) LiteralNode(call_pos, *prefix));
@@ -11219,7 +11219,8 @@
 
 AstNode* Parser::ParseStaticCall(const Class& cls,
                                  const String& func_name,
-                                 TokenPosition ident_pos) {
+                                 TokenPosition ident_pos,
+                                 const LibraryPrefix* prefix) {
   TRACE_PARSER("ParseStaticCall");
   const TokenPosition call_pos = TokenPos();
   ASSERT(CurrentToken() == Token::kLPAREN);
@@ -11255,7 +11256,8 @@
     return ThrowNoSuchMethodError(ident_pos, cls, func_name, arguments,
                                   InvocationMirror::kStatic,
                                   InvocationMirror::kMethod,
-                                  NULL);  // No existing function.
+                                  NULL,  // No existing function.
+                                  prefix);
   } else if (cls.IsTopLevel() && (cls.library() == Library::CoreLibrary()) &&
              (func.name() == Symbols::Identical().raw())) {
     // This is the predefined toplevel function identical(a,b).
@@ -11392,8 +11394,15 @@
     // for a field (which may be defined in a subclass.)
     const String& name =
         String::Cast(Object::ZoneHandle(primary->primary().raw()));
-    if (current_function().is_static() ||
-        current_function().IsInFactoryScope()) {
+    if (primary->is_deferred_reference()) {
+      StaticGetterNode* getter = new (Z) StaticGetterNode(
+          primary->token_pos(),
+          NULL,  // No receiver.
+          Class::ZoneHandle(Z, library_.toplevel_class()), name);
+      getter->set_is_deferred(primary->is_deferred_reference());
+      return getter;
+    } else if (current_function().is_static() ||
+               current_function().IsInFactoryScope()) {
       StaticGetterNode* getter = new (Z)
           StaticGetterNode(primary->token_pos(),
                            NULL,  // No receiver.
@@ -11506,13 +11515,21 @@
           // For now, resolve type arguments and ignore.
           ParseTypeArguments(ClassFinalizer::kCanonicalize);
         }
-        if (left->IsPrimaryNode() &&
-            left->AsPrimaryNode()->primary().IsClass()) {
+        PrimaryNode* primary_node = left->AsPrimaryNode();
+        if ((primary_node != NULL) && primary_node->primary().IsClass()) {
           // Static method call prefixed with class name.
-          const Class& cls = Class::Cast(left->AsPrimaryNode()->primary());
-          selector = ParseStaticCall(cls, *ident, ident_pos);
+          const Class& cls = Class::Cast(primary_node->primary());
+          selector =
+              ParseStaticCall(cls, *ident, ident_pos, primary_node->prefix());
         } else {
-          selector = ParseInstanceCall(left, *ident, ident_pos, is_conditional);
+          if ((primary_node != NULL) && primary_node->is_deferred_reference()) {
+            const Class& cls = Class::Handle(library_.toplevel_class());
+            selector =
+                ParseStaticCall(cls, *ident, ident_pos, primary_node->prefix());
+          } else {
+            selector =
+                ParseInstanceCall(left, *ident, ident_pos, is_conditional);
+          }
         }
       } else {
         // Field access.
@@ -11520,11 +11537,13 @@
         bool is_deferred = false;
         if (left->IsPrimaryNode()) {
           PrimaryNode* primary_node = left->AsPrimaryNode();
+          is_deferred = primary_node->is_deferred_reference();
           if (primary_node->primary().IsClass()) {
             // If the primary node referred to a class we are loading a
             // qualified static field.
             cls ^= primary_node->primary().raw();
-            is_deferred = primary_node->is_deferred_reference();
+          } else if (is_deferred) {
+            cls = library_.toplevel_class();
           }
         }
         if (cls.IsNull()) {
@@ -11616,7 +11635,12 @@
           }
           const String& name =
               String::Cast(Object::ZoneHandle(primary_node->primary().raw()));
-          if (current_function().is_static()) {
+          if (primary_node->is_deferred_reference()) {
+            // The static call will be converted to throwing a NSM error.
+            const Class& cls = Class::Handle(library_.toplevel_class());
+            selector =
+                ParseStaticCall(cls, name, primary_pos, primary_node->prefix());
+          } else if (current_function().is_static()) {
             // The static call will be converted to throwing a NSM error.
             selector = ParseStaticCall(current_class(), name, primary_pos);
           } else {
@@ -12503,7 +12527,9 @@
     const Class& cls = Class::Cast(obj);
     PrimaryNode* primary =
         new (Z) PrimaryNode(ident_pos, Class::ZoneHandle(Z, cls.raw()));
-    primary->set_is_deferred(is_deferred);
+    if (is_deferred) {
+      primary->set_prefix(&prefix);
+    }
     return primary;
   } else if (obj.IsField()) {
     const Field& field = Field::Cast(obj);
@@ -12532,7 +12558,9 @@
     } else {
       PrimaryNode* primary =
           new (Z) PrimaryNode(ident_pos, Function::ZoneHandle(Z, func.raw()));
-      primary->set_is_deferred(is_deferred);
+      if (is_deferred) {
+        primary->set_prefix(&prefix);
+      }
       return primary;
     }
   }
@@ -13969,6 +13997,9 @@
           const String& qualified_name =
               String::ZoneHandle(Z, Symbols::FromConcatAll(T, pieces));
           primary = new (Z) PrimaryNode(qual_ident_pos, qualified_name);
+          if (prefix.is_deferred_load()) {
+            primary->AsPrimaryNode()->set_prefix(&prefix);
+          }
         }
       } else if (FLAG_load_deferred_eagerly && prefix.is_deferred_load()) {
         // primary != NULL.
diff --git a/runtime/vm/parser.h b/runtime/vm/parser.h
index 38961c8..7f11efe 100644
--- a/runtime/vm/parser.h
+++ b/runtime/vm/parser.h
@@ -805,7 +805,8 @@
                                           bool require_const);
   AstNode* ParseStaticCall(const Class& cls,
                            const String& method_name,
-                           TokenPosition ident_pos);
+                           TokenPosition ident_pos,
+                           const LibraryPrefix* prefix = NULL);
   AstNode* ParseInstanceCall(AstNode* receiver,
                              const String& method_name,
                              TokenPosition ident_pos,
diff --git a/runtime/vm/precompiler.cc b/runtime/vm/precompiler.cc
index ff691d1..0dd3b18 100644
--- a/runtime/vm/precompiler.cc
+++ b/runtime/vm/precompiler.cc
@@ -53,7 +53,7 @@
 #define Z (zone())
 
 
-DEFINE_FLAG(bool, print_unique_targets, false, "Print unique dynaic targets");
+DEFINE_FLAG(bool, print_unique_targets, false, "Print unique dynamic targets");
 DEFINE_FLAG(bool, trace_precompiler, false, "Trace precompiler.");
 DEFINE_FLAG(
     int,
@@ -274,6 +274,7 @@
     if (!table->HasValidClassAt(cid)) continue;
     if (cid == kVoidCid) continue;
     if (cid == kDynamicCid) continue;
+    if (cid == kNullCid) continue;  // Instance is not at Bottom like Null type.
     cls = table->At(cid);
     if (cls.is_abstract()) continue;
     if (cls.is_patch()) continue;
@@ -2001,7 +2002,7 @@
   // corpses. Request a full GC and wait for the sweeper tasks to finish before
   // we continue.
   I->heap()->CollectAllGarbage();
-  I->heap()->WaitForSweeperTasks();
+  I->heap()->WaitForSweeperTasks(T);
 #endif
 
   ClassTable* class_table = I->class_table();
diff --git a/runtime/vm/runtime_entry.cc b/runtime/vm/runtime_entry.cc
index b0cd46e..860f048 100644
--- a/runtime/vm/runtime_entry.cc
+++ b/runtime/vm/runtime_entry.cc
@@ -14,7 +14,7 @@
 void VerifyOnTransition() {
   Thread* thread = Thread::Current();
   TransitionGeneratedToVM transition(thread);
-  thread->isolate()->heap()->WaitForSweeperTasks();
+  thread->isolate()->heap()->WaitForSweeperTasks(thread);
   SafepointOperationScope safepoint_scope(thread);
   VerifyPointersVisitor::VerifyPointers();
   thread->isolate()->heap()->Verify();
diff --git a/runtime/vm/thread.cc b/runtime/vm/thread.cc
index e938101..620e542 100644
--- a/runtime/vm/thread.cc
+++ b/runtime/vm/thread.cc
@@ -38,6 +38,8 @@
     delete compiler_stats_;
     compiler_stats_ = NULL;
   }
+  // All zone allocated memory should be free by this point.
+  ASSERT(current_thread_memory_ == 0);
   // There should be no top api scopes at this point.
   ASSERT(api_top_scope() == NULL);
   // Delete the resusable api scope if there is one.
@@ -74,6 +76,8 @@
       os_thread_(NULL),
       thread_lock_(new Monitor()),
       zone_(NULL),
+      current_thread_memory_(0),
+      memory_high_watermark_(0),
       api_reusable_scope_(NULL),
       api_top_scope_(NULL),
       top_resource_(NULL),
@@ -213,6 +217,7 @@
   jsobj.AddPropertyF("id", "threads/%" Pd "",
                      OSThread::ThreadIdToIntPtr(os_thread()->trace_id()));
   jsobj.AddProperty("kind", TaskKindToCString(task_kind()));
+  jsobj.AddPropertyF("_memoryHighWatermark", "%" Pu "", memory_high_watermark_);
   Zone* zone = zone_;
   {
     JSONArray zone_info_array(&jsobj, "zones");
diff --git a/runtime/vm/thread.h b/runtime/vm/thread.h
index e73c44b..57a7c1f6 100644
--- a/runtime/vm/thread.h
+++ b/runtime/vm/thread.h
@@ -264,6 +264,22 @@
 
   bool ZoneIsOwnedByThread(Zone* zone) const;
 
+  void IncrementMemoryUsage(uintptr_t value) {
+    current_thread_memory_ += value;
+    if (current_thread_memory_ > memory_high_watermark_) {
+      memory_high_watermark_ = current_thread_memory_;
+    }
+  }
+
+  void DecrementMemoryUsage(uintptr_t value) {
+    ASSERT(current_thread_memory_ >= value);
+    current_thread_memory_ -= value;
+  }
+
+  uintptr_t memory_high_watermark() const { return memory_high_watermark_; }
+
+  void ResetHighWatermark() { memory_high_watermark_ = current_thread_memory_; }
+
   // The reusable api local scope for this thread.
   ApiLocalScope* api_reusable_scope() const { return api_reusable_scope_; }
   void set_api_reusable_scope(ApiLocalScope* value) {
@@ -681,6 +697,8 @@
   OSThread* os_thread_;
   Monitor* thread_lock_;
   Zone* zone_;
+  uintptr_t current_thread_memory_;
+  uintptr_t memory_high_watermark_;
   ApiLocalScope* api_reusable_scope_;
   ApiLocalScope* api_top_scope_;
   StackResource* top_resource_;
diff --git a/runtime/vm/thread_registry.cc b/runtime/vm/thread_registry.cc
index 4694cc0..c2c81a4 100644
--- a/runtime/vm/thread_registry.cc
+++ b/runtime/vm/thread_registry.cc
@@ -170,6 +170,7 @@
   return thread;
 }
 
+
 void ThreadRegistry::ReturnToFreelistLocked(Thread* thread) {
   ASSERT(thread != NULL);
   ASSERT(thread->os_thread_ == NULL);
@@ -181,4 +182,16 @@
   free_list_ = thread;
 }
 
+
+uintptr_t ThreadRegistry::ThreadHighWatermarksTotalLocked() const {
+  ASSERT(threads_lock()->IsOwnedByCurrentThread());
+  uintptr_t memory_high_watermarks_total = 0;
+  Thread* current = active_list_;
+  while (current != NULL) {
+    memory_high_watermarks_total += current->memory_high_watermark();
+    current = current->next_;
+  }
+  return memory_high_watermarks_total;
+}
+
 }  // namespace dart
diff --git a/runtime/vm/thread_registry.h b/runtime/vm/thread_registry.h
index 0742d22..e46c338 100644
--- a/runtime/vm/thread_registry.h
+++ b/runtime/vm/thread_registry.h
@@ -37,6 +37,9 @@
   void PrintJSON(JSONStream* stream) const;
 #endif
 
+  // Calculates the sum of the max memory usage in bytes of each thread.
+  uintptr_t ThreadHighWatermarksTotalLocked() const;
+
   intptr_t CountZoneHandles() const;
   intptr_t CountScopedHandles() const;
 
diff --git a/runtime/vm/thread_test.cc b/runtime/vm/thread_test.cc
index 44082bc..8002e39 100644
--- a/runtime/vm/thread_test.cc
+++ b/runtime/vm/thread_test.cc
@@ -320,12 +320,21 @@
   isolate->PrintJSON(&stream, false);
   const char* json = stream.ToCString();
 
+  Thread* current_thread = Thread::Current();
+  {
+    StackZone stack_zone(current_thread);
+    char* isolate_info_buf = OS::SCreate(current_thread->zone(),
+                                         "\"_memoryHighWatermark\":"
+                                         "\"%" Pu "\"",
+                                         isolate->memory_high_watermark());
+    EXPECT_SUBSTRING(isolate_info_buf, json);
+  }
+
   // Confirm all expected entries are in the JSON output.
   for (intptr_t i = 0; i < kTaskCount + 1; i++) {
     Thread* thread = threads[i];
     Zone* top_zone = thread->zone();
 
-    Thread* current_thread = Thread::Current();
     StackZone stack_zone(current_thread);
     Zone* current_zone = current_thread->zone();
 
@@ -348,9 +357,11 @@
                     "\"type\":\"_Thread\","
                     "\"id\":\"threads\\/%" Pd
                     "\","
-                    "\"kind\":\"%s\"",
+                    "\"kind\":\"%s\","
+                    "\"_memoryHighWatermark\":\"%" Pu "\"",
                     OSThread::ThreadIdToIntPtr(thread->os_thread()->trace_id()),
-                    Thread::TaskKindToCString(thread->task_kind()));
+                    Thread::TaskKindToCString(thread->task_kind()),
+                    thread->memory_high_watermark());
 
     EXPECT_SUBSTRING(thread_info_buf, json);
   }
diff --git a/runtime/vm/vm.gypi b/runtime/vm/vm.gypi
index a8c0e74..1371285 100644
--- a/runtime/vm/vm.gypi
+++ b/runtime/vm/vm.gypi
@@ -61,6 +61,13 @@
             ],
           },
         }],
+        # The following condition should be kept in sync with the corresponding
+        # configurations in runtime/bin/bin.gypi.
+	['OS == "linux" and asan == 0 and msan == 0 and tsan == 0', {
+          'defines': [
+            'DART_USE_TCMALLOC'
+          ],
+        }],
         ['OS=="android" and _toolset=="host"', {
           'link_settings': {
             'libraries': [
@@ -105,6 +112,13 @@
             ],
           },
         }],
+        # The following condition should be kept in sync with the corresponding
+        # configurations in runtime/bin/bin.gypi.
+        ['OS == "linux" and asan == 0 and msan == 0 and tsan == 0', {
+          'defines': [
+            'DART_USE_TCMALLOC'
+          ],
+        }],
         ['OS=="android" and _toolset=="host"', {
           'link_settings': {
             'libraries': [
@@ -149,6 +163,13 @@
             ],
           },
         }],
+        # The following condition should be kept in sync with the corresponding
+        # configurations in runtime/bin/bin.gypi.
+        ['OS == "linux" and asan == 0 and msan == 0 and tsan == 0', {
+          'defines': [
+            'DART_USE_TCMALLOC'
+          ],
+        }],
         ['OS=="android" and _toolset=="host"', {
           'link_settings': {
             'libraries': [
@@ -194,6 +215,13 @@
             ],
           },
         }],
+        # The following condition should be kept in sync with the corresponding
+        # configurations in runtime/bin/bin.gypi.
+        ['OS == "linux" and asan == 0 and msan == 0 and tsan == 0', {
+          'defines': [
+            'DART_USE_TCMALLOC'
+          ],
+        }],
         ['OS=="android" and _toolset=="host"', {
           'link_settings': {
             'libraries': [
diff --git a/runtime/vm/vm_sources.gypi b/runtime/vm/vm_sources.gypi
index 9b1d27c..e75af23 100644
--- a/runtime/vm/vm_sources.gypi
+++ b/runtime/vm/vm_sources.gypi
@@ -285,6 +285,9 @@
     'longjump.cc',
     'longjump.h',
     'longjump_test.cc',
+    'malloc_hooks.cc',
+    'malloc_hooks_unsupported.cc',
+    'malloc_hooks.h',
     'megamorphic_cache_table.cc',
     'megamorphic_cache_table.h',
     'memory_region.cc',
diff --git a/runtime/vm/zone.cc b/runtime/vm/zone.cc
index 36e9622..05e7eb7 100644
--- a/runtime/vm/zone.cc
+++ b/runtime/vm/zone.cc
@@ -43,7 +43,13 @@
 
 void Zone::Segment::DeleteSegmentList(Segment* head) {
   Segment* current = head;
+  Thread* current_thread = Thread::Current();
   while (current != NULL) {
+    if (current_thread != NULL) {
+      // TODO(bkonyi) Handle special case of segment deletion within native
+      // isolate.
+      current_thread->DecrementMemoryUsage(current->size());
+    }
     Segment* next = current->next();
 #ifdef DEBUG
     // Zap the entire current segment (including the header).
@@ -68,6 +74,11 @@
 #endif
   result->next_ = next;
   result->size_ = size;
+  if (Thread::Current() != NULL) {
+    // TODO(bkonyi) Handle special case of segment creation within native
+    // isolate.
+    Thread::Current()->IncrementMemoryUsage(size);
+  }
   return result;
 }
 
diff --git a/sdk/lib/html/dart2js/html_dart2js.dart b/sdk/lib/html/dart2js/html_dart2js.dart
index 5480b2d..112f7fb 100644
--- a/sdk/lib/html/dart2js/html_dart2js.dart
+++ b/sdk/lib/html/dart2js/html_dart2js.dart
@@ -40077,13 +40077,21 @@
   EventListener _onData;
   final bool _useCapture;
 
-  // TODO(jacobr): for full strong mode correctness we should write
-  // _onData = onData == null ? null : _wrapZone/*<Event, dynamic>*/((e) => onData(e as T))
-  // but that breaks 114 co19 tests as well as multiple html tests as it is reasonable
-  // to pass the wrong type of event object to an event listener as part of a
-  // test.
+  // TODO(leafp): It would be better to write this as
+  // _onData = onData == null ? null :
+  //   onData is _wrapZoneCallback<Event, dynamic>
+  //     ? _wrapZone/*<Event, dynamic>*/(onData)
+  //     : _wrapZone/*<Event, dynamic>*/((e) => onData(e as T))
+  // In order to support existing tests which pass the wrong type of events but
+  // use a more general listener, without causing as much slowdown for things
+  // which are typed correctly.  But this currently runs afoul of restrictions
+  // on is checks for compatibility with the VM.
   _EventStreamSubscription(this._target, this._eventType, void onData(T event),
-      this._useCapture) : _onData = _wrapZone/*<Event, dynamic>*/(onData) {
+                           this._useCapture) :
+      _onData = onData == null
+      ? null
+      : _wrapZone/*<Event, dynamic>*/((e) => (onData as dynamic)(e))
+  {
     _tryResume();
   }
 
@@ -43392,23 +43400,13 @@
   // For performance reasons avoid wrapping if we are in the root zone.
   if (Zone.current == Zone.ROOT) return callback;
   if (callback == null) return null;
-  // TODO(jacobr): we cast to _wrapZoneCallback/*<A, R>*/ to hack around missing
-  // generic method support in zones.
-  // ignore: STRONG_MODE_DOWN_CAST_COMPOSITE
-  _wrapZoneCallback/*<A, R>*/ wrapped =
-      Zone.current.bindUnaryCallback(callback, runGuarded: true);
-  return wrapped;
+  return Zone.current.bindUnaryCallback/*<R, A>*/(callback, runGuarded: true);
 }
 
 _wrapZoneBinaryCallback/*<A, B, R>*/ _wrapBinaryZone/*<A, B, R>*/(_wrapZoneBinaryCallback/*<A, B, R>*/ callback) {
   if (Zone.current == Zone.ROOT) return callback;
   if (callback == null) return null;
-  // We cast to _wrapZoneBinaryCallback/*<A, B, R>*/ to hack around missing
-  // generic method support in zones.
-  // ignore: STRONG_MODE_DOWN_CAST_COMPOSITE
-  _wrapZoneBinaryCallback/*<A, B, R>*/ wrapped =
-      Zone.current.bindBinaryCallback(callback, runGuarded: true);
-  return wrapped;
+  return Zone.current.bindBinaryCallback/*<R, A, B>*/(callback, runGuarded: true);
 }
 
 /**
diff --git a/sdk/lib/html/dartium/html_dartium.dart b/sdk/lib/html/dartium/html_dartium.dart
index 5385090..39f4dc3 100644
--- a/sdk/lib/html/dartium/html_dartium.dart
+++ b/sdk/lib/html/dartium/html_dartium.dart
@@ -44600,13 +44600,21 @@
   EventListener _onData;
   final bool _useCapture;
 
-  // TODO(jacobr): for full strong mode correctness we should write
-  // _onData = onData == null ? null : _wrapZone/*<Event, dynamic>*/((e) => onData(e as T))
-  // but that breaks 114 co19 tests as well as multiple html tests as it is reasonable
-  // to pass the wrong type of event object to an event listener as part of a
-  // test.
+  // TODO(leafp): It would be better to write this as
+  // _onData = onData == null ? null :
+  //   onData is _wrapZoneCallback<Event, dynamic>
+  //     ? _wrapZone/*<Event, dynamic>*/(onData)
+  //     : _wrapZone/*<Event, dynamic>*/((e) => onData(e as T))
+  // In order to support existing tests which pass the wrong type of events but
+  // use a more general listener, without causing as much slowdown for things
+  // which are typed correctly.  But this currently runs afoul of restrictions
+  // on is checks for compatibility with the VM.
   _EventStreamSubscription(this._target, this._eventType, void onData(T event),
-      this._useCapture) : _onData = _wrapZone/*<Event, dynamic>*/(onData) {
+                           this._useCapture) :
+      _onData = onData == null
+      ? null
+      : _wrapZone/*<Event, dynamic>*/((e) => (onData as dynamic)(e))
+  {
     _tryResume();
   }
 
@@ -47864,23 +47872,13 @@
   // For performance reasons avoid wrapping if we are in the root zone.
   if (Zone.current == Zone.ROOT) return callback;
   if (callback == null) return null;
-  // TODO(jacobr): we cast to _wrapZoneCallback/*<A, R>*/ to hack around missing
-  // generic method support in zones.
-  // ignore: STRONG_MODE_DOWN_CAST_COMPOSITE
-  _wrapZoneCallback/*<A, R>*/ wrapped =
-      Zone.current.bindUnaryCallback(callback, runGuarded: true);
-  return wrapped;
+  return Zone.current.bindUnaryCallback/*<R, A>*/(callback, runGuarded: true);
 }
 
 _wrapZoneBinaryCallback/*<A, B, R>*/ _wrapBinaryZone/*<A, B, R>*/(_wrapZoneBinaryCallback/*<A, B, R>*/ callback) {
   if (Zone.current == Zone.ROOT) return callback;
   if (callback == null) return null;
-  // We cast to _wrapZoneBinaryCallback/*<A, B, R>*/ to hack around missing
-  // generic method support in zones.
-  // ignore: STRONG_MODE_DOWN_CAST_COMPOSITE
-  _wrapZoneBinaryCallback/*<A, B, R>*/ wrapped =
-      Zone.current.bindBinaryCallback(callback, runGuarded: true);
-  return wrapped;
+  return Zone.current.bindBinaryCallback/*<R, A, B>*/(callback, runGuarded: true);
 }
 
 /**
diff --git a/sdk/lib/js/dart2js/js_dart2js.dart b/sdk/lib/js/dart2js/js_dart2js.dart
index b08f7ac..fd612c0 100644
--- a/sdk/lib/js/dart2js/js_dart2js.dart
+++ b/sdk/lib/js/dart2js/js_dart2js.dart
@@ -629,7 +629,7 @@
   }
 }
 
-JsObject _wrapToDart(o) {
+Object _wrapToDart(o) {
   if (JS('bool', 'typeof # == "function"', o)) {
     return _getDartProxy(
         o, DART_CLOSURE_PROPERTY_NAME, (o) => new JsFunction._fromJs(o));
diff --git a/tests/co19/co19-kernel.status b/tests/co19/co19-kernel.status
index bf9af78..f51c40d 100644
--- a/tests/co19/co19-kernel.status
+++ b/tests/co19/co19-kernel.status
@@ -26,14 +26,6 @@
 Language/Classes/Constructors/Generative_Constructors/formal_parameter_t06: DartkCrash
 Language/Classes/Constructors/Generative_Constructors/initializing_this_t02: DartkCrash
 Language/Classes/Getters/static_getter_t02: DartkCompileTimeError
-Language/Classes/Setters/name_t08: DartkCompileTimeError
-Language/Classes/Setters/name_t09: DartkCompileTimeError
-Language/Classes/Setters/name_t10: DartkCompileTimeError
-Language/Classes/Setters/name_t11: DartkCompileTimeError
-Language/Classes/Setters/name_t12: DartkCompileTimeError
-Language/Classes/Setters/name_t13: DartkCompileTimeError
-Language/Classes/Setters/name_t14: DartkCompileTimeError
-Language/Classes/Setters/name_t15: DartkCompileTimeError
 Language/Enums/syntax_t08: MissingCompileTimeError
 Language/Enums/syntax_t09: MissingCompileTimeError
 Language/Expressions/Function_Invocation/Unqualified_Invocation/instance_context_invocation_t03: MissingCompileTimeError
@@ -52,134 +44,6 @@
 Language/Expressions/Identifier_Reference/built_in_not_dynamic_t30: MissingCompileTimeError
 Language/Expressions/Identifier_Reference/built_in_not_dynamic_t31: MissingCompileTimeError
 Language/Expressions/Identifier_Reference/built_in_not_dynamic_t32: MissingCompileTimeError
-Language/Expressions/Property_Extraction/Anonymous_Constructor_Closurization/identical_t01: DartkCompileTimeError
-Language/Expressions/Property_Extraction/Anonymous_Constructor_Closurization/identical_t02: DartkCompileTimeError
-Language/Expressions/Property_Extraction/Anonymous_Constructor_Closurization/identical_t03: DartkCompileTimeError
-Language/Expressions/Property_Extraction/Anonymous_Constructor_Closurization/named_parameters_t01: DartkCompileTimeError
-Language/Expressions/Property_Extraction/Anonymous_Constructor_Closurization/positional_parameters_t01: DartkCompileTimeError
-Language/Expressions/Property_Extraction/Anonymous_Constructor_Extraction/closurization_t01: DartkCompileTimeError
-Language/Expressions/Property_Extraction/Anonymous_Constructor_Extraction/closurization_t02: DartkCompileTimeError
-Language/Expressions/Property_Extraction/Anonymous_Constructor_Extraction/closurization_t03: DartkCompileTimeError
-Language/Expressions/Property_Extraction/Anonymous_Constructor_Extraction/deferred_type_t01: DartkCompileTimeError
-Language/Expressions/Property_Extraction/Anonymous_Constructor_Extraction/malbounded_type_t01: DartkCompileTimeError
-Language/Expressions/Property_Extraction/Anonymous_Constructor_Extraction/malbounded_type_t02: DartkCompileTimeError
-Language/Expressions/Property_Extraction/Anonymous_Constructor_Extraction/malformed_type_t01: DartkCompileTimeError
-Language/Expressions/Property_Extraction/Anonymous_Constructor_Extraction/malformed_type_t02: DartkCompileTimeError
-Language/Expressions/Property_Extraction/Anonymous_Constructor_Extraction/no_such_method_t01: DartkCompileTimeError
-Language/Expressions/Property_Extraction/Anonymous_Constructor_Extraction/no_such_method_t02: DartkCompileTimeError
-Language/Expressions/Property_Extraction/Anonymous_Constructor_Extraction/not_class_t01: DartkCompileTimeError
-Language/Expressions/Property_Extraction/Anonymous_Constructor_Extraction/not_class_t02: DartkCompileTimeError
-Language/Expressions/Property_Extraction/Anonymous_Constructor_Extraction/not_class_t03: DartkCompileTimeError
-Language/Expressions/Property_Extraction/Anonymous_Constructor_Extraction/static_type_t01: DartkCompileTimeError
-Language/Expressions/Property_Extraction/Anonymous_Constructor_Extraction/static_type_t02: DartkCompileTimeError
-Language/Expressions/Property_Extraction/Anonymous_Constructor_Extraction/static_type_t03: DartkCompileTimeError
-Language/Expressions/Property_Extraction/General_Closurization/expression_evaluation_t01: DartkCompileTimeError
-Language/Expressions/Property_Extraction/General_Closurization/expression_evaluation_t02: DartkCompileTimeError
-Language/Expressions/Property_Extraction/General_Closurization/expression_evaluation_t03: DartkCompileTimeError
-Language/Expressions/Property_Extraction/General_Closurization/getter_lookup_t01: DartkCompileTimeError
-Language/Expressions/Property_Extraction/General_Closurization/getter_lookup_t02: DartkCompileTimeError
-Language/Expressions/Property_Extraction/General_Closurization/getter_lookup_t03: DartkCompileTimeError
-Language/Expressions/Property_Extraction/General_Closurization/getter_lookup_t04: DartkCompileTimeError
-Language/Expressions/Property_Extraction/General_Closurization/getter_lookup_t05: DartkCompileTimeError
-Language/Expressions/Property_Extraction/General_Closurization/getter_lookup_t06: DartkCompileTimeError
-Language/Expressions/Property_Extraction/General_Closurization/getter_lookup_t07: DartkCompileTimeError
-Language/Expressions/Property_Extraction/General_Closurization/getter_lookup_t08: DartkCompileTimeError
-Language/Expressions/Property_Extraction/General_Closurization/getter_lookup_t09: DartkCompileTimeError
-Language/Expressions/Property_Extraction/General_Closurization/method_lookup_t01: DartkCompileTimeError
-Language/Expressions/Property_Extraction/General_Closurization/method_lookup_t02: DartkCompileTimeError
-Language/Expressions/Property_Extraction/General_Closurization/method_lookup_t03: DartkCompileTimeError
-Language/Expressions/Property_Extraction/General_Closurization/method_lookup_t04: DartkCompileTimeError
-Language/Expressions/Property_Extraction/General_Closurization/method_lookup_t05: DartkCompileTimeError
-Language/Expressions/Property_Extraction/General_Closurization/method_lookup_t06: DartkCompileTimeError
-Language/Expressions/Property_Extraction/General_Closurization/method_lookup_t07: DartkCompileTimeError
-Language/Expressions/Property_Extraction/General_Closurization/no_accessible_member_t01: DartkCompileTimeError
-Language/Expressions/Property_Extraction/General_Closurization/no_accessible_member_t02: DartkCompileTimeError
-Language/Expressions/Property_Extraction/General_Closurization/no_accessible_member_t03: DartkCompileTimeError
-Language/Expressions/Property_Extraction/General_Closurization/no_accessible_member_t04: DartkCompileTimeError
-Language/Expressions/Property_Extraction/General_Closurization/no_accessible_member_t05: DartkCompileTimeError
-Language/Expressions/Property_Extraction/General_Closurization/no_accessible_member_t06: DartkCompileTimeError
-Language/Expressions/Property_Extraction/General_Closurization/no_accessible_member_t07: DartkCompileTimeError
-Language/Expressions/Property_Extraction/General_Closurization/no_accessible_member_t08: DartkCompileTimeError
-Language/Expressions/Property_Extraction/General_Closurization/setter_lookup_t01: DartkCompileTimeError
-Language/Expressions/Property_Extraction/General_Closurization/setter_lookup_t02: DartkCompileTimeError
-Language/Expressions/Property_Extraction/General_Closurization/setter_lookup_t03: DartkCompileTimeError
-Language/Expressions/Property_Extraction/General_Closurization/setter_lookup_t04: DartkCompileTimeError
-Language/Expressions/Property_Extraction/General_Closurization/setter_lookup_t05: DartkCompileTimeError
-Language/Expressions/Property_Extraction/General_Closurization/setter_lookup_t06: DartkCompileTimeError
-Language/Expressions/Property_Extraction/General_Closurization/setter_lookup_t07: DartkCompileTimeError
-Language/Expressions/Property_Extraction/General_Closurization/setter_lookup_t08: DartkCompileTimeError
-Language/Expressions/Property_Extraction/General_Closurization/setter_lookup_t09: DartkCompileTimeError
-Language/Expressions/Property_Extraction/General_Closurization/static_type_t01: DartkCompileTimeError
-Language/Expressions/Property_Extraction/General_Closurization/static_type_t02: DartkCompileTimeError
-Language/Expressions/Property_Extraction/General_Closurization/static_type_t03: DartkCompileTimeError
-Language/Expressions/Property_Extraction/General_Closurization/static_type_t04: DartkCompileTimeError
-Language/Expressions/Property_Extraction/General_Closurization/static_type_t05: DartkCompileTimeError
-Language/Expressions/Property_Extraction/General_Closurization/static_type_t06: DartkCompileTimeError
-Language/Expressions/Property_Extraction/General_Closurization/static_type_t07: DartkCompileTimeError
-Language/Expressions/Property_Extraction/Getter_Access_and_Method_Extraction/expression_evaluation_t07: DartkCompileTimeError
-Language/Expressions/Property_Extraction/Named_Constructor_Closurization/identical_t01: DartkCompileTimeError
-Language/Expressions/Property_Extraction/Named_Constructor_Closurization/identical_t02: DartkCompileTimeError
-Language/Expressions/Property_Extraction/Named_Constructor_Closurization/named_parameters_t01: DartkCompileTimeError
-Language/Expressions/Property_Extraction/Named_Constructor_Closurization/positional_parameters_t01: DartkCompileTimeError
-Language/Expressions/Property_Extraction/Named_Constructor_Extraction/closurization_t01: DartkCompileTimeError
-Language/Expressions/Property_Extraction/Named_Constructor_Extraction/closurization_t02: DartkCompileTimeError
-Language/Expressions/Property_Extraction/Named_Constructor_Extraction/deferred_type_t01: DartkCompileTimeError
-Language/Expressions/Property_Extraction/Named_Constructor_Extraction/malbounded_type_t01: DartkCompileTimeError
-Language/Expressions/Property_Extraction/Named_Constructor_Extraction/malbounded_type_t02: DartkCompileTimeError
-Language/Expressions/Property_Extraction/Named_Constructor_Extraction/malformed_type_t01: DartkCompileTimeError
-Language/Expressions/Property_Extraction/Named_Constructor_Extraction/malformed_type_t02: DartkCompileTimeError
-Language/Expressions/Property_Extraction/Named_Constructor_Extraction/no_such_method_t01: DartkCompileTimeError
-Language/Expressions/Property_Extraction/Named_Constructor_Extraction/no_such_method_t02: DartkCompileTimeError
-Language/Expressions/Property_Extraction/Named_Constructor_Extraction/not_class_t01: DartkCompileTimeError
-Language/Expressions/Property_Extraction/Named_Constructor_Extraction/not_class_t02: DartkCompileTimeError
-Language/Expressions/Property_Extraction/Named_Constructor_Extraction/not_class_t03: DartkCompileTimeError
-Language/Expressions/Property_Extraction/Named_Constructor_Extraction/static_type_t01: DartkCompileTimeError
-Language/Expressions/Property_Extraction/Named_Constructor_Extraction/static_type_t02: DartkCompileTimeError
-Language/Expressions/Property_Extraction/Named_Constructor_Extraction/static_type_t03: DartkCompileTimeError
-Language/Expressions/Property_Extraction/Named_Constructor_Extraction/static_type_t04: DartkCompileTimeError
-Language/Expressions/Property_Extraction/Ordinary_Member_Closurization/getter_closurization_t01: DartkCompileTimeError
-Language/Expressions/Property_Extraction/Ordinary_Member_Closurization/getter_closurization_t02: DartkCompileTimeError
-Language/Expressions/Property_Extraction/Ordinary_Member_Closurization/getter_closurization_t03: DartkCompileTimeError
-Language/Expressions/Property_Extraction/Ordinary_Member_Closurization/getter_closurization_t04: DartkCompileTimeError
-Language/Expressions/Property_Extraction/Ordinary_Member_Closurization/getter_closurization_t05: DartkCompileTimeError
-Language/Expressions/Property_Extraction/Ordinary_Member_Closurization/getter_closurization_t06: DartkCompileTimeError
-Language/Expressions/Property_Extraction/Ordinary_Member_Closurization/getter_closurization_t07: DartkCompileTimeError
-Language/Expressions/Property_Extraction/Ordinary_Member_Closurization/getter_closurization_t08: DartkCompileTimeError
-Language/Expressions/Property_Extraction/Ordinary_Member_Closurization/method_closurization_named_params_t01: DartkCompileTimeError
-Language/Expressions/Property_Extraction/Ordinary_Member_Closurization/method_closurization_named_params_t02: DartkCompileTimeError
-Language/Expressions/Property_Extraction/Ordinary_Member_Closurization/method_closurization_positional_params_t01: DartkCompileTimeError
-Language/Expressions/Property_Extraction/Ordinary_Member_Closurization/method_closurization_positional_params_t02: DartkCompileTimeError
-Language/Expressions/Property_Extraction/Ordinary_Member_Closurization/method_identical_t01: DartkCompileTimeError
-Language/Expressions/Property_Extraction/Ordinary_Member_Closurization/method_identical_t02: DartkCompileTimeError
-Language/Expressions/Property_Extraction/Ordinary_Member_Closurization/method_identical_t03: DartkCompileTimeError
-Language/Expressions/Property_Extraction/Ordinary_Member_Closurization/operator_closurization_list_access_t01: DartkCompileTimeError
-Language/Expressions/Property_Extraction/Ordinary_Member_Closurization/operator_closurization_list_assignment_t01: DartkCompileTimeError
-Language/Expressions/Property_Extraction/Ordinary_Member_Closurization/operator_closurization_t01: DartkCompileTimeError
-Language/Expressions/Property_Extraction/Ordinary_Member_Closurization/operator_closurization_t02: DartkCompileTimeError
-Language/Expressions/Property_Extraction/Ordinary_Member_Closurization/operator_closurization_t03: DartkCompileTimeError
-Language/Expressions/Property_Extraction/Ordinary_Member_Closurization/operator_closurization_t04: DartkCompileTimeError
-Language/Expressions/Property_Extraction/Ordinary_Member_Closurization/operator_closurization_t05: DartkCompileTimeError
-Language/Expressions/Property_Extraction/Ordinary_Member_Closurization/operator_closurization_t06: DartkCompileTimeError
-Language/Expressions/Property_Extraction/Ordinary_Member_Closurization/operator_closurization_t07: DartkCompileTimeError
-Language/Expressions/Property_Extraction/Ordinary_Member_Closurization/operator_closurization_t08: DartkCompileTimeError
-Language/Expressions/Property_Extraction/Ordinary_Member_Closurization/operator_closurization_t09: DartkCompileTimeError
-Language/Expressions/Property_Extraction/Ordinary_Member_Closurization/operator_closurization_t10: DartkCompileTimeError
-Language/Expressions/Property_Extraction/Ordinary_Member_Closurization/operator_closurization_t11: DartkCompileTimeError
-Language/Expressions/Property_Extraction/Ordinary_Member_Closurization/operator_closurization_t12: DartkCompileTimeError
-Language/Expressions/Property_Extraction/Ordinary_Member_Closurization/operator_closurization_t13: DartkCompileTimeError
-Language/Expressions/Property_Extraction/Ordinary_Member_Closurization/operator_closurization_t14: DartkCompileTimeError
-Language/Expressions/Property_Extraction/Ordinary_Member_Closurization/operator_closurization_t15: DartkCompileTimeError
-Language/Expressions/Property_Extraction/Ordinary_Member_Closurization/operator_closurization_t16: DartkCompileTimeError
-Language/Expressions/Property_Extraction/Ordinary_Member_Closurization/operator_closurization_t17: DartkCompileTimeError
-Language/Expressions/Property_Extraction/Ordinary_Member_Closurization/operator_closurization_unary_bitwise_t01: DartkCompileTimeError
-Language/Expressions/Property_Extraction/Ordinary_Member_Closurization/setter_closurization_t01: DartkCompileTimeError
-Language/Expressions/Property_Extraction/Ordinary_Member_Closurization/setter_closurization_t02: DartkCompileTimeError
-Language/Expressions/Property_Extraction/Ordinary_Member_Closurization/setter_closurization_t03: DartkCompileTimeError
-Language/Expressions/Property_Extraction/Ordinary_Member_Closurization/setter_closurization_t04: DartkCompileTimeError
-Language/Expressions/Property_Extraction/Ordinary_Member_Closurization/setter_closurization_t05: DartkCompileTimeError
-Language/Expressions/Property_Extraction/Ordinary_Member_Closurization/setter_closurization_t06: DartkCompileTimeError
-Language/Expressions/Property_Extraction/Ordinary_Member_Closurization/setter_closurization_t07: DartkCompileTimeError
-Language/Expressions/Property_Extraction/Ordinary_Member_Closurization/setter_closurization_t08: DartkCompileTimeError
 Language/Interfaces/Superinterfaces/Inheritance_and_Overriding/same_name_method_and_getter_t01: DartkCompileTimeError
 Language/Interfaces/Superinterfaces/Inheritance_and_Overriding/same_name_method_and_getter_t02: DartkCompileTimeError
 Language/Libraries_and_Scripts/Exports/syntax_t01: MissingCompileTimeError
@@ -342,8 +206,7 @@
 LibTest/core/StringBuffer/write_A01_t02: RuntimeError
 Language/Expressions/Constants/exception_t01: Crash
 Language/Expressions/Constants/exception_t02: Crash
-Language/Expressions/Null/instance_of_class_null_t01: Crash
 
 # dartk: precompilation failures (debug)
 [ $compiler == dartkp && $runtime == dart_precompiled && $mode == debug ]
-Language/Libraries_and_Scripts/Scripts/top_level_main_t05: Crash  # !main_obj.IsNull()
\ No newline at end of file
+Language/Libraries_and_Scripts/Scripts/top_level_main_t05: Crash  # !main_obj.IsNull()
diff --git a/tests/co19/co19-runtime.status b/tests/co19/co19-runtime.status
index 9c4faf6..b4e205c 100644
--- a/tests/co19/co19-runtime.status
+++ b/tests/co19/co19-runtime.status
@@ -189,6 +189,9 @@
 [ ($runtime == vm || $runtime == dart_precompiled ) && $mode == debug ]
 LibTest/core/List/List_class_A01_t02: Pass, Slow
 LibTest/isolate/Isolate/spawn_A04_t01: Pass, Fail  # Issue 28269
+Language/Types/Interface_Types/subtype_t28: Pass, Slow
+Language/Types/Interface_Types/subtype_t27: Pass, Slow
+LibTest/collection/ListMixin/ListMixin_class_A01_t02: Pass, Slow
 
 [ ($runtime == dart_precompiled || $runtime == dart_app) && $mode == debug ]
 Language/Libraries_and_Scripts/Imports/deferred_import_t02: Crash # Issue 27201
@@ -286,7 +289,7 @@
 Language/Expressions/Property_Extraction/General_Super_Property_Extraction: CompileTimeError # Issue 26287
 Language/Expressions/Property_Extraction/Super_Closurization: CompileTimeError # Issue 26287
 
-[ $noopt || $compiler == precompiler || $mode == product ]
+[ $noopt || $runtime == dart_precompiled || $mode == product ]
 Language/Metadata/*: SkipByDesign # Uses dart:mirrors
 Language/Expressions/Null/instance_of_class_null_t01: Skip # Uses dart:mirrors
 
diff --git a/tests/compiler/dart2js/categories_test.dart b/tests/compiler/dart2js/categories_test.dart
index 677d1a8..48fef4c 100644
--- a/tests/compiler/dart2js/categories_test.dart
+++ b/tests/compiler/dart2js/categories_test.dart
@@ -25,7 +25,5 @@
     await runTest("import 'dart:html'; main() {}", "Server", 1);
     await runTest("import 'dart:io'; main() {}", "Client", 1);
     await runTest("import 'dart:io'; main() {}", "Server", 0);
-    await runTest("import 'dart:_internal'; main() {}", "Client", 1);
-    await runTest("import 'dart:_internal'; main() {}", "Server", 1);
   });
 }
diff --git a/tests/compiler/dart2js/kernel/constructors_test.dart b/tests/compiler/dart2js/kernel/constructors_test.dart
index ba38190..2664910 100644
--- a/tests/compiler/dart2js/kernel/constructors_test.dart
+++ b/tests/compiler/dart2js/kernel/constructors_test.dart
@@ -46,6 +46,27 @@
 ''';
     return check(code, lookup: defaultConstructorFor('Foo'));
   });
+
+  // TODO(efortuna): Kernel needs to have some additional constructor
+  // implementaion work before this is legitimately equivalent code to the
+  // original AST.
+/*  test('initialized field and constructor', () {
+    String code = '''
+import 'dart:_foreign_helper' show JS, JS_EMBEDDED_GLOBAL;
+import 'package:expect/expect.dart';
+
+
+class Foo {
+  final value = JS('bool', '#()', JS_EMBEDDED_GLOBAL('', 'foo'));
+  Foo() {
+    print('hello world');
+  }
+}
+
+main() => new Foo();
+''';
+    return check(code, lookup: defaultConstructorFor('Foo'));
+  });*/
 }
 
 defaultConstructorFor(String className) => (Compiler compiler) {
diff --git a/tests/compiler/dart2js/modulo_remainder_test.dart b/tests/compiler/dart2js/modulo_remainder_test.dart
new file mode 100644
index 0000000..a391a34
--- /dev/null
+++ b/tests/compiler/dart2js/modulo_remainder_test.dart
@@ -0,0 +1,100 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+import 'package:expect/expect.dart';
+import 'package:async_helper/async_helper.dart';
+import 'compiler_helper.dart';
+
+const String MOD1 = r"""
+foo(param) {
+  var a = param ? 0xFFFFFFFF : 1;
+  return a % 2;
+  // present: ' % 2'
+  // absent: '$mod'
+}
+""";
+
+const String MOD2 = r"""
+foo(param) {
+  var a = param ? 0xFFFFFFFF : -0.0;
+  return a % 2;
+  // Cannot optimize due to potential -0.
+  // present: '$mod'
+  // absent: ' % 2'
+}
+""";
+
+const String MOD3 = r"""
+foo(param) {
+  var a = param ? 0xFFFFFFFF : -0.0;
+  return (a + 1) % 2;
+  // 'a + 1' cannot be -0.0, so we can optimize.
+  // present: ' % 2'
+  // absent: '$mod'
+}
+""";
+
+const String REM1 = r"""
+foo(param) {
+  var a = param ? 0xFFFFFFFF : 1;
+  return a.remainder(2);
+  // Above can be compiled to '%'.
+  // present: ' % 2'
+  // absent: 'remainder'
+}
+""";
+
+const String REM2 = r"""
+foo(param) {
+  var a = param ? 123.4 : -1;
+  return a.remainder(3);
+  // Above can be compiled to '%'.
+  // present: ' % 3'
+  // absent: 'remainder'
+}
+""";
+
+const String REM3 = r"""
+foo(param) {
+  var a = param ? 123 : null;
+  return 100.remainder(a);
+  // No specialization for possibly null inputs.
+  // present: 'remainder'
+  // absent: '%'
+}
+""";
+
+main() {
+  RegExp directivePattern = new RegExp(
+      //      \1                    \2        \3
+      r'''// *(present|absent): (?:"([^"]*)"|'([^'']*)')''',
+      multiLine: true);
+
+  Future check(String test) {
+    return compile(test, entry: 'foo', check: (String generated) {
+      for (Match match in directivePattern.allMatches(test)) {
+        String directive = match.group(1);
+        String pattern = match.groups([2, 3]).where((s) => s != null).single;
+        if (directive == 'present') {
+          Expect.isTrue(generated.contains(pattern),
+              "Cannot find '$pattern' in:\n$generated");
+        } else {
+          assert(directive == 'absent');
+          Expect.isFalse(generated.contains(pattern),
+              "Must not find '$pattern' in:\n$generated");
+        }
+      }
+    });
+  }
+
+  asyncTest(() => Future.wait([
+        check(MOD1),
+        check(MOD2),
+        check(MOD3),
+        check(REM1),
+        check(REM2),
+        check(REM3),
+      ]));
+}
diff --git a/tests/compiler/dart2js/simple_inferrer_test.dart b/tests/compiler/dart2js/simple_inferrer_test.dart
index fb54674..f3dbf3e 100644
--- a/tests/compiler/dart2js/simple_inferrer_test.dart
+++ b/tests/compiler/dart2js/simple_inferrer_test.dart
@@ -872,10 +872,9 @@
         checkFactoryConstructor('A', '');
 
         checkReturn('testCascade1', commonMasks.growableListType);
-        checkReturn(
-            'testCascade2',
-            new TypeMask.nonNullExact(
-                findElement(compiler, 'CascadeHelper'), closedWorld));
+        ClassElement clsCascadeHelper = findElement(compiler, 'CascadeHelper');
+        checkReturn('testCascade2',
+            new TypeMask.nonNullExact(clsCascadeHelper, closedWorld));
         checkReturn('testSpecialization1', commonMasks.numType);
         checkReturn('testSpecialization2', commonMasks.dynamicType);
         checkReturn('testSpecialization3', commonMasks.uint31Type.nullable());
diff --git a/tests/corelib/corelib.status b/tests/corelib/corelib.status
index 5944e86..2dfdb3b 100644
--- a/tests/corelib/corelib.status
+++ b/tests/corelib/corelib.status
@@ -40,9 +40,6 @@
 symbol_reserved_word_test/07: MissingCompileTimeError # bug 11669, 19972
 symbol_reserved_word_test/10: MissingCompileTimeError # bug 11669, 19972
 
-[ ($compiler == none || $compiler == app_jit) && $unchecked ]
-iterable_generate_test/01: RuntimeError # Issue 28025
-
 [ $compiler == none && ($runtime == drt || $runtime == dartium) ]
 package_resource_test: RuntimeError # Issue 26842
 symbol_reserved_word_test/02: RuntimeError # bug 20191 / dartium/drt cannot detect CompileTimeErrors
diff --git a/tests/html/html.status b/tests/html/html.status
index c3df098..14ab0bd 100644
--- a/tests/html/html.status
+++ b/tests/html/html.status
@@ -78,7 +78,7 @@
 worker_test/functional: Pass, Crash # Issue 9929.
 
 [ $compiler == dart2js && $runtime == chrome ]
-fileapi_test/entry: Fail # TODO(dart2js-team): Please triage this failure.
+fileapi_test/entry: Pass, Fail # TODO(dart2js-team): Please triage this failure.
 fileapi_test/getDirectory: Fail # TODO(dart2js-team): Please triage this failure.
 fileapi_test/getFile: Fail # TODO(dart2js-team): Please triage this failure.
 media_stream_test/supported_MediaStreamEvent: RuntimeError # Please triage.
diff --git a/tests/language/bad_typedef_test.dart b/tests/language/bad_typedef_test.dart
new file mode 100644
index 0000000..cbc271e
--- /dev/null
+++ b/tests/language/bad_typedef_test.dart
@@ -0,0 +1,15 @@
+// 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.
+// Dart test for a function type test that cannot be eliminated at compile time.
+
+import "package:expect/expect.dart";
+
+typedef int H(Function
+    Function   /// 00: compile-time error
+    x);
+
+main() {
+  bool b = true;
+  Expect.isFalse(b is H);
+}
diff --git a/tests/language/language.status b/tests/language/language.status
index 8697ac4..ed6179e 100644
--- a/tests/language/language.status
+++ b/tests/language/language.status
@@ -5,21 +5,9 @@
 # This directory contains tests that are intended to show the
 # current state of the language.
 
-[ $compiler == none || $compiler == app_jit ]
-null_is_bottom_test/22: RuntimeError # Issue 28025
-null_is_bottom_test/34: RuntimeError # Issue 28025
-
 [ $compiler == none || $compiler == precompiler || $compiler == app_jit ]
 # Other issues:
 generic_methods_type_expression_test: RuntimeError # Issue 25869
-null_is_bottom_test/05: RuntimeError # Issue 28025
-null_is_bottom_test/07: RuntimeError # Issue 28025
-null_is_bottom_test/20: RuntimeError # Issue 28025
-null_is_bottom_test/25: RuntimeError # Issue 28025
-null_is_bottom_test/27: RuntimeError # Issue 28025
-null_is_bottom_test/32: RuntimeError # Issue 28025
-null_is_bottom_test/37: RuntimeError # Issue 28025
-null_is_bottom_test/39: RuntimeError # Issue 28025
 
 # This is OK for now, but we may want to change the semantics to match the test.
 async_star_pause_test: Fail, OK
@@ -72,14 +60,8 @@
 generic_local_functions_test: Pass # Issue 25869
 generic_functions_test: Pass # Issue 25869
 generic_methods_generic_function_parameter_test: Pass # Issue 25869
-null_is_bottom_test/03: RuntimeError # Issue 28025
-null_is_bottom_test/18: RuntimeError # Issue 28025
-null_is_bottom_test/23: RuntimeError # Issue 28025
-null_is_bottom_test/30: RuntimeError # Issue 28025
-null_is_bottom_test/35: RuntimeError # Issue 28025
 
 [ ($compiler == none || $compiler == precompiler || $compiler == app_jit) && ($runtime == vm || $runtime == dart_precompiled) ]
-
 class_keyword_test/02: MissingCompileTimeError # Issue 13627
 unicode_bom_test: Fail # Issue 16067
 vm/debug_break_enabled_vm_test/01: Crash, OK # Expected to hit breakpoint.
@@ -172,7 +154,7 @@
 [ $compiler == precompiler && $runtime == dart_precompiled ]
 vm/regress_27671_test: Skip # Unsupported
 
-[ $noopt || $compiler == precompiler ]
+[ $noopt || $runtime == dart_precompiled ]
 # Stacktraces in precompilation omit inlined frames.
 full_stacktrace1_test: Pass, RuntimeError
 full_stacktrace2_test: Pass, RuntimeError
@@ -183,7 +165,7 @@
 stacktrace_test: Pass, RuntimeError
 regress_26948_test: Skip # Crashes, regis investigating
 
-[ $noopt || $compiler == precompiler || $mode == product ]
+[ $noopt || $runtime == dart_precompiled || $mode == product ]
 # Imports dart:mirrors
 const_evaluation_test: SkipByDesign
 deferred_constraints_constants_test: SkipByDesign
@@ -276,7 +258,7 @@
 # The following tests are supposed to fail.
 library_env_test/has_no_mirror_support: RuntimeError, OK
 
-[ $noopt || $compiler == precompiler || $mode == product ]
+[ $noopt || $runtime == dart_precompiled || $mode == product ]
 # The following tests are supposed to fail.
 library_env_test/has_mirror_support: RuntimeError, OK
 
@@ -313,6 +295,7 @@
 issue_1751477_test: Crash # Requires deferred libraries
 regress_23408_test: Crash # Requires deferred libraries
 regress_22443_test: Crash # Requires deferred libraries
+regress_28278_test: Crash # Requires deferred libraries
 conditional_import_test: Crash # Requires deferred libraries
 conditional_import_string_test: Crash # Requires deferred libraries
 override_field_method1_negative_test: Pass, Crash # Issue 27835
@@ -336,6 +319,9 @@
 [$runtime == vm && $compiler == none]
 duplicate_part_test/01: MissingCompileTimeError # Issue 27516
 
+[$runtime == vm && $compiler == none && $system == windows && $arch == ia32]
+vm/optimized_stacktrace_test: Pass, Crash # Issue 28276
+
 [$compiler == dart2analyzer]
 vm/regress_27201_test: SkipByDesign # Loads bad library, so will always crash.
 config_import_corelib_test: StaticWarning, OK
@@ -351,7 +337,3 @@
 async_star_test: StaticWarning
 regress_18535_test: StaticWarning
 
-[ $runtime == dart_precompiled || $runtime == vm || $runtime == dartium]
-null_bottom_test/none: RuntimeError # Issue 28025
-null_bottom_test/01: RuntimeError # Issue 28025
-null_bottom_test/02: RuntimeError # Issue 28025
diff --git a/tests/language/language_dart2js.status b/tests/language/language_dart2js.status
index dc59965..fc253a47 100644
--- a/tests/language/language_dart2js.status
+++ b/tests/language/language_dart2js.status
@@ -37,6 +37,8 @@
 
 duplicate_part_test/01: MissingCompileTimeError # Issue 27517
 
+bad_typedef_test/00: Crash # Issue 28214
+
 [ $compiler == dart2js && $fast_startup ]
 const_evaluation_test/*: Fail # mirrors not supported
 deferred_constraints_constants_test/none: Fail # mirrors not supported
@@ -60,6 +62,7 @@
 regress_13462_0_test: Fail # mirrors not supported
 regress_13462_1_test: Fail # mirrors not supported
 regress_18535_test: Fail # mirrors not supported
+regress_28255_test: Fail # mirrors not supported
 super_call4_test: Fail # mirrors not supported
 super_getter_setter_test: Fail # mirrors not supported
 vm/reflect_core_vm_test: Fail # mirrors not supported
diff --git a/tests/language/language_kernel.status b/tests/language/language_kernel.status
index 98ed9bc..3ea014e 100644
--- a/tests/language/language_kernel.status
+++ b/tests/language/language_kernel.status
@@ -7,8 +7,6 @@
 large_class_declaration_test: Skip
 large_implicit_getter_test: Skip
 larger_implicit_getter_test: Skip
-null_is_bottom_test/22: RuntimeError # Issue 28025
-null_is_bottom_test/34: RuntimeError # Issue 28025
 
 ###############################################################################
 # Dartk Entries
@@ -85,14 +83,6 @@
 multiline_newline_test/06: MissingCompileTimeError
 no_main_test/01: DartkCrash
 not_enough_positional_arguments_test/01: DartkCompileTimeError
-null_is_bottom_test/05: RuntimeError # Issue 28025
-null_is_bottom_test/07: RuntimeError # Issue 28025
-null_is_bottom_test/20: RuntimeError # Issue 28025
-null_is_bottom_test/25: RuntimeError # Issue 28025
-null_is_bottom_test/27: RuntimeError # Issue 28025
-null_is_bottom_test/32: RuntimeError # Issue 28025
-null_is_bottom_test/37: RuntimeError # Issue 28025
-null_is_bottom_test/39: RuntimeError # Issue 28025
 regress_27617_test/1: MissingCompileTimeError
 super_call3_test/01: DartkCrash
 type_variable_conflict2_test/02: MissingCompileTimeError
@@ -326,6 +316,7 @@
 regress_23408_test: RuntimeError
 regress_27164_test: CompileTimeError
 regress_r24720_test: RuntimeError
+regress_28278_test: RuntimeError
 reify_typevar_test: RuntimeError
 script1_negative_test: Fail
 script2_negative_test: Fail
@@ -365,24 +356,9 @@
 
 # dartk: precompilation failures
 [ $compiler == dartkp && $runtime == dart_precompiled ]
-const_evaluation_test/01: Crash
-full_stacktrace1_test: RuntimeError
-full_stacktrace2_test: RuntimeError
-full_stacktrace3_test: RuntimeError
 if_null_assignment_static_test/35: Crash
-instance_creation_in_function_annotation_test: Crash
-invocation_mirror_invoke_on2_test: Crash
-issue21079_test: Crash
 large_class_declaration_test: Pass, Timeout
-library_env_test/has_mirror_support: RuntimeError
-redirecting_factory_reflection_test: Crash
-regress_18535_test: Crash
-stacktrace_rethrow_error_test/none: RuntimeError
-stacktrace_rethrow_error_test/withtraceparameter: RuntimeError
-stacktrace_rethrow_nonerror_test: RuntimeError
-stack_trace_test: RuntimeError
 string_interpolation7_test: RuntimeError
-super_call4_test: RuntimeError
 
 # dartk: precompilation failures (debug)
 [ $compiler == dartkp && $runtime == dart_precompiled && $mode == debug ]
diff --git a/tests/language/regress_28278_lib.dart b/tests/language/regress_28278_lib.dart
new file mode 100644
index 0000000..0bc67f1
--- /dev/null
+++ b/tests/language/regress_28278_lib.dart
@@ -0,0 +1,5 @@
+// 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.
+
+foo(x) => x + "Hello";
diff --git a/tests/language/regress_28278_test.dart b/tests/language/regress_28278_test.dart
new file mode 100644
index 0000000..08d276f
--- /dev/null
+++ b/tests/language/regress_28278_test.dart
@@ -0,0 +1,27 @@
+// 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.
+// VMOptions=--load-deferred-eagerly
+// VMOptions=
+
+import "package:expect/expect.dart";
+
+import "regress_28278_lib.dart" deferred as def;
+
+var result = "";
+
+class D {
+  m() async {
+    await def.loadLibrary();
+    result = def.foo(result += "Here");
+  }
+
+}
+
+main() async {
+  var d = new D();
+  await d.m();
+  await d.m();
+  Expect.equals("HereHelloHereHello", result);
+}
+
diff --git a/tests/language_strong/language_strong.status b/tests/language_strong/language_strong.status
index 424f579..dadc4a0 100644
--- a/tests/language_strong/language_strong.status
+++ b/tests/language_strong/language_strong.status
@@ -262,6 +262,7 @@
 generic_constructor_mixin_test: Skip
 generic_field_mixin6_test: Skip
 generic_list_checked_test: Skip
+generic_tearoff_test: Skip
 generic_test: Skip
 generics_test: Skip
 get_set_syntax_test: Skip
diff --git a/tests/lib/mirrors/relation_assignable_test.dart b/tests/lib/mirrors/relation_assignable_test.dart
index 970aedf..8014a82 100644
--- a/tests/lib/mirrors/relation_assignable_test.dart
+++ b/tests/lib/mirrors/relation_assignable_test.dart
@@ -33,11 +33,13 @@
   TypeMirror Sub1 = thisLibrary.declarations[#Subclass1];
   TypeMirror Sub2 = thisLibrary.declarations[#Subclass2];
   TypeMirror Obj = coreLibrary.declarations[#Object];
+  TypeMirror Nul = coreLibrary.declarations[#Null];
 
   Expect.isTrue(Obj.isAssignableTo(Obj));
   Expect.isTrue(Super.isAssignableTo(Super));
   Expect.isTrue(Sub1.isAssignableTo(Sub1));
   Expect.isTrue(Sub2.isAssignableTo(Sub2));
+  Expect.isTrue(Nul.isAssignableTo(Nul));
 
   Expect.isTrue(Sub1.isAssignableTo(Super));
   Expect.isTrue(Super.isAssignableTo(Sub1));
@@ -57,6 +59,10 @@
   Expect.isTrue(Super.isAssignableTo(Obj));
   Expect.isTrue(Obj.isAssignableTo(Super));
 
+  Expect.isTrue(Nul.isAssignableTo(Obj));
+  Expect.isTrue(Obj.isAssignableTo(Nul));
+  Expect.isTrue(Nul.isAssignableTo(Super));  // Null type is bottom type.
+  Expect.isTrue(Super.isAssignableTo(Nul));
 
   // Function typedef - argument type.
   TypeMirror Func = coreLibrary.declarations[#Function];
diff --git a/tests/lib/mirrors/relation_subclass_test.dart b/tests/lib/mirrors/relation_subclass_test.dart
index 2e8bbc2..c0c7927 100644
--- a/tests/lib/mirrors/relation_subclass_test.dart
+++ b/tests/lib/mirrors/relation_subclass_test.dart
@@ -28,11 +28,13 @@
   ClassMirror Sub1 = thisLibrary.declarations[#Subclass1];
   ClassMirror Sub2 = thisLibrary.declarations[#Subclass2];
   ClassMirror Obj = coreLibrary.declarations[#Object];
+  ClassMirror Nul = coreLibrary.declarations[#Null];
 
   Expect.isTrue(Obj.isSubclassOf(Obj));
   Expect.isTrue(Super.isSubclassOf(Super));
   Expect.isTrue(Sub1.isSubclassOf(Sub1));
   Expect.isTrue(Sub2.isSubclassOf(Sub2));
+  Expect.isTrue(Nul.isSubclassOf(Nul));
 
   Expect.isTrue(Sub1.isSubclassOf(Super));
   Expect.isFalse(Super.isSubclassOf(Sub1));
@@ -52,6 +54,11 @@
   Expect.isTrue(Super.isSubclassOf(Obj));
   Expect.isFalse(Obj.isSubclassOf(Super));
 
+  Expect.isTrue(Nul.isSubclassOf(Obj));
+  Expect.isFalse(Obj.isSubclassOf(Nul));
+  Expect.isFalse(Nul.isSubclassOf(Super));
+  Expect.isFalse(Super.isSubclassOf(Nul));
+
   var Func = coreLibrary.declarations[#Function];
   Expect.isTrue(Func.isSubclassOf(Obj));
   Expect.isFalse(Obj.isSubclassOf(Func));
diff --git a/tests/lib/mirrors/relation_subtype_test.dart b/tests/lib/mirrors/relation_subtype_test.dart
index 9504c8c..ab015ce 100644
--- a/tests/lib/mirrors/relation_subtype_test.dart
+++ b/tests/lib/mirrors/relation_subtype_test.dart
@@ -33,11 +33,13 @@
   TypeMirror Sub1 = thisLibrary.declarations[#Subclass1];
   TypeMirror Sub2 = thisLibrary.declarations[#Subclass2];
   TypeMirror Obj = coreLibrary.declarations[#Object];
+  TypeMirror Nul = coreLibrary.declarations[#Null];
 
   Expect.isTrue(Obj.isSubtypeOf(Obj));
   Expect.isTrue(Super.isSubtypeOf(Super));
   Expect.isTrue(Sub1.isSubtypeOf(Sub1));
   Expect.isTrue(Sub2.isSubtypeOf(Sub2));
+  Expect.isTrue(Nul.isSubtypeOf(Nul));
 
   Expect.isTrue(Sub1.isSubtypeOf(Super));
   Expect.isFalse(Super.isSubtypeOf(Sub1));
@@ -57,6 +59,10 @@
   Expect.isTrue(Super.isSubtypeOf(Obj));
   Expect.isFalse(Obj.isSubtypeOf(Super));
 
+  Expect.isTrue(Nul.isSubtypeOf(Obj));
+  Expect.isFalse(Obj.isSubtypeOf(Nul));
+  Expect.isTrue(Nul.isSubtypeOf(Super));  // Null type is bottom type.
+  Expect.isFalse(Super.isSubtypeOf(Nul));
 
   // Function typedef - argument type.
   TypeMirror Func = coreLibrary.declarations[#Function];
diff --git a/tests/lib_strong/html/js_test.dart b/tests/lib_strong/html/js_test.dart
index 55b6eef..c55b926 100644
--- a/tests/lib_strong/html/js_test.dart
+++ b/tests/lib_strong/html/js_test.dart
@@ -649,6 +649,13 @@
       context.deleteProperty('callback');
     });
 
+    test('pass a Dart function to JS and back', () {
+      var dartFunction = () => 42;
+      context['dartFunction'] = dartFunction;
+      expect(identical(context['dartFunction'], dartFunction), isTrue);
+      context.deleteProperty('dartFunction');
+    });
+
     test('callback as parameter', () {
       expect(context.callMethod('getTypeOf', [context['razzle']]),
           equals("function"));
diff --git a/tests/standalone/io/file_blocking_lock_test.dart b/tests/standalone/io/file_blocking_lock_test.dart
index 9f665b6..5fd6e55 100644
--- a/tests/standalone/io/file_blocking_lock_test.dart
+++ b/tests/standalone/io/file_blocking_lock_test.dart
@@ -39,7 +39,7 @@
   });
 }
 
-const int peerTimeoutMilliseconds = 10000;
+const int peerTimeoutMilliseconds = 30000;
 
 Future<bool> waitForPeer(RandomAccessFile raf, int length) async {
   Stopwatch s = new Stopwatch();
@@ -70,8 +70,13 @@
   await raf.lock(FileLock.BLOCKING_EXCLUSIVE, 0, length);
   Process peer = await runPeer(file.path, length, FileLock.BLOCKING_EXCLUSIVE);
 
-  // Waits for the peer to take the lock, then takes the lock.
-  Expect.isTrue(await waitForPeer(raf, length));
+  // If the peer doesn't come up within the timeout, then give up on the test
+  // to avoid the test being flaky.
+  if (!await waitForPeer(raf, length)) {
+    await raf.close();
+    await directory.delete(recursive: true);
+    return;
+  }
 
   // Check that the peer wrote to the file.
   int p = 0;
diff --git a/tests/standalone/standalone.status b/tests/standalone/standalone.status
index eb4a550..6fb01d9 100644
--- a/tests/standalone/standalone.status
+++ b/tests/standalone/standalone.status
@@ -7,6 +7,8 @@
 # listed in tests/lib/analyzer/analyze_tests.status without the "standalone"
 # prefix.
 
+io/raw_socket_test: Pass, RuntimeError # Issue 28288
+
 packages_file_test: Skip # Issue 26715
 packages_file_test/none: Skip   # contains no tests.
 
diff --git a/tools/FAKE_COMMITS b/tools/FAKE_COMMITS
index db84018..8d4d095 100644
--- a/tools/FAKE_COMMITS
+++ b/tools/FAKE_COMMITS
@@ -21,3 +21,4 @@
 Trigger bots after master restart.
 Trigger mirroring of github repository
 Trigger mirroring of github repository
+Trigger mirroring of github repository
diff --git a/tools/VERSION b/tools/VERSION
index 275af21..d077412 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 1
 MINOR 22
 PATCH 0
-PRERELEASE 5
+PRERELEASE 6
 PRERELEASE_PATCH 0
diff --git a/tools/bots/gn_build.py b/tools/bots/gn_build.py
index 0fe2298..4518c99 100644
--- a/tools/bots/gn_build.py
+++ b/tools/bots/gn_build.py
@@ -14,7 +14,7 @@
 DART_ROOT = os.path.realpath(os.path.join(SCRIPT_DIR, '..', '..'))
 
 def main(argv):
-  os.environ["DART_USE_GN"] = "1"
+  os.environ["DART_USE_GYP"] = "1"
   generate_buildfiles = os.path.join(
       DART_ROOT, 'tools', 'generate_buildfiles.py')
   gclient_result = subprocess.call(['python', generate_buildfiles])
diff --git a/tools/build.py b/tools/build.py
index 5b66500..2645ef5 100755
--- a/tools/build.py
+++ b/tools/build.py
@@ -44,11 +44,11 @@
 
 unless you really intend to use a non-default Makefile.""" % DART_ROOT
 
-DART_USE_GN = "DART_USE_GN"
+DART_USE_GYP = "DART_USE_GYP"
 
 
-def use_gn():
-  return DART_USE_GN in os.environ
+def use_gyp():
+  return DART_USE_GYP in os.environ
 
 
 def BuildOptions():
@@ -84,9 +84,9 @@
       help='Name of the devenv.com/msbuild executable on Windows (varies for '
            'different versions of Visual Studio)',
       default=vs_executable)
-  result.add_option("--gn",
-      help='Build with GN/Ninja',
-      default=use_gn(),
+  result.add_option("--gyp",
+      help='Build with gyp.',
+      default=use_gyp(),
       action='store_true')
   return result
 
@@ -435,7 +435,7 @@
   if options.verbose:
     command += ['-v']
   if UseGoma(out_dir):
-    command += ['-j200']
+    command += ['-j1000']
   command += [target]
   return command
 
@@ -446,7 +446,7 @@
   start_time = time.time()
   args = []
   build_config = utils.GetBuildConf(mode, arch, target_os)
-  if options.gn:
+  if not options.gyp:
     args = BuildNinjaCommand(options, target, target_os, mode, arch)
   else:
     os.environ['DART_BUILD_MODE'] = mode
@@ -455,6 +455,8 @@
       project_file = 'dart.xcodeproj'
       if os.path.exists('dart-%s.gyp' % CurrentDirectoryBaseName()):
         project_file = 'dart-%s.xcodeproj' % CurrentDirectoryBaseName()
+      if target == 'all':
+        target = 'All'
       args = ['xcodebuild',
               '-project',
               project_file,
@@ -590,10 +592,7 @@
     return 1
   # Determine which targets to build. By default we build the "all" target.
   if len(args) == 0:
-    if HOST_OS == 'macos':
-      targets = ['All']
-    else:
-      targets = ['all']
+    targets = ['all']
   else:
     targets = args
 
diff --git a/tools/dom/src/EventStreamProvider.dart b/tools/dom/src/EventStreamProvider.dart
index 474a143..9a75afd 100644
--- a/tools/dom/src/EventStreamProvider.dart
+++ b/tools/dom/src/EventStreamProvider.dart
@@ -226,13 +226,21 @@
   EventListener _onData;
   final bool _useCapture;
 
-  // TODO(jacobr): for full strong mode correctness we should write
-  // _onData = onData == null ? null : _wrapZone/*<Event, dynamic>*/((e) => onData(e as T))
-  // but that breaks 114 co19 tests as well as multiple html tests as it is reasonable
-  // to pass the wrong type of event object to an event listener as part of a
-  // test.
+  // TODO(leafp): It would be better to write this as
+  // _onData = onData == null ? null :
+  //   onData is _wrapZoneCallback<Event, dynamic>
+  //     ? _wrapZone/*<Event, dynamic>*/(onData)
+  //     : _wrapZone/*<Event, dynamic>*/((e) => onData(e as T))
+  // In order to support existing tests which pass the wrong type of events but
+  // use a more general listener, without causing as much slowdown for things
+  // which are typed correctly.  But this currently runs afoul of restrictions
+  // on is checks for compatibility with the VM.
   _EventStreamSubscription(this._target, this._eventType, void onData(T event),
-      this._useCapture) : _onData = _wrapZone/*<Event, dynamic>*/(onData) {
+                           this._useCapture) :
+      _onData = onData == null
+      ? null
+      : _wrapZone/*<Event, dynamic>*/((e) => (onData as dynamic)(e))
+  {
     _tryResume();
   }
 
diff --git a/tools/dom/src/shared_html.dart b/tools/dom/src/shared_html.dart
index 7342cdf..b76b37b 100644
--- a/tools/dom/src/shared_html.dart
+++ b/tools/dom/src/shared_html.dart
@@ -12,23 +12,13 @@
   // For performance reasons avoid wrapping if we are in the root zone.
   if (Zone.current == Zone.ROOT) return callback;
   if (callback == null) return null;
-  // TODO(jacobr): we cast to _wrapZoneCallback/*<A, R>*/ to hack around missing
-  // generic method support in zones.
-  // ignore: STRONG_MODE_DOWN_CAST_COMPOSITE
-  _wrapZoneCallback/*<A, R>*/ wrapped =
-      Zone.current.bindUnaryCallback(callback, runGuarded: true);
-  return wrapped;
+  return Zone.current.bindUnaryCallback/*<R, A>*/(callback, runGuarded: true);
 }
 
 _wrapZoneBinaryCallback/*<A, B, R>*/ _wrapBinaryZone/*<A, B, R>*/(_wrapZoneBinaryCallback/*<A, B, R>*/ callback) {
   if (Zone.current == Zone.ROOT) return callback;
   if (callback == null) return null;
-  // We cast to _wrapZoneBinaryCallback/*<A, B, R>*/ to hack around missing
-  // generic method support in zones.
-  // ignore: STRONG_MODE_DOWN_CAST_COMPOSITE
-  _wrapZoneBinaryCallback/*<A, B, R>*/ wrapped =
-      Zone.current.bindBinaryCallback(callback, runGuarded: true);
-  return wrapped;
+  return Zone.current.bindBinaryCallback/*<R, A, B>*/(callback, runGuarded: true);
 }
 
 /**
diff --git a/tools/generate_buildfiles.py b/tools/generate_buildfiles.py
old mode 100644
new mode 100755
index 9aa26e7..b6be5a4
--- a/tools/generate_buildfiles.py
+++ b/tools/generate_buildfiles.py
@@ -11,12 +11,12 @@
 
 SCRIPT_DIR = os.path.dirname(sys.argv[0])
 DART_ROOT = os.path.realpath(os.path.join(SCRIPT_DIR, '..'))
-DART_USE_GN = "DART_USE_GN"
+DART_USE_GYP = "DART_USE_GYP"
 DART_DISABLE_BUILDFILES = "DART_DISABLE_BUILDFILES"
 
 
-def use_gn():
-  return DART_USE_GN in os.environ
+def use_gyp():
+  return DART_USE_GYP in os.environ
 
 
 def disable_buildfiles():
@@ -29,21 +29,26 @@
   return process.returncode
 
 
-def run_gn():
+def run_gn(options):
   gn_command = [
     'python',
     os.path.join(DART_ROOT, 'tools', 'gn.py'),
     '-m', 'all',
     '-a', 'all',
   ]
+  if options.verbose:
+    gn_command.append('-v')
+    print ' '.join(gn_command)
   return execute(gn_command)
 
 
-def run_gyp():
+def run_gyp(options):
   gyp_command = [
     'python',
     os.path.join(DART_ROOT, 'tools', 'gyp_dart.py'),
   ]
+  if options.verbose:
+    print ' '.join(gyp_command)
   return execute(gyp_command)
 
 
@@ -58,17 +63,17 @@
       action="store_true")
   parser.add_argument("--gn",
       help='Use GN',
-      default=use_gn(),
+      default=not use_gyp(),
       action='store_true')
   parser.add_argument("--gyp",
       help='Use gyp',
-      default=not use_gn(),
+      default=use_gyp(),
       action='store_true')
 
   options = parser.parse_args(args)
-  # If gn is enabled one way or another, then disable gyp
-  if options.gn:
-    options.gyp = False
+  # If gyp is enabled one way or another, then disable gn
+  if options.gyp:
+    options.gn = False
   return options
 
 
@@ -78,9 +83,9 @@
     return 0
   options = parse_args(argv)
   if options.gn:
-    return run_gn()
+    return run_gn(options)
   else:
-    return run_gyp()
+    return run_gyp(options)
 
 
 if __name__ == '__main__':
diff --git a/tools/testing/dart/runtime_configuration.dart b/tools/testing/dart/runtime_configuration.dart
index d3747ea..87fd0f5 100644
--- a/tools/testing/dart/runtime_configuration.dart
+++ b/tools/testing/dart/runtime_configuration.dart
@@ -58,6 +58,9 @@
       case 'vm':
         return new StandaloneDartRuntimeConfiguration();
 
+      case 'flutter':
+        return new StandaloneFlutterEngineConfiguration();
+
       case 'dart_precompiled':
         if (configuration['system'] == 'android') {
           return new DartPrecompiledAdbRuntimeConfiguration(useBlobs: useBlobs);
@@ -240,6 +243,29 @@
   }
 }
 
+/// The flutter engine binary, "sky_shell".
+class StandaloneFlutterEngineConfiguration extends DartVmRuntimeConfiguration {
+  List<Command> computeRuntimeCommands(
+      TestSuite suite,
+      CommandBuilder commandBuilder,
+      CommandArtifact artifact,
+      List<String> arguments,
+      Map<String, String> environmentOverrides) {
+    String script = artifact.filename;
+    String type = artifact.mimeType;
+    if (script != null &&
+        type != 'application/dart' &&
+        type != 'application/dart-snapshot') {
+      throw "Flutter Engine cannot run files of type '$type'.";
+    }
+    String executable = suite.flutterEngineBinaryFileName;
+    var args = <String>['--non-interactive']..addAll(arguments);
+    return <Command>[
+      commandBuilder.getVmCommand(executable, args, environmentOverrides)
+    ];
+  }
+}
+
 class DartPrecompiledRuntimeConfiguration extends DartVmRuntimeConfiguration {
   final bool useBlobs;
   DartPrecompiledRuntimeConfiguration({bool useBlobs}) : useBlobs = useBlobs;
diff --git a/tools/testing/dart/status_reporter.dart b/tools/testing/dart/status_reporter.dart
index 0f5e37b..37f66ae 100644
--- a/tools/testing/dart/status_reporter.dart
+++ b/tools/testing/dart/status_reporter.dart
@@ -30,6 +30,12 @@
     'archs': ['ia32'],
     'compiler': 'none'
   },
+  {
+    'runtimes': ['flutter_engine'],
+    'modes': ['debug', 'release'],
+    'archs': ['x64'],
+    'compiler': 'none'
+  },
 ];
 
 List<Map> MACOS_COMBINATIONS = [
diff --git a/tools/testing/dart/test_options.dart b/tools/testing/dart/test_options.dart
index 66e0e0a..ed54fc1 100644
--- a/tools/testing/dart/test_options.dart
+++ b/tools/testing/dart/test_options.dart
@@ -64,7 +64,7 @@
           '''Specify any compilation step (if needed).
 
    none: Do not compile the Dart code (run native Dart code on the VM).
-         (only valid with the following runtimes: vm, drt)
+         (only valid with the following runtimes: vm, flutter, drt)
 
    dart2js: Compile dart code to JavaScript by running dart2js.
          (only valid with the following runtimes: d8, drt, chrome,
@@ -99,6 +99,8 @@
           '''Where the tests should be run.
     vm: Run Dart code on the standalone dart vm.
 
+    flutter: Run Dart code on the flutter engine.
+
     dart_precompiled: Run a precompiled snapshot on a variant of the standalone
                       dart vm lacking a JIT.
 
@@ -129,6 +131,7 @@
           ['-r', '--runtime'],
           [
             'vm',
+            'flutter',
             'dart_precompiled',
             'd8',
             'jsshell',
@@ -307,6 +310,8 @@
       new _TestOptionSpecification(
           'dart', 'Path to dart executable', ['--dart'], [], ''),
       new _TestOptionSpecification(
+          'flutter', 'Path to flutter executable', ['--flutter'], [], ''),
+      new _TestOptionSpecification(
           'drt', // TODO(antonm): fix the option name.
           'Path to content shell executable',
           ['--drt'],
@@ -626,6 +631,7 @@
     'chrome',
     'copy_coredumps',
     'dart',
+    'flutter',
     'dartium',
     'drt',
     'exclude_suite',
@@ -720,6 +726,7 @@
       case 'none':
         validRuntimes = const [
           'vm',
+          'flutter',
           'drt',
           'dartium',
           'ContentShellOnAndroid',
@@ -749,6 +756,15 @@
       print("Cannot have both --use-repository-packages and "
           "--use-public-packages");
     }
+    if ((config['runtime'] == 'flutter') && (config['flutter'] == '')) {
+      isValid = false;
+      print("-rflutter requires the flutter engine executable to "
+          "be specified using --flutter=");
+    }
+    if ((config['runtime'] == 'flutter') && (config['arch'] != 'x64')) {
+      isValid = false;
+      print("-rflutter is applicable only for --arch=x64");
+    }
 
     return isValid;
   }
diff --git a/tools/testing/dart/test_suite.dart b/tools/testing/dart/test_suite.dart
index 47b8a879..289aaf3 100644
--- a/tools/testing/dart/test_suite.dart
+++ b/tools/testing/dart/test_suite.dart
@@ -208,6 +208,14 @@
     return dartExecutable;
   }
 
+  /// Returns the name of the flutter engine executable.
+  String get flutterEngineBinaryFileName {
+    // Controlled by user with the option "--flutter".
+    String flutterExecutable = configuration['flutter'];
+    TestUtils.ensureExists(flutterExecutable, configuration);
+    return flutterExecutable;
+  }
+
   String get dartVmNooptBinaryFileName {
     // Controlled by user with the option "--dart".
     String dartExecutable = configuration['dart'];